-
Notifications
You must be signed in to change notification settings - Fork 0
Respawn Behavior
The way respawning works in FUEL is that as you are playing the game saves a list of your current positions so when you die or reset it can place you nearby; however, there are some interesting quirks in how this was implemented that lead to weird behavior in specific instances.
Once every second the game will try to save the player's position three times, first with the player's current position and then again with the position 5
and 10
units away from the current position in the direction of the forward vector.
If you are greater than or equal to 10
units from the last saved respawn and your current position is "good" for a saved respawn, then the position will be saved. The position will also be saved if the list is empty regardless of the checks, so if you somehow manage to end up underwater with an empty list then the current position will be saved underwater and you will end up in a respawn loop. A position is good if it is in bounds and on the ground (terrain and structures count, but the Trident on water does not) among other things. If the condition below is true, then the position is immediately discarded.
is_out_of_area(vehicle->pos_x, vehicle->pos_z)// Out-of-area
|| vehicle->up.y < 0.0 // Upsidedown
|| !is_all_suspension_compressed(vehicle) // Not on the ground
|| vehicle->velocity.y < -30.0 // Falling
|| vehicle->terrain_steepness < 0.81900001 // Steep terrain: 1 - horizontal, 0 - vertical
|| vehicle->forward.y > 0.5 // Facing too far up or down
|| vehicle->forward.y < -0.70700002 // 1/sqrt(2)
|| vehicle->underwater > 0.0 // In water
|| is_colliding(position_1, position, vehicle, vehicle)// Something physicsy is happening
Following this condition, there are a few more checks. The integrity of the world is validated making sure that it only saves if the world exists where you are. If the vehicle's position is within 1
unit of the position trying to be saved then it will immediately succeed. Finally, if you are over 50
units above the terrain the position will not be saved, otherwise, it will be.
You can get it to save many positions without moving by saving where the current position and the position 10
units ahead are good, and then stay still. This is related to the 10
unit limit combined with the 10
unit projection along the forward vector leading to some interesting behavior when the player is not moving and both positions are good. This could be fixed by checking that the last saved position was strictly greater than 10
units away with a small epsilon to mitigate floating point rounding errors. This will cause the count to tick up by 2
per second as opposed to 3
because only the current position and 10
-unit projection will count, not the 5
-unit projection.
The exact series of events that leads to this behavior is that the player's current position is saved initially, then the position 10
units ahead is saved which is okay because it is far enough away from the last saved position (the current position), then the next second it will save the player's current position again which is okay because it is far enough away from the last saved position (the 10
-unit projection), this repeats forever.
The respawn list will be cleared if you (1) enter a hub, (2) use a helipad, (3) start a mission, or (4) are over 1000
units away from the last saved respawn.
There is a 5th, less likely, way the list will be "cleared". The size of the list is stored in an unsigned short
and there are no apparent checks for overflows. So, if you manage to fill the list, a size of (2^16)-1
, and then add 1
more, the size of the list will overflow and go back to 0
; in this state, the game thinks that the list isn't empty but also that it has a size of 0
. The reason the game thinks the list is not empty despite the size being 0
is that there are several size members that do not equal each other and the one that is used to check if the list is empty has not overflowed but the one used to index into the list has.
So when it tries to look up the last item in the list using positions[size-1]
, to check if its within 10
units, it tries to access the element before the start of the list, which will at best be an erroneous out-of-bounds read and at worse be an access violation depending on how the buffer was allocated. After leaving the game running for several hours, 65535/2/3600=9.1hrs
, with the saved respawns counting up using the trick described above, the size overflowed and the game crashed with a (C0000005, EXCEPTION_ACCESS_VIOLATION)
since the buffer was allocated at the beginning of a page and there was no accessible memory directly before that.
There are a few cases where the game will respawn you. Most notably when you die or reset, these will play the death rtc. Switching vehicles when you are in a bad position will reset you without the rtc.
While searching for the position to respawn you at, the game will search the list backward for the farthest saved respawn within 100
units. Whichever is farthest when the first saved respawn that is greater than or equal to 100
units away is encountered will be used. The saved respawn that is used and all saved respawns following it will be discarded from the list. If the list is empty or no saved respawns meet the criteria the death position will be used.
For FMTK Users and Mod Developers
For FMTK Developers
Asobo BigFile Format Specification
Asobo Classes
Animation_Z
Binary_Z
Bitmap_Z
Camera_Z
CollisionVol_Z
Fonts_Z
GameObj_Z
GenWorld_Z
GwRoad_Z
Keyframer*_Z
Light_Z
LightData_Z
Lod_Z
LodData_Z
Material_Z
MaterialAnim_Z
MaterialObj_Z
Mesh_Z
MeshData_Z
Node_Z
Omni_Z
Particles_Z
ParticlesData_Z
RotShape_Z
RotShapeData_Z
Rtc_Z
Skel_Z
Skin_Z
Sound_Z
Spline_Z
SplineGraph_Z
Surface_Z
SurfaceDatas_Z
UserDefine_Z
Warp_Z
World_Z
WorldRef_Z
Asobo File Format Idioms
Asobo CRC32
Asobo LZ Compression
Asobo Arithmetic Coding Compression
Asobo Save Game File Format Specification
Asobo Audio Formats
TotemTech/ToonTech/Zouna/ACE/BSSTech/Opal Timeline
Zouna Modding Resources
Miscellaneous