Unvanquished 0.54, ARMed and dangerous

Happy new year, Unvanquished 0.54 is there!  🎉

Many bugs were fixed as usual, the game can now run on Linux ARM devices, navigation meshes for bot navigation are now generated in game, bots were improved, and Sweet joined the team… Let’s talk more about all that goodness!

Granger celebrating the new year!
Granger celebrating the new year!

ARM binaries on Linux!

Unvanquished 0.54 on arm64 (Banana Pi M5, Armbian/Linux, Mesa/panfrost).
Unvanquished 0.54 on arm64 (Banana Pi M5, Armbian/Linux, Mesa/panfrost).

Unvanquished 0.54 is the first Unvanquished release to be available on other platforms than 32-bit and 64-bit x86. Unvanquished is now playable on both 32-bit and 64-bit ARM on Linux. Some graphic chips provided with ARM-based devices may be a bit slow for playing Unvanquished, but this port also fulfills the need for running the game server on ARM.

ARM support is currently only available on Linux. The NaCl virtual machine technology we use for virtualizing downloadable game code isn’t available for ARM on Windows and macOS. Speaking about macOS, Unvanquished for 64-bit x86 runs very well on Rosetta2 so for now Rosetta2 is a very good solution on M1 macs.

ARM is still considered a secondary platform; as such, the updater/launcher isn’t available for it. Those who want to try out Unvanquished on ARM would need to use our “universal zip” (to be found in our download page) and follow the instructions in the README file from it.

We still want to port our game sandbox from Native Client to WebAssembly but this is not ready yet. Doing this will enable more systems and hardware, but a complete jump to WebAssembly would still be a bit too early as some platforms like 32-bit x86 aren’t supported yet in virtual machines and toolchains.

While doing it, we improved the code to make it more multiplatform, and the engine toolchain is now ready to support many other platforms. The only thing that is now preventing us to support more platforms are the gamecode sandboxing technology we use.

As a side note, all the binaries for all hardware architectures and operating systems were built in docker containers, including macOS binaries built in a Linux container using Darling.

Polishing the graphical user interface

Unvanquished map loading screen.
Unvanquished map loading screen.

The map load screen now displays the map name and the map author(s) names based on map metadata given they are provided in the map packages. For historical reasons, people baked such information in the levelshot, this is not required anymore.

People wanting to be creative may still want to do complex levelshots, but otherwise, having a good looking map load screen for his own map now only requires to capture a shot of the map, write some metadata and… tadaa, the game prints the information nicely. In the future we may even translate the way the information is printed, something that wasn’t doable with a text baked in a bitmap.

Example of welcome screen on a modded server.
Example of welcome screen on a modded server.

It’s now possible for a server owner to display a welcome screen when players join a server, by providing such welcome screen in a custom package. This is very handy when implementing gameplay changes to announce what’s new and what changed to people joining the server hosting the changes.

Handling of color codes in text was improved, and usage of color code in fields like user names is no longer penalized so much when counting the maximum allowed length. A color code only counts as one letter rather than the number of characters it takes to write the code. Color is now properly reset after user-provided strings to avoid custom colors to be applied on the whole string.

Some configuration windows were refined, for example by adding or removing fields for options that were added or removed. Some logs and other text messages were revamped.

On console side, setting a value to a cvar using the “/cvarname value” syntax doesn’t mark the cvar as archive (permanent) anymore. To mark the cvar as archive when setting it, one must now explicitly use the “/seta cvarname value” syntax.

Refining the gameplay

Good old lucifer cannon.
Good old lucifer cannon.

The lucifer cannon model is now reusing again a previous model we used in the past. People preferred how this older one looks more intimidating, which is relevant for what is our most powerful weapon. We have yet to decide what to do with the other model.

There is no negative momentum anymore (i.e. momentum becoming less than it is at the start of the game). A bug affecting Marauder zap chains is fixed. Rockets no longer follow dead players.

New icons (not all are redone yet).
New icons (not all are redone yet).

Spectators can no longer open the beacon menu, since they don’t play, they have no information to give! Some inventory icons were redone by Nanaa, Gireen and Bob Vador. The unpowered animation for the medistation is now correct.

When a granger puts out a fire with its spit, a visual and audible notification is done so the player knows about the success of the operation.

The slap command was improved (velocity is now independent from mass). The teamstatus command, introduced in Unvanquished 0.53.0, is now enabled by default.

For developers, it is now possible to remove momentum in game using the give command (previously it was only possible to add momentum). Speaking of game code, more migration to the GLM mathematical library happened.

Improving bots

Bot “tremble” is now fixed. It was a bug making a bot sometimes appear stuck in one spot while trembling as if it were confused by its own contradictory decisions. Bot behavior trees received proper care and attention. Obstacle avoidance was also improved, and advanced Dragoons now aim before launching their barb. Dragoon bot is now prevented to throw a barb when too close to an enemy to avoid hurting oneself. Bot competencies were re-attributed to the various skill levels.

It’s now possible to set the skill level when adding a bot with the bot command, a new listbots command was added to only list bots, and it’s now possible to configure bot competencies with granularity: head aiming, predictive aim, medkit usage, armour usage preference, flee running, pain feeling, dragoon barb usage… The g_bot_infiniteMomentum cvar now makes possible unlocking all alien forms, weapons, and upgrades for bots, regardless of their teams’ momentum.

In game generated navigation meshes and shipped navcons

For bot navigation we use a technology named navigation meshes or navmeshes. Navmeshes were previously produced at map build time, at the same time we precompute the lightmaps and things like that, before releasing the game or custom maps themselves. And those navmeshes had to be distributed with the map themselves.

Generating navmeshes in game.
Generating navmeshes in game.

So, until now we generated navmeshes with a separate tool named daemonmap which now becomes obsolete. We now generate them in game.

The first drawback of generating the navmeshes at map build time is that it was needed to ship them with the maps, from that came many other drawbacks! If the generator is upgraded, existing maps would still ship existing navmeshes that would not benefit from the generator upgrade. If the gamecode was updated, existing navmeshes would still target the previous version. If someone wanted to make a mod and add or modify species, existing navmeshes would be missing for the added species or just assuming the wrong species properties.

By generating the navmeshes in game, maps can be shipped without them. The game code regenerates the navmesh whenever something has changed:  either when the map changed, or when the game changed. It also means improving the generator would automatically regenerate the navmeshes when distributing a new version of the game!

The code for navmesh generation, based on Detour and Recast, was basically ported from daemonmap to our game code, and some mechanism was implemented to allow the generation on the fly without blocking the server.

Some navcon files are now shipped with some maps to help bot navigation. A “navigation connection” or navcon is a special file listing one-way or two-way paths between two apparently disconnected places (in Recast/Detour such link is called an “off-mesh connection”). It can be used for example to tell bots they can jump from a platform to reach another route, and include that specific path in their path computation. The navcon format is now text-based, making the navcon files more friendly with git repositories.

Efforts on renderer and engine

Light styles can now be disabled. Light styles are a kind of precomputed dynamic lighting for static map objects. They are generated at map compilation time while baking lightmaps. The feature works by dynamically blending multiple lightmaps for the same surface in game. As this feature isn’t very heavy on performance (it already existed in early 2000’s and was already used in Tremulous maps), it is only disabled in “lowest” graphical preset for now.

More files for optional features are prevented from being uselessly loaded when related features are disabled: for example, deluxemaps aren’t loaded anymore from disk and sent to GPU if features making use of them are disabled. Because XreaL (the engine Dæmon derivates from) was mostly a technical demo in some ways, it happens that some code was more focused on showing off the features than disabling them, and sometime the code made strong assumptions about the availability of this or that! With time we make things more optional, step by step, which also allows us to make the code more robust.

Some serious issues with dynamic lights have been resolved. A longstanding bug meant that only 1 out of every 4 dynamic lights in the scene was actually being rendered. The bug went unnoticed until now because most of our dynamically lit assets use clusters of several lights. As an unexpected side effect, the fix for this also fixes the even worse (and easily noticeable) bug affecting recent versions of the proprietary Nvidia driver where dynamic lights are far brighter than they ought to be. It appears that for some inscrutable reason, the change makes a bug in their GLSL compiler stop triggering.

The engine can now fallback on the EXT_framebuffer_object OpenGL extension if ARB_framebuffer_object isn’t available. The EXT feature is a subset of the ARB one but we only use the features of that subset, so there is no need to arbitrarily prevent the engine to run on older hardware that can still do it.

The navmesh rendering when using the navedit command is (a little) less buggy. It’s a developer command to turn the game into a special mode to visualize navmeshes and generate navcons. So while having a perfect visualization is not the highest priority (it doesn’t affect players), making it less glitchy is always welcome.

Some unit tests were added using the Googletest framework. There is also many bugs and crashes that were fixed, dead code cleaned-up, code rewritten for better efficiency, more comment written to document the code a bit more, etc.

No more Python 2 in Unvanquished toolchain

The NaCl SDK, the last bit of our toolchain requiring Python 2 to build the game, was ported to Python 3. That thing is only used at build time when producing downloadable gamecode, so this was only a developer concern (the game itself is written in C++ and doesn’t require any Python to run). The aging of Python 2 and the growing unavailability of it would have become a concern for developers and modders if we hadn’t done that port. Bye bye Python 2!

Let’s play!

The game will be 11 years old in February. If you haven’t read it yet, you can read our 10 years retrospective! 👀️

The game entered Beta cycle in 2021, there are now more than 300 community maps played on servers (most of them ported from Tremulous). Along the various code contributions Sweet did, he also ported almost all those maps…

Let’s spread the word, download the game, join servers, and play Unvanquished! :bsuit:

11 thoughts on “Unvanquished 0.54, ARMed and dangerous”

  1. I encountered an issue with this release: When playing a local game, after loading in everything and spawning the bots the console messages display in the upper left just repeatedly says “Warn: no more slots for bot”. Very annoying to have that just keep flashing up in the corner.

    1. The maximum number of players in the game is 20 by default. You would receive this message if you tried to add 20 or more bots.

      If you want to have more bots and know how to do console commands, you can use: /seta sv_maxclients 64 to increase the limit.

    1. El cliente se ejecuta (pero lento) en rpi4 como arm64 o armhf. El servidor se probó con éxito en rpi3 como arm64 o armhf. No hemos probado rpi2, ¡pero debería funcionar como servidor! 🙂️

      1. Sí, funciona (the server, daemonded) bien en la Pi2. Únicamente he percibido que se ralentiza un poco cuando lanzo los bots, pero supongo que debe de ser algo relacionado con la realización de las navmesh. Pero está genial, esta última versión es mucho más de lo que esperaba, ¡muchísimas gracias, por este gran trabajo! 😉

        1. Sí, el servidor genera la navmesh la primera vez que carga un mapa, por lo que es un poco lento los primeros segundos. Después de eso, las próximas veces reutiliza las navmesh generadas. Ahora tengo curiosidad, ¿estás alojando un servidor en Internet o en casa, o en alguna LAN para juegos en equipo? 🙂️

Comments are closed.