Skip to content

Once a player joins, rollback runs from tick 0 to current tick #260

@TheYellowArchitect

Description

@TheYellowArchitect

I'm currently focused on other PRs but this is a performance bug which I have to at least bring up.
The following function is inside the class rollback-synchronizer.gd
The below logger I added, reports that a new player joining, runs the below function from tick 0 to whatever tick you joined.

func _get_history(buffer: Dictionary, tick: int) -> Dictionary:
	if buffer.has(tick):
		return buffer[tick]

	if buffer.is_empty():
		return {}
	
	var earliest = buffer.keys().min()
	var latest = buffer.keys().max()

	
	if tick < earliest:
		_logger.warning("Tried to load tick %s which is earlier than the earliest we have recorded (%s)
		Try increasing the history limit." % [tick, earliest])
		return buffer[earliest]
	
	#For inputs, this is extrapolation aka prediction
	#For example, if you move to the right (at latest)
	#at tick, you will still be moving to the right ;)
	if tick > latest:
		return buffer[latest]
	
	var before: int = buffer.keys() \
		.filter(func (key): return key < tick) \
		.max()
	
	return buffer[before]

The full stack trace is this:

rollback-synchronizer -> func _prepare_tick(tick: int)
network-rollback -> 		on_prepare_tick.emit(tick)
network-rollback ->   func _rollback()

Below class is network-rollback.gd

func _ready():
	NetworkTime.after_tick_loop.connect(_rollback)

func _rollback():
	if not enabled:
		return

	_is_rollback = true

	# Ask all rewindables to submit their earliest inputs
	_resim_from = NetworkTime.tick
	before_loop.emit()
	
	# from = Earliest input amongst all rewindables
	var from: int = _resim_from

	# to = Current tick
	var to: int = NetworkTime.tick
	
	# for tick in from .. to:
	for tick in range(from, to): #FORLOOP FROM 0 TO player_joined_at_tick
		_tick = tick
		_simulated_nodes.clear()

		# Prepare state
		#	Done individually by Rewindables ( usually Rollback Synchronizers )
		#	Restore input and state for tick
		on_prepare_tick.emit(tick) #IT ENTERS HERE

It shouldn't run these loops (imagine if a player joins tick 100000 lol), as at each one, it returns buffer[earliest]
Anyway, needs more investigation, I only stumbled into it while implementing input delay, its not serious even for full games, since normally lobby games start everyone at tick 0 instead of joining at whatever tick

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions