Two Weeks in Veloren 225

13 minute read20 January 2024

Authored by Christof

These weeks, we look at Haniwa tombs, WGPU testing, item i18n and more sprite IDs.

- Christof, TWiV editor

Contributor Work

Thanks to last two weeks' contributors @imbris, @dsalt, @jtornello, @Pybit, @yusdacra, @Isse, @the_dimasmith, @hrom, @juliancoffee, @crabman, @walpo, @zesterer, weblate contributors, @fvasco, @alphyr, @floppy.

The merged work includes more efficient screenshot conversion, shader fixes, a day length slider for singleplayer, more potions, system dispatcher optimizations, and nix build script updates, cave entrance fixes, Ukrainian translation, twig shoulder rename, buff extension command, unstacking buffs, removing twitter, server rules at login, item internationalization, a modernized character selection menu, updated translations, a large sprite rework, an update of the assets manager dependency, Haniwa tomb dungeon, and a sword nerf.

Ongoing (unmerged) work is happening on event system diversification, loot export, drowning in terrain, beginner balance tweaks, a much updated WGPU version, wireshark decoder, more price entries, item tiering fixes, loading plugins over network, more options for kill NPC, dwarfen mine, and a digging tooltip fix.

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.

WGPU testing by @Isse

We're currently trying to upgrade our graphic backend and need your help.

In the new version DirectX11 is no longer supported, but OpenGL is. So I'm mostly looking for people to test on Windows, but other people testing is helpful too, to be able to catch any bugs.

OpenGL is supported on Linux in this new version too.

There is a form here to go through, and there are download links in the form. And any question can go in the thread of this message.

Form link

In case you want to try the binary before starting any feed-back form, here are direct links to the binary downloads: Windows Linux MacOs x86 MacOs aarch64 - but please keep in mind that we created this blog-post specifically to receive your early feed-back about this significant change.

Haniwa updates

Tree burning event

YouTube live link

Wiki update

Updated: For some time, loot tables on the wiki were out of date and did not support multi-loot. These now generate from exported data, with collapsible grouping in drop tables. Examples below are the Yeti drop table and Rugged Hide source table.


There is also a new MR which extends /buff command to be used with complex buffs like polymorphed, so you can transform yourself into a bunny :3

Strange bugs (enable sound to experience what goes wrong here):

A new way of fighting a Frost Giga resulted in a lot of traffic until the bug was fixed:

A collection of nice photos

Copious metal resources:

Shield blocking by @Papinha

Proposal to make giant trees great again

You can run veloren on Android … using a Windows emulator

Server rules by @zesterer

@crabman and I spent the last few days working on a menu that displays server rules when players first connect to a server. Accepting server rules is mandatory, and happens on first connection (or for subsequent changes to the rules). Rules can be customised by server owners and fully support localisation. See here for more information.

@juliancoffee: By the way, for an official server, we do accept translations of official rules, as I understand ⁠ rules transl… or ⁠new-contributors if you don't have permissions

A new character selection by @zesterer

I've also been working on overhauling the character selection screen. The (very old) placeholder backdrop has been removed, and your character(s) now appear on an Airship, hovering over the world. The terrain beneath corresponds to that of the world you're about to join.

Item internationalization by @juliancoffee

What and why this MR does.

First, "cosmetic" things.

We created a new veloren/common/i18n crate that hosts Content type, that previously was in the common::comp::chat module. Because Content is general enough, it needed its own module anyway, by putting it in its own crate, we can significantly reduce the compilation time of veloren/client/i18n crate which depends on Content.

Additionally, Localization::get_content has better docs (cut from !4236 (closed)). And using random in i18n is explicitly discouraged, yet not completely deprecated. Read #1655 for more.

Now, the reason you're reading this — item localization. This MR deprecates and Item.description() methods along with the corresponding ItemDesc methods. Instead, we use the ItemL10n manifest (like item_image_manifest.ron, but in common) that maps ItemKey to the i18n identifier.

Important note: if an item has a different ItemKey it has a different i18n identifier, which means two things.

  • All modular weapons have different i18n identifier, we don't use concatenation magic.

  • Some modular weapons have the same i18n identifier (like Staff with Heavy core and Light one). We only differentiate by hand-ness and primary component. That's how ItemKey works and that's what we do with voxel assets.

Import note no. 2: we deprecate these methods, not remove them. There are a number of systems that rely on these.

  • Plugins can't use i18n yet.
  • CSV import/export.
  • Inventory sorting (by name) is server-side, which is unfortunate.
  • Crafting UI ordering and filtering. This is probably easiest to solve because all data is available, but I think that should be done in follow-up MR, this one is big enough.
  • There was also dependency on the English name in the sfx.ron config, but it's fixed in this MR.

After we solve all these issues in follow-up MRs, we can remove Item::name/description. (as well as ItemKind::Ingredient::descriptor).

oh, almost forgot, it also changes /kit all, which now really gives you all items, that's why Admin Bag is now enlarged.

On the topic of translations, that's still a concept, but we want to start handling grammatical gender.

I want to start with hud/chat.ftl and expose a few of the variables there.

First is what I call gender, in our case it's an answer to the question "he or she?", and we check it from Body.body_type.

Second is animacy, which is roughly an answer to the question "is it sentient or no?" and roughly corresponds to what the English language calls "it".

That allows us to do things like that for Slavic languages that require agreement with the gender of a noun.

hud-chat-online_msg = [{ $name }] { $user_gender ->
    *[he] зайшов на сервер
    [she] зайшла на сервер

Because we use body.body_type, for a moment, your gender is derived from the sex of the character you play with.

I showed the example from Ukrainian, what about other languages you would ask?

Well, it's probably impossible to cover every rule of every language, but we want to try, so if you see some problems with how we handle your language or some requests, please reach out to me on Discord, @juliancoffee.

Sprite identifier rework by @zesterer

These two weeks started quietly and then a lot of changes came in over the past days. Another one of these is @zesterer's change to expand sprite identifiers:

Over the last few days I've been working on overhauling the way we represent sprites, the small-scale voxel objects you find around the world like grass, crafting tables, and doors.

This is an internal change that's been needed for a long time, but the fact that we recently started to approach the existing limit of 255 sprites was concerning and something needed to be done. As a happy side-effect, this overhaul should open up a lot of opportunities for more interesting sprite behaviours!

A little context

In Veloren, each block is represented as 4 bytes (where each byte is 8 bits, i.e: 256 possible values). The first byte is the 'block kind': this tells the game the overhaul type of block.

Examples of block kinds include Stone, Wood, Grass, Ice. For these so-called 'filled' blocks (i.e: that get rendered as a coloured cube), the remaining 3 bytes specified the RGB (red, green, blue) colour.

However, block kinds can also be 'unfilled' such as Air and Water. In these cases, we don't need to use the remaining 3 bytes for the colour, since these blocks have no colour (water colour is hard-coded elsewhere and can't change on a per-block basis)! As such, we use the 3 extra bytes to represent sprites. Previously, we chose the first of these to represent the 'sprite kind'. Like the 'block kind', this tells the game what type of sprite is present. We have sprite kinds like LongGrass, CraftingBench, Pumpkin, WildFlax, etc. You've no doubt encountered these sprites on your adventures.

However, there's a problem! A byte can only have up to 256 possible values. Since one of them is used to represent the lack of a sprite (Empty), we can only have a maximum of 255 possible sprites! That might sound like a large number, but Veloren is an ever-growing project with ever-more sites and features that demand a wider variety of sprites. Within the last few weeks we've come very close to the limit, so it was time to do some work to expand that number.

The people demand sprite attributes!

The old approach was quite inefficient. We only used just one of the 3 extra bytes, so we can do better. However, there are more things we'd like to be able to do. In particular, for a long while we've wanted to be able to give sprites additional attributes that change their behaviour. Here are a few examples of attributes we might want to give sprites:

  • The orientation of the sprite
  • The growth stage of plants
  • Whether a lantern/lamp has been turned on or off
  • Whether a trapdoor or gate it open or closed
  • The level or quality of loot in a container
  • Whether the sprite has snow covering it
  • Whether a pot/planter has a plant in it, and the type of plant
  • The specific objects that a cupboard or shelf has on it
  • The material of an item of furniture (colour of paint, stone/metal/wood, etc.)
  • The colour or design of a flag/banner
  • etc.

The solution

To accommodate all of these needs, I've overhauled the way we represent sprites. Now, the first of the three extra bytes corresponds to the sprite 'category', a new idea introduced with this change. The category of a sprite tells the games which bits in the remaining two bytes are used to store which attributes (or whether those attributes even exist at all!), along with the sprite ID (which, together with the category, gives you back the sprite kind that we mentioned earlier).

By placing things in categories, we can isolate the attributes above to those categories. We might want plants to store their growth stage, but we don't want to be wasting those bits for sprites that can't grow at all! Therefore, only the category containing plant sprites gets allocated the growth stage attribute.

This new design is immensely more flexible. In addition to allowing for many sprite attributes, it also allows the sprite ID to inhabit as many as all of the remaining 2 extra bytes (i.e: 16 bits). That means we can have up to 65,536 sprites per-category! Needless to say, I think it'll be a long while until we need to think about upgrading our sprite representation again!

Express deliveries (not yet in game). See you next time!