Hello and welcome to another one of our monthly openage devlogs! This month was all about adding
usability features to the engine as well as making the nyan data API easier to use. Well, easier
for us developers at least. Without further ado, let's start with our most interesting new feature.
Selecting units with drag selection on screen is something you see in every RTS game since the
90s and I'm sure everyone reading this has used it before. For the player, the process is pretty simple:
They draw a rectangle on screen by holding the mouse button down and everything visible in the rectangle
is then put into their selection queue. In openage it now looks like this:
While this looks like a small feature, the implementation a bit more challenging than what we have done before.
Most of this is because drag selection requires multiple subsystems to work together to get the desired
result. First of all, we need the input system to handle not just one event but a sequence of three
mouse actions (
MouseUp). For the selection itself, we also
need to figure out which units inside the rectangle are selectable by the player, so we don't end
up with a bunch of trees in our selection queue. Last but not least, the rectangle also has to be drawn
on screen, so the player can see what they are actually going to select.
In our old engine architecture, the implementation of this feature was a hot garbled mess that massively
tanked performance (also visible in our YouTube demo),
partly because it was basically taking control of the renderer which stalled all other draw commands.
This is where our new engine architecture with decoupled subsystems finally pays off big time. In comparison to
the previous implementation, the new drag selection is communicated via sane interfaces from the input system
to the other subsystems of the engine.
Here is how the input events are handled now:
MouseDown: The input system detects the drag selection sequence initialization and switches into a drag selection context
MouseMove: Inputs are forwarded to two different places
- A HUD controller that tells the renderer to draw/resize the rectangle on screen
- A game controller for the player that keeps track of the rectangle position and size
MouseUp: The input system finalizes the selection
- The HUD controller tells the renderer to delete the drawn rectangle
- The game controller sends the final rectangle position size as a drag select event to the game simulation
- The game simulation handles the drag select event by
- Checking which units are inside the rectangle
- Checking which units are selectable by the player
- Finally, sending the list of unit IDs back to the controller
Way back in June, we added configurable game entity behaviour in the
form of the activity system into the engine. However, for the last months the "configurable" part only
existed in theory, since all game entities were assigned a hardcoded activity by default. This month. we
have been making efforts to add support for activities both to our nyan data API and the openage converter.
This will eventually allow us to define the whole behaviour in the modpack itself, which in turn
also allows modders to change game entity behaviour with a simple data mod.
Currently, the nyan API changes look like this:
Since activities are simple directed node graphs, we can model all node types as nyan objects which
point to successor nodes via the
next member. Internal events are handled the same
way, using nyan objects that have members for the event payload. When the modpack is loaded, the engine
builds the activity graph from using the node definitions.
Activities are assigned to game entities with a new ability (also called
references the node graph. This means that every game entity can potentially have its own
unique behaviour (which can also be changed at runtime).
During next month, we will put more work into the configurable activities and release a new data API
specification when we are done. If there is enough time, we will also improve the HUD a bit to
display more useful information for players on screen.
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: