Saving blockair/blockairh is nice because RecalculateBlockAirMaps uses the sim rng, which means the sim rng would get advanced in Simulation::Load. Also rename RecalculateBlockAirMaps to ApproximateBlockAirMaps because that's what it is, an approximation, and it's needed only if there are no block air maps in the save.
Simulation::frameCount keeps track of frames elapsed since the beginning of the simulation, zeroed at clear_sim. It overflows when it reaches the 64-bit limit, which means anything that depends on it should either handle this, or not fail catastrophically. sandcolour (the only thing that depends on it as of now) is a good example of the latter: sandcolour has a periodicity of 360 frames, which means that there is one sandcolour period that is cut short by the overflow. This is not "handled" (the period is cut short, which is detectable by users) but is not catastrophic either (it's not a big deal, and it won't ever happen unless someone hacks the save).
Also restrict saves with determinism data to 98.0.
A bug existed before where certain events would not update Engine's lastTick. If the sim was lagging hard, then this could cause "script is not responding" errors to appear in unintentional situations.
The starting execution time is tracked in LuaScriptInterface instead now, and set in tpt_lua_pcall
Also replace a few rename calls with RenameFile calls. Old code doesn't expect rename to overwrite existing files without question, when it in fact can.
We can't rely on atexit, handlers registered with it are in a hard to establish ordering relationship with destructors of static and thread-local objects.
... while retaining all the functionality of stamps.def.
Also fix stamp names encoding only 32 bits of the timestamp, migrate from stamps.def to stamps.json if the latter doesn't exist, delete both on migration to the shared data directory, rescan stamps at startup, and make rescanning a painless process in general by removing invalid entries and adding missing entires at the beginning of the list.
Request ownership is no longer flaky. Requests are now owned by the code that makes requests, and Requests and the RequestManager co-own RequestHandles. RequestManager disowns a RequestHandle if it's done with it or if Request code reports that it's no longer needed.
All libcurl code has been moved to RequestManager. This is nice because once NOHTTP is removed, we can add any number of RequestManager implementations, for example one for Android.
Client outliving RequestManager is still a problem, this will have to be addressed later.
More precisely, refactor the code responsible for routing these GameController events to the Lua side. The issue with the previous solution was it relied on preprocessor macros to switch between Lua-ful and Lua-less builds.
Also make ENFORCE_HTTPS optional, but default to enabled, so unencrypted HTTP is disabled by default, and require it to be enabled for release binaries.
This website API was created to enable TPTMP to prove the identity of connecting users, and while TPTMP works fine without explicit support for this from the game, it has to resort to parsing powder.pref. This is not only ugly but also likely to be disallowed by the next version of the script manager. This new script manager will probably come after 97.0, so it's okay for it to rely on a game feature that won't be available until 97.0.
Also restructure meson.build and the ghactions workflow a bit, and enable -ffunction-sections and -fdata-sections.
Note that starcatcher uploads have not been tested and most likely don't work.
Also fix a few bugs and other weirdness in Platform::DirectorySearch. Empty string paths would crash and filenames with 4 or fewer characters wouldn't register.
This fixes bugs like "type\0hello mom" being a property name sim.partProperty accepts and half-fixes bugs like text formatting codes making gfx.drawText exit prematurely.