This file details thoughts about the time control mechanism. TIME CONTROL: Introduction A time control mechanism is useful for pausing, starting and ending levels, or gameplay tricks. This mechanism was planned from the beginning, so implementing it should be no problem. A time control mechanism allows the rate of time passage to be changed. This rate is described by a time factor. Normally, this time factor should be 1.0. Setting the factor to 0.5 slows the game down to half its speed. Setting the factor to 2.0 doubles the game speed. Setting the factor to 0.0 essentially pauses the game. Negative time factors make no sense and are forbidden. The time factor should affect the physical side *only*, nothing else. TIME CONTROL: Implementation (client and server) Both client and server have a (per level? server-wide?) time factor. Ideally, this time factor is always the same, though latency might destroy this overlap. Latency could be corrected through the PING mechanism, and through movement updates. When the physics engines are run, the time (in seconds) since the last update are passed. This mechanism may seem to be error-prone, since any errors (through precision artifacts and other causes) will accumulate. However, such errors not important, since whatever the server believes is the truth, and the clients attempt to follow the server. The second-passing mechanism becomes very neat for time controls, since we can apply the currently effective time factor to the time since last update for an instant effect. The actual seconds-since-last-update are not affected at all, the reported values are merely scaled. So if the current system time is XXX100 ms, and the next update happens at XXX300 ms, exactly 200 ms have passed. With a time factor of 1.0, 200 ms will be passed to the physics engines. With a time factor of 0.5, 100 ms will be passed, and with a time factor of 0.0, 0 ms will be passed. In any case, the update after that happens at (say) system time XXX500 ms, which again corresponds to 200 ms prescaled, or 200/100/0 ms after each respective scaling. Care must be taken with time factors greatly beyond 1.0, since this may affect collision handling as well. One solution would be to break down the time into managable portions, and handle these in the physics engines. For example, if the collision mechanism must be run at least once every 0.25 seconds (due to object speeds), the physics can be updated for 0.25 seconds until the actual time parameter has been reached. This repetition should be done closer to the physics core, since we don't want several movement update notices from a single run() invocation. But if the repeated physics loops take more time than they are supposed to handle, the server cannot keep up and will continue to take more time. The solution to this problem, a "speed limit", also shows a much simpler mechanism. If the physics updates may only cover a specific maximal amount of time (0.25 seconds in our above example), then the physics engines will truncate the time taken down to this time (no more than 0.25 seconds are allowed to have passed). To help the clients, an effective time factor may be computed and passed to them as described below. This soft time factor should shift smoothly between the hard time factor which would have applied for the physics engine and the time factor set by the server administration. Example: - The current time factor on the server is set to 10.0. - The real-world time between server physics updates is 0.03 seconds. - The adjusted time which will be passed to the physics engine is 0.3 seconds. - The physics engine can only handle a time difference of 0.25 seconds, and applies another factor of 0.83 - Combined with the server time factor, the new server time factor is 8.3 - This time factor is communicated to the clients, possibly as a smoothed value. - The server may accept this time factor for the next update (knowing that the user wanted 10.0). - The server would then gradually raise the time factor towards 10.0 until the next cutoff occurs. TIME CONTROL: Time bends A "time bend" is a shift in the time factor that occurs over a stretch of time. In many cases, such as a pause or resume, the time factor needs to apply immediately. In other cases, though, such as time slowing due to a power-up, the change will occur more gradually. For example, the current time factor may be 1.0 (no change), and a player picks up a power-up which will set the time factor to 0.2. For visualization reasons, this change should not occur now, but stretched over 1 second of real time. At the beginning of this 1 second time bend, the time factor is at 1.0. After half a second, the time factor will be half way there, at 0.6. After the full 1 second, the time factor is finally 0.2. Only one bend at a time can be active. A bend which starts during another bend replaces it. Since bends have both a start and a finish value, the start value overwrites the current value. TIME CONTROL: Networking The server sends the currently applicable time factor to the clients in the form of a TIMF message (name not final yet). This message has the usual timing information (i.e. the server time when this message applies). This time stamp may be in the future, causing the time factor to be applied then, not now. A more accurate client will remember this for future use and / or recalculate the objects' positions to reflect the server side change, taking into account the time stamp of the message. A less accurate client will simply apply the new time factor now and not worry about object positions (which will get updated anyway). The payload of the TIMF message is either a single unsigned 16 bit number, or three unsigned 16 bit numbers. The first number is always the time factor to be set now (or at the message time stamp). The time factor is encoded as a fixed point number with 7 bits before the point and 9 bits afterwards. This allows a maximal time factor of (almost) 128.0 and a minimal non-zero time factor of less than 0.002. 7 bits were chosen so that the symbolic time factor of 100.0 could be chosen, despite the fact that this should be more than unplayable. If the second and third 16 bit numbers are present, this indicates a time bend. The second number is the number of milliseconds for the bend to take, and the third number is the final time factor at the end of the bend. TIME CONTROL: Time stamps The time stamps and general timing are not effected. The time stamps still denote the server time at which a message has been sent.