Two Weeks in Veloren 228

11 minute read09 March 2024

Authored by Christof

These weeks, we learn about glider physics, Weblate preference and plugin architecture.

- Christof, TWiV editor

Contributor Work

Thanks to last two weeks' contributors @uniior and @crabman, @imbris, @danielkenji83, @floppy, @necti, @do-no-van, @fvasco, @Synis, @juliancoffee, @otto.splvs, @walpo, @neras.

The merged work includes more beginner balancing, shaderc optimization fixes, attack blocking, terracotta tweaks, glider buffs, sword vs speed buff balancing, more sword balancing, translation updates, cave updates 💎, more flexible asset autocompletion, a bunch of Weblate translations, generating worlds from the command line, body transformation, translation fixes, enemy balancing in terracotta ruins, lots of translation enhancements, chat window updates, glider fixes, gliding travelers, admin broom improvements, beam aiming fixes, dependency vulnerability fixes, loot table simplifications, dropped item merge, better character loading debugging, admin glider, and pets for NPCs.

Ongoing (unmerged) work is happening on learnable recipes, vampire castle, spots in plugins, loading plugins from the server, quadtree LoD tiling, animated NPCs in plugins, attack balancing, bitcode for more efficient network communication, dwarfen mines, NIX script updates, sword animation, structure data loading, sprite attributes, a new voxygen UI, hammer skills, mage tower, attack radius, further cave changes, aabb_in_circle refactoring, rock snapper animation, test server fixes, inventory overflow, aerodynamics, loot table in structure rework, loot table balancing, merging torvus and more Weblate translation updates.

Phew, there is a lot of coding going on at the moment!

This developer blog is based on information collected in #blog-content, where game contributors are always invited to communicate their updates or simply post a link to a different channel.


Mushroom spores

The community voted to keep "energy" over "stamina" in descriptions.

The discussion about using a different or even creating a custom UI crate for veloren rekindled.

Tweaks, fixes and additions to air content by @juliancoffee

Glider physics

So, remember the update to the glider which left some people upset? Well, sorry, although we did buff it later, so I guess it's fine now :). But I'm here to announce a new change, more like a bugfix, to be honest.

Two things:

  • Actual wind. We missed it in the client-side calculation of gliding, this update enables it, and it's much cooler now. Your gliding ratios will naturally be affected by it, if you fly into the wind, your horizontal velocity will be lower, while vertical one is the same, which means you will cover less distance until you touch the ground.

    But the same is true if you follow the wind, in that case, your velocity is buffed by it, which means you can cover more distance until you touch the ground! Whether the wind goes where you want to go or not might be the question of luck, yes, so ... I wish you all good luck!)

  • Ridge lift. Here @Treeco might add more (he was responsible for fix in this MR), but conceptually, the more steep the terrain is, the bigger lift you get, because the wind pushes into the ground and bounces from it. If it pushes into the mountains, the only way it can go then is upward, so you get a massive boost there. Here is the video during the strong storm. (Note, air velocity and actual upward gliding velocity).

NPC Gliding AI

For a while, humanoid NPC with gliders did equip the glider when reaching the velocity limit soon after which they would receive fall damage, but the way they controlled their glider was wrong, and they did stall very frequently. Now, this problem is fixed, as they are using their glider maybe even better than Voxygen's automatic glide feature.

Admin tools

For a while, we had The Broom in /kit debug, it resembles the legends of witches using them to fly, but the actual implementation and visuals were close to non-existent. So I did improve things a little, by adding better particles and orientation. There's an intermediate state shown in the video below, and since then we have improved things to change orientation based on velocity (so now the animation also changes depending on whether you fly up or down) and better particle positioning, which can be seen if you try to fly straight down.

And, for a long time, I was working on Admin Glider. The goal was revamping internal ability systems, as for now we only can have them on weapons, which is limiting, we want to do more. Also, it's a chance to experiment with the glider itself and explore different gliding physics effects. Here is a very short demo.

Here is the recorded video:

In the future it allows us to be more flexible with where our abilities come from, so we can implement things like fishing, better mining, armor abilities, fist fighting and so on.

Comments by @Treeco:

So, ridge lift isn't a new feature, and in fact we've made it weaker than before, but previously it applied in the wrong places.

It's meant to represent horizontal wind being deflected upwards by hillsides, generating updraughts, however we were calculating steepness incorrectly, such that plains were maximally steep, and a sheer cliff faces were considered horizontal. This lead to unexpected, random, strong thermals while travelling, and was generally just confusing. It seems to work more as expected now.

Animated characters in plugins by @Christof

This figure has a separate idle and running animation

I have a working animation inside a plugin, connected via WIT (so I could also write the animation in C++, java script or python), hot reloading for plugins isn't working, yet, but it is already very cool!

Plugin source code

And these are the most amazing features of all:

  • you can compile the plugin with only a copy of the wit, no veloren sources are required
  • you can debug the plugin in chrome, single step into Rust independent of veloren:

The output of the tested function:

And the JS test harness

import {animation, events} from './anim.js'
import {getBody} from './veloren/plugin/actions.js'

let bodyidx = getBody("lizard");
let body = new animation.Body(bodyidx);
let dependency = {
    velocity: [1.0, 2.0, 0.0],
    ori: [0.0, 0.0, 0.0, 1.0],
    lastOri: [0.0, 0.0, 0.0, 1.0],
    globalTime: 0.2,
    avgVel: [1.0, 2.0, 0.0],
    state: 'run',
let skeleton = body.updateSkeleton(dependency, 0.1);

Important translation announcement by @juliancoffee

TL;DR from now on, Weblate is the only accepted way to get your translations into the game.

Now, if I may, a little history.

For some time, we used a simplistic internationalization system via config files. Our game is written in Rust and for config files, we use .ron files. If you know what JSON is, you get the idea, but simply put it's a way to represent common data structures like numbers, strings, lists or objects, using a strictly defined format. Our data structure for translations is an object that maps localization keys to the translated text.

/// WARNING: Localization files shall be saved in UTF-8 format without BOM

/// Localization for "global" English
    string_map: {
        // SCT outputs
        "hud.sct.experience": "{amount} Exp",
        "hud.sct.block": "BLOCKED",       

    vector_map: {

The snippet above defines two keys: hud.sct.experience and hud.sct.block.

There are some disadvantages to using it, and I think you will figure them out for yourself. However, the main disadvantage is that this format is only used in Veloren, so there is no tooling for it. We could build this tooling ourselves, and we tried, but what we ideally need is some production-ready solution we and our translators (yes, I'm looking at you, the person behind the screen :3) can use.

So we started by changing the underlying format to Fluent, a localization format by Mozilla. We could go with something older like gettext, but we decided that Fluent will serve us better, as we're building the game, and we need more modern features.

hud-sct-experience = { $amount } XP
hud-sct-block = BLOCKED

This is the same snippet, much easier to write and read, don't you think?

That solved a lot of problems but didn't solve the main one: You still need a lot of expertise to get your translation into the game. The only way to get anything into the game is by committing it to the git repository, which means you need to at least know what that is, and then how to use it. Ideally, we prefer you also wouldn't burn out in the middle of doing all of it.

That's where Weblate steps in. It's a web interface, you can open it in your browser, just go to

After you log in, you can start suggesting translations, simple as that. Then, either your translation is reviewed by dedicated members of the translation team, or you get three upvotes from the community and soon after that, the next time you get the update from Airshipper, it will include your work!

Check our translator documentation for more:

For better or for worse, I'm here not to tell you the story, but to share a decision we made. In the past, the only way to get your translation in the game was to open a Merge Request on GitLab and get it reviewed and merged.

It was unnecessarily hard for non-programmers, and we introduced Weblate as an alternative way.

Recently, we focused our attention on Weblate and made it the recommended way to translate.

Weblate helps us with the organization of the translation team, we can define per-language reviewers, and if not we have escape-hatch in terms of community voting, multiple people can work with the same language at the same time, which wasn't possible with git-based workflow, it provides a lot of useful stats, it even has some automated checks.

There are downsides to it, as it makes the feedback loop much bigger, but there are some ways to make it shorter. Also, it's a bit longer to review contributions in Weblate, but we believe it can be solved in the future.

That said, git isn't happy when multiple entities touch the same part of the project and requires careful coordination of workflows, which puts a lot of work on maintainers, so we needed to choose, and we have chosen Weblate.

If you contributed via GitLab in the past, reach out to us, there is a high chance we will give you a reviewer role in Weblate, leave a comment on your accepted GitLab MR, so we know that's you.


Paradise Island? See you next time!