February is gone, but we're here with another update on openage and what happened over the month.
Our initial February implementation goal from last month was getting the simulation running with player input. However, that input part turned out to be more complicated than at first glance, so it will take a little longer before there is anything interesting to talk about. However, there are other things about the general simulation framework and the renderer that made some progress, so you get news about that instead.
Simulation Time Shenanigans
The most precious resource of our internal simulation is time (as in actual time points provided by a clock). This has to do with how our engine calculates the current gamestate. In openage, the gamestate is event-based which means updates to anything (unit, building, or cactus) are scheduled for a specific time and then executed when the simulation time has advanced enough. Therefore, it is very important that the internal clock works correctly, since we would get all kinds of simulation deadlocks or desyncs otherwise.
Which leads us to a funny little "problem" with the clock that was merged in PR #1492 last month. Advancing the time consists of a simple diff between the current system time and the time of the last update, multiplying this value by the current simulation speed, and then adding the result to the cumulated simulation time. Additionally, this clock has no regular update intervals; it only advances time as a side effect of getting the current time. And all that works reasonably well... until the program is involuntarily stopped by a debugger or the OS going into sleep mode or your browser in the background eating too much RAM. You might have guessed it already but the problem is that the time diff between system time and last update grows larger and larger, even if the program is frozen by the OS. Technically, the simulation never stops in this case. When you close your laptop lid on a running game, you would probably be surprised that the AI won the game while you were away for 2 hours.
But openage development isn't about AIs taking over when you don't expect them to. So in the implementation, the clock has a dedicated update method, caps time advancements at a very small time value, runs in its own thread, and (hopefully) doesn't cause trouble anymore.
Rendering with the Clock
Other than the internal event-based simulation, the clock is also used in the renderer to time animation frames. Most of the functionality for that was completed in a PR this month which also added a bunch of other rendering features (mostly asset management). Playing animations based on the current simulation time also got its own demo which you can see here:
(Run with these commands:)
./bin/run test --demo renderer.tests.renderer_demo 4
The video of the demo also shows how animations can speed up, slow down and even reverse based on the simulation speed. Reversing time is something much more relevant for the gamestate than the renderer, but it's cool to show off here.
It will be input events for the gamestate, but this time for real. There are no major features that need implementing anymore which don't involve the gamestate. Simulation, rendering and the event loop are all set up and working. For input events, we still need to rewrite the control flow of the old input handlers so that they produce events for the gamestate. Once that is finished, we can start creatng game objects that receive and act on these events.
Any more questions? Let us know and discuss those ideas by visiting our subreddit /r/openage!
As always, if you want to reach us directly in the dev chatroom: