This shows you the differences between two versions of the page.
— |
blog:tribes_2_ghastly_ghosts [2019/12/08 19:17] (current) Robert MacGregor created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Tribes 2: Ghastly Ghosts ====== | ||
+ | |||
+ | About a week ago I discovered a ghosting bug in the Tribes 2 engine. What's especially peculiar is that I discovered a networking bug in a listen | ||
+ | server of all things. It takes the following form: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | The above screenshot was taken in a Meltdown 3 listen game server. After a couple of seconds, everything snaps back into reality: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ===== Background ===== | ||
+ | |||
+ | Before I get into the bug itself, I should explain how Torque Game Engine synchronizes game simulations across the network. To start off with, all | ||
+ | interested parties (including the server) run at a tickrate of 32 milliseconds. This means that the game will update the game world in increments of | ||
+ | 32 milliseconds each. So, 3 ticks = 3 ticks * 32ms = 96ms. On the server side this is precisely true because that's where the local simulation | ||
+ | resides -- no latency is accounted for. However, when operating with clients across the internet, network transmission latency has to be accounted | ||
+ | for in some way. | ||
+ | |||
+ | The game deals with latency using a client-side simulation to fill in the time it takes for the game server to throw another frame at you which yields | ||
+ | a more natural looking simulation according to game rules, but it is prone to desynchronization from what the game server wants you to see at any | ||
+ | given point in time. The game has several scripting language exposed values that help control this (with their default values): | ||
+ | |||
+ | * $Item:: | ||
+ | * $Item:: | ||
+ | * $Item:: | ||
+ | * $Player:: | ||
+ | * $Player:: | ||
+ | * $Player:: | ||
+ | * $Player:: | ||
+ | |||
+ | Fractional ticks are possible depending on the implementation, | ||
+ | we'll focus primarily on $Player:: | ||
+ | is used to express how many ticks the game will simulate for between receiving frames from the game server. In this case, it defaults to 30 which is | ||
+ | 960ms, almost a full second of simulation. So it takes up to about a humanly visible second for the whole game simulation to freeze if the server | ||
+ | crashes or if ping time is so bad that it exceeds this time. | ||
+ | |||
+ | Cool, so what does this have to do with the screenshot above? Or even the title for that matter? An optimized synchronization technique called | ||
+ | ghosting. The client-side representation of a given game object is called the " | ||
+ | against using that recent data. However, the game has to deal with dialup connections and slow desktop processors (Pentium 3, Pentium 2). To help alleviate network stress and memory/CPU stress for clients, the game restricts the scope of ghosts to what's relevant to a given player. This means | ||
+ | that objects far away enough out of visible distance flat-out does not exist on the client. The game server also performs ghosting based on indoor | ||
+ | and outdoor presence -- when indoors, many outdoor ghosts vanish from the client' | ||
+ | |||
+ | Now what do ghosts have to do with the screenshot? The second " | ||
+ | to be mounted to my vehicle. Think of images as holographic representations of an object that you can put on vehicles and players. These images are | ||
+ | often used to make new looking objects and weapons without requiring genuine client-side content. Tribes 2 has an inherent bug with keeping these | ||
+ | images attached to ghosts in some circumstances. | ||
+ | |||
+ | ==== The Bug ==== | ||
+ | |||
+ | Not only does Tribes 2 have trouble keeping images mounted correctly, it has a problem with keeping actual objects mounted to the vehicle which | ||
+ | are not corrected indefinitely and do not seem correctable aside from modder intervention unmounting and remounting the object. This is noticeable | ||
+ | in Meltdown 3 (when the fix isn't applied) where a small cloaked sentry turret can sometimes be found floating around the map which doesn' | ||
+ | seem to fully exist -- because it doesn' | ||
+ | to be visible. When you see it detached, its still connected to a vehicle in reality. | ||
+ | |||
+ | This bug is very easily reproduced by placing a vehicle outdoors and going indoors on foot. Once inside (you have to be pretty far indoors), use | ||
+ | the script to mount yourself back into the vehicle and move as quickly as possible. If done correctly, the images will lag behind briefly and any | ||
+ | mounted objects may " | ||
+ | |||
+ | ==== Fixes ==== | ||
+ | |||
+ | As mentioned above, a fairly simple fix which is likely the most commonly used is to occasionally unmount and remount objects occasionally to fix the | ||
+ | perpetually unmounted objects after the fact. However, there is no reliable way of timing this as its bound to the server side ghosting systems which | ||
+ | means that this is only a partial bandaid, not a full fix. | ||
+ | |||
+ | The scripting engine exposes a function called %object.setScopeAlways, | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | The vehicle is also inaudible, which is really odd. Everything goes back to normal once I mount the vehicle, *and* the chassis weight object is | ||
+ | detached. | ||
+ | |||
+ | The scripting engine also exposes a function called %object.scopeToClient(%client), | ||
+ | it and I have not been able to reproduce it since. Perhaps a WINE bug, hopefully not. And hopefully that function can be looped to scope the object | ||
+ | to more than one person to properly resolve both the image bug and the object detachment bug. | ||
+ | |||
+ | {{tag> | ||
+ | |||
+ | |||