Currently the use case of reloading a previously saved situation is not formally supported. While, as part of the work on 1.5.3, some changes were introduced toward that goal, little testing was undertaken to confirm these are bug-free.
Saved situation reload is not exactly trivial to implement correctly:
On reload, vehicles always have zero velocity. Yet, the saving might in fact have occurred at a non-zero velocity, implying that the saved vehicle state (e.g. engaged gear, engine RPM) may be erroneous, and lead to edge cases in the code, normally deemed impossible to manifest, to actually do. Other contextual information may differ between the time of saving and the time of reloading as well. For example, the user is free to change the date and time when reloading a situation, consequently bringing about discrepancies in functionality related to, e.g., timetables (delay, stops serviced prior to saving, etc.), or heating/cooling (different solar elevation angle). Generally speaking, this is a problem area rather similar to the one challenging the AI when abruptly respawned by the game; but unlike that case, for which relatively thoroughly tested countermeasures have been introduced, no safeguards are currently available for ensuring that the contextual transition after saved situation reload is a smooth one.
On reload, const- and .cti-file ([setvar]) entries might have changed. Unless scripts had bothered coping all the hundreds of them over to variables (spoiler: none do), they may be in trouble.
On reload, any GetTime-based timers may fail, because of the system variable being reset.
There appears to be precision loss in vehicle state persisted to an .osn-file during situation saving. More accurately, while variable values seem to be persisted correctly, upon reloading, comparison and in particular equality testing fails in curious ways. It is a well-known fact that OMSI internally operates on inexact float values -- 0.5 for instance being represented as 0.4999.... Yet, testing whether the latter value equals 0.5 normally correctly yields logical truth. Unfortunately, post-reload that same test fails, necessitating that one counter-intuitively test for "marginal inequality" (e.g. abs(0.5 - var) < 0.0001) instead. That has long-reaching repercussions -- any code is doomed to fail when primitive numeric operations no longer work as expected.
The workaround chosen by many vehicle authors is to wipe out as much state as possible (by allowing all inits to re-execute as if the vehicle were "freshly-spawned"), while for the most part ignoring the other facets. As a consequence, we oftentimes witness vehicles that post-reload have a non-configured / "blank slate" IBIS; dashboard switches being reset to their original spawn-time positions; cabin temperature being equal to the environmental one, despite the A/C having been on for hours; and so on. In our opinion this isn't a proper solution, as it beats the whole point in saving a situation -- getting back a vehicle that is identical, both in terms of internal state and external context, to the one captured by the "save-point".
Course of action
Identify what state is worth or even possible / sensible / practical to preserve across situation save-reload cycles; for example dashboard switch state. Only such state should remain excluded from re-initialization (init calls) upon reload. All other state, e.g. transmission output torque, shall be re-initialized upon reload.
Ostrich algorithm for the second bullet. Duplicating all entries as variables is not worth the effort, and would likely be a performance hit. Furthermore, processing of piecewise-linear functions ([newcurve]s) would have to be re-implemented in "user-space", which would be rather messy, given the static nature of variable declarations, imposed by the language, precluding declaration of, and assignment to, arbitrary new variables on-demand at runtime, that a generic, reusable solution would require.
Refactor all GetTime-based timing operations to rely on Timegap instead. We have been eliminating those for a while now, due to there being other pitfalls associated with them as well, but there are still some occurrences remaining in the wiper and VDV scripts.
With regards to the last item, figure out whether it always occurs, or only does for decimals exceeding a certain precision or scale. See if there are practical workarounds, such as padding such values with an extra trailing (decimal) zero, as M+R seem to do in their scripts some of the time. model- and sound-config changes in literals might be necessary as well.
Progress thus far
Thus far the focus has been to preserve more state than the vanilla scripts did. Only now have the downsides of doing so dawned on us.
User-level workarounds
For best results, always save the situation while the vehicle is stationary, and, before reloading, do not alter the date and time. Even then you may hit the other problems discussed herein, which is why this use case remains, for the time being, unsupported.
Background
Currently the use case of reloading a previously saved situation is not formally supported. While, as part of the work on 1.5.3, some changes were introduced toward that goal, little testing was undertaken to confirm these are bug-free.
Saved situation reload is not exactly trivial to implement correctly:
[setvar]
) entries might have changed. Unless scripts had bothered coping all the hundreds of them over to variables (spoiler: none do), they may be in trouble.GetTime
-based timers may fail, because of the system variable being reset.0.5
for instance being represented as0.4999...
. Yet, testing whether the latter value equals0.5
normally correctly yields logical truth. Unfortunately, post-reload that same test fails, necessitating that one counter-intuitively test for "marginal inequality" (e.g.abs(0.5 - var) < 0.0001
) instead. That has long-reaching repercussions -- any code is doomed to fail when primitive numeric operations no longer work as expected.The workaround chosen by many vehicle authors is to wipe out as much state as possible (by allowing all
init
s to re-execute as if the vehicle were "freshly-spawned"), while for the most part ignoring the other facets. As a consequence, we oftentimes witness vehicles that post-reload have a non-configured / "blank slate" IBIS; dashboard switches being reset to their original spawn-time positions; cabin temperature being equal to the environmental one, despite the A/C having been on for hours; and so on. In our opinion this isn't a proper solution, as it beats the whole point in saving a situation -- getting back a vehicle that is identical, both in terms of internal state and external context, to the one captured by the "save-point".Course of action
init
calls) upon reload. All other state, e.g. transmission output torque, shall be re-initialized upon reload.[newcurve]
s) would have to be re-implemented in "user-space", which would be rather messy, given the static nature of variable declarations, imposed by the language, precluding declaration of, and assignment to, arbitrary new variables on-demand at runtime, that a generic, reusable solution would require.GetTime
-based timing operations to rely onTimegap
instead. We have been eliminating those for a while now, due to there being other pitfalls associated with them as well, but there are still some occurrences remaining in the wiper and VDV scripts.Progress thus far
Thus far the focus has been to preserve more state than the vanilla scripts did. Only now have the downsides of doing so dawned on us.
User-level workarounds
For best results, always save the situation while the vehicle is stationary, and, before reloading, do not alter the date and time. Even then you may hit the other problems discussed herein, which is why this use case remains, for the time being, unsupported.