Next: Translating, Up: Hacker's guide [Contents][Index]

### 3.1 Designing levels

#### 3.1.1 Why is level design so important?

As of Liquid War 5, most levels have been contributed by players. While the maintainer of Liquid War 6 has technical knowledge to develop the game, artistic talent and taste might not be his domain of excellence 8-)

Therefore contribution are truely welcomed when they take the form of a new, original, fun and good looking level. It’s believed the levels often make the game much more than its engine. This is true for any type of game, and Liquid War is no exception.

So this section is here to help players understand how to hack existing levels, and create new ones, in the hope that 1) they can enjoy their own creations and 2) possibly share their work with others.

Note that this manual might refer to levels and maps: they are just two different names to describe the very same thing. It’s an alias.

#### 3.1.2 Format overview

Liquid War 6 stores level information in a plain directory.

There is no such thing as an opaque `.dat` binary file. The name of the level is the name of the directory itself, and its elements are the files contained in it.

Files must follow a precise naming scheme. For instance Liquid War 6 expects a `map.png` file to be present in each map directory.

All image files in a level use the Portable Network Graphics or JPEG format. It is possible that in the long term, Liquid War 6 will be able to handle levels as `.tar.gz` or `.zip` files. In that case these files will only be a compressed image of the actual level directory.

See the `./map/` directory of the source Liquid War 6 distribution to see example of maps.

#### 3.1.3 Resolution (map size)

Liquid War 6 does enforce a limit on map size. This is not to frustrate map designers and/or players, simply, it would be a lie to pretend the game can handle arbitrary big maps.

They might look great on your computer but will become unplayable soon on an older machine. And most of the time they don’t look that great, carefully crafted 1280Ã720 just looks awesome and can represent a great level complexity.

Here are the technical limits:

Type | Max width | Max height | Max surface
--- | --- | --- | ---
Texture | 3 000 | 2 000 | 6 000 000
Logical map | 1 500 | 1 000 | 1 000 000

The texture can be somewhat bigger than the logical map, this allows for pretty levels while limiting the horsepower needed to move the fighters and animate everything. Note that you could technically feed the game with a `map.png` that is bigger than the logical map limit, only it will be downscaled when being loaded.

The texture limits are generous enough to accept a full-HD 1920x1080 image, or a 4/3 1600x1200 image, while the “one million pixels” logical map limit is enough to store a 16/9 1280x720 map or a 4/3 1024x768.

Keep in mind that the logical map (`map.png`) will probably be scaled whatsoever, even if it’s within the absolute limits (the game adapts the resolution to your computer speed) and your texture will rarely appear in its native resolution, will probably be distorted, and so on.

#### 3.1.4 Metadata

Older versions of Liquid War 6 used to load a plain `README` file and use this as metadata. Title was take from map directory name. This is still supported, but it now also supports the addition of a `metadata.xml` file in which you can describe your map.

The following files can be defined:

- `title`: map title, what will appear in the menus
- `author`: map author
- `description`: description of the map, to help players when browsing folders
- `license`: map license (short version, just a simple one-liner, don’t use lenghtly copyright notices here, the `README` file would be the file to put long legal sections)

#### 3.1.5 map.png

This is the only required file in a level.

In fact, the existence of `map.png` makes a directory a level. When checking wether a directory is a correct level, Liquid War 6 simply tests the existence and validity of `map.png`.

This image is a simple black & white area, where white zones are the background, the sea, the places where fighters can move, and black zones are the foreground, the walls, the places where fighters can’t go.

This informations can be stored in a 2-color indexed file, or in a grayscaled or even truecolor RGB file, but color information won’t be used. Internally, Liquid War 6 will read the color of every point. If it is over 127 on a 0 to 255 scale, it will be considered as background, if it is below 127, it will be considered as foreground.

#### 3.1.6 layer2.png ... layer7.png

Liquid War 6 can handle mutiple layer maps. Think of a pile of maps, one being on top of the other. This allows you to create a volume, the game considers every layer has two axis x and y, and the z axis is to travel through layers. First layer corresponds to z=0, second layer to z=1, and so on.

Here are the files you can use to define layers:

- `map.png` this one is on top, it’s always defined (z=0)
- `layer2.png` (z=1)
- `layer3.png` (z=2)
- `layer4.png` (z=3)
- `layer5.png` (z=4)
- `layer6.png` (z=5)
- `layer7.png` (z=6)

A `layerX.png` file should be designed exactly like `map.png`. In fact, `map.png` could simply have been called `layer1.png`.

Up to 6 extra layers can be defined (from `layer2.png` to `layer7.png`). This is a hardcoded limit. It allows you to define 7 different layers, including the top `map.png` layer. Keep in mind this layer system is not real 3D, it’s more a “2D and a half” model. Adding layers can considerably slow down the game, so it’s wise to try and use as few layers as possible. Technically, 3 layers will allow you to build bridges and tunnels, which is probably the most usefull construction using layers. Fighters can also have difficulties navigating through layers so piling up layers in narrow “vertical” z-axis based tunnels is probably not a great idea.

The `ufoot/concept/pass` map of the `liquidwar6-extra-maps` demonstrates basic layer usage.

#### 3.1.7 texture.png, texture.jpeg and texture-alpha.jpeg

It is possible to define a texture for the map by putting a `texture.png` or `texture.jpeg` file. It does not need to have the same dimensions as the map itself. Indeed, textures can be much more precise than the actual logical map.

There’s no theorical limit on how big a texture can be, more precisely, it can be much bigger than any hardware/driver maximum texture size. In practice, a too big texture will waste your video card RAM, and slow everything down. Sizes ranging from 640x480 to 1600x1200 are reasonable texture sizes.

If you don’t define this, the `map.png` file will be used as the texture, and also import colors from `style.xml` if defined.

Note that the shape of the texture defines the shape of the map, that is, the ratio with which it will appear on the screen.

The PNG alpha layer will be used for transparency. But to save disk space, it can be convienient to prefer the JPEG format, use `texture.jpeg` instead of `texture.png` and store the alpha layer in a separated file, called `texture-alpha.jpeg`. This avoids handling heavy PNG files, PNG compression not being performant on most textures.

In `texture-alpha.jpeg`, black is considered opaque, and white is transparent. Different levels of gray correspond to different levels of opacity. Previous versions of the game used the other way of doing things (black is transparent) because this is technically, the most obvious way to do things. Black is 0 and transparent is 0. But for a human “reader” of the map this does not make sense. One generally expects white to be the equivalent of “undrawn” or “blank”, well, if it’s undecided, void, transparent, whatever, it’s white. When the Gimp flattens an image, it becomes white, not black.

So white is transparent. Period.

#### 3.1.8 glue.png and boost.png

If there’s a `glue.png` or `boost.png` file in the map directory (you can use one of them or both) then they will be interpreted as follow:

- on areas where `glue.png` and `boost.png` are white, nothing special happens, fighters follow their default behavior
- on areas where `glue.png` is black, fighters will be slowed down. How slowish they will be depends on the ’glue-power’ parameter. If ’glue-power’ is 3 then fighters will move three times slower.
- on areas where `boost.png` is black, fighters will behave faster. How fast they will be depends on the ’boost-power’ parameter. If ’boost-power’ is 2 then fighters will move two times faster.
- on areas where `glue.png` or `boost.png` are gray, they will be slowed down less or speeded up less depending on how dark the grey is.

There can be, at the same place, some gray or black in both `boost.png` and `glue.png`. How this will behave exactly is not really clear at this stage, the recommendation is not to do this (it does not really make sense anyway) but if you do it, game won’t complain.

It’s also wise not to abuse of `boost.png` for obviously, a map filled with “boosted” zones at a X10 pace will require much more CPU than the same map with no such setting. This might fool the automatic resampling algorithm and lead to maps that are unplayable. The spirit of `boost.png` is just to make a few spots go faster.

It’s also important to note that behaving faster or slower means moving faster or slower but also attacking faster or slower, and, in a general manner doing any action with a different pace.

#### 3.1.9 danger.png and medicine.png

If there’s a `danger.png` or `medicine.png` file in the map directory (you can use one of them or both) then they will be interpreted as follow:

- on areas where `danger.png` and `medicine.png` are white, nothing special happens, fighters follow their default behavior
- on areas where `danger.png` is black, fighters die automatically, that is, they become black and loose health. How dangerous these zones are depends on the ’danger-power’ parameter.
- on areas where `medicine.png` is black, fighters regenerate faster, they become bright and shiny as if auto-healing. How efficient this medicine is depends on the ’medicine-power’ parameter.
- on areas where `danger.png` or `medicine.png` are gray, well, it’s in between, the “danger” and “medicine” effect will be proportional to the level of gray.

There can be, at the same place, some gray or black in both `medicine.png` and `danger.png`. How this will behave exactly is not really clear at this stage, the recommendation is not to do this (it does not really make sense anyway) but if you do it, game won’t complain.

#### 3.1.10 one-way-<direction>.png

The four files:

- `one-way-north.png` (AKA “up”)
- `one-way-east.png` (AKA “right”)
- `one-way-south.png` (AKA “down”)
- `one-way-west.png` (AKA “left”)

can be used to force the fighters to go in one given direction, on some parts of the map. If an area is black on one of this meta-layers, then fighters will go in the given direction. For instance, a black zone in `one-way-north` will make fighters go to the north (AKA “up” direction) regardless of the cursor position. The fact that this is a one-way path is understood by fighters and they will take this in account when choosing the shortest path to go somewhere. You can combine vertical and horizontal one-way informations, making diagonal one-way paths.

#### 3.1.11 cursor.png and cursor-color.png

By default, a simple cursor will be displayed, but you can use a custom per-map cursor. Cursors are defined by two 64x64 bitmaps:

- `cursor.png` is a PNG file, very likely to use transparency, which will be default be colorized according to the map colors. You can draw it any color, only greyscale informations will be used. You can keep the original colors if you really want to by setting `colorize-cursor` to false, but the default is to ignore the hue.
- `cursor-color.png` is another PNG file, very likely to use transparency too, which will always be colorized, replacing white by the team color, and black by the “dead” color, which by default is black and is usually a dark color. This colorization is a way to recognize your cursor and know which team it belongs to.

You can define only one of those bitmaps, if doing so, then the other layer will be empty, and won’t be filled with the default cursor data. Note that additionnally, a little letter (single character) will be displayed using the team color, so that’s yet another way to identify which teams the cursor belongs too. The PNG files really need to be PNG (JPEG won’t work) and need to be 64x64, any other size will be ignored.

#### 3.1.12 rules.xml

Whereas `style.xml` is only about the appearance of the map, `rules.xml` allows the map designer to change pretty much any parameter.

Ultimately, the player can still ignore these settings and overide them with its own values, but the idea is: most game options are only pertinent in a given context. For instance, on some maps it’s interesting to move slowly, on some other it’s interesting to move fast. Some maps might be playable packed with fighters everywhere, some other might be much more fun with almost nobody on them.

The approach in Liquid War 5 was to make the options available, but let the player himself find the right settings for the right map. The consequence is that no one ever used all those cryptic options in the advanced options menu, and probably 99% of the players ended up playing with default settings. This is not that bad, but given the fact that changing a few parameters one can totally transform the gameplay, it has decided been that in Liquid War 6, the map designer suggests the right options that matches his map.

This does not prevent the player from toying with options himself, he can still do it.

There’s also one important point to note: all these options are technically implemented as integer parameters. We certainly do not want any float here, since, and it is a Liquid War specific behavior, the game must be 100,00% predictable and behave the same on every platform. As there is nothing like exactness when speaking of floats, those are forbidden here. As for strings, we are dealing here with low-level internals, and this section is not about telling a story. They are technical options only. Booleans are implemented with the usual `false = 0` and `true = 1` convention. Note that other config files in Liquid War 6 might rely on floats, strings, and booleans with conventionnal `true` and `false` values, but not this one. `rules.xml` is special.

This `rules.xml` file is a direct image of the internal “rules” structure, so it contains technical, sometimes not very user-friendly parameters. While hacking `rules.xml` directly is a good way to test things, most of the time, the other file `hints.xml` contains more high-level informations that do the job the right way. A typicall example is speed.

See rules.xml reference.

#### 3.1.13 hints.xml

This parameter is only used by the map loader. The map itself contains none of these parameters, they are only clues (hints, in fact..) on “how to load the map” which are passed to the loader.

Let’s take an example : speed. This `rules.xml` file has a (rather) easy to use “speed” parameter, which will do all the job of finding the right resolution for your map, the right “rounds-per-sec” and “moves-per-round” parameters, in short, it will set many other parameters to fit your needs.

As far as the map designer is concerned, `rules.xml` and `hints.xml` could have been merged (but so would have `style.xml`) but internally they are very different: `rules.xml` contains the real parameters, the one used by the algorithm whereas `hints.xml` contains only instructions which are used once when loading the map and then disappear. The core algorithm has no idea of what was in `hints.xml`, once it’s loaded.

See hints.xml reference.

#### 3.1.14 style.xml

This is a simple XML file defining various appearance parameters. It has absolutely no effect on gameplay. These settings can ultimately be overriden by the player, but the idea is that if the map designer thinks this level looks better with this or that option, let him say it in this file.

See style.xml reference.

#### 3.1.15 teams.xml

In this file one can specify per-map team settings. In short, this is where you can say how many bots you want, which color, and so on. This can be on a per-map basis, so that each map has different customized settings, some maps might be fun with only one bot, some other maps might be fun packed with 8 opponents.

Technically, `teams.xml` will allow you to define up to 4 players and 9 bots. This is an awfull lot considering there are only 10 colors. Basically, it’s OK to simply define:

- 2 players (`player1` and `player2`)
- 4 bots (`bot1` and `bot2`)

It might also be a clever idea to just set up `player2` and `bot1` being the same color, in case of a conflict the game will pick up another color, but in practice those two entries often correspond to “the second player, bot or human, coming on the battlefield”.

All in all, this represents 5 entries to set up (main player, other player or first bot which can be the same, then 3 more bots), it’s OK to have the rest undefined or set to defaults.

Note that this can also simply be unset, and in that case the game defaults will apply, and the user will be able to change them, whereas if you set these up, the player will somewhat force to used the map settings.

See teams.xml reference.

#### 3.1.16 Resampling

This is a very important point. Liquid War almost *always* resamples maps, unless you ask it not to do it. This is not recommended, it is believed in the general case, letting the internal algorithm make its own decisions is better than trying to figure out oneself “which is the best resolution”.

The reason is, the right resolution (we’re talking here of the logical resolution, how many fighters wide is the battlefield) often depends on the speed and general ressources the of the computer the program is running on. The map designer does not have this information. The program does. It runs a bench at startup. So this way it can choose, at runtime, the resolution which fits best.

The recommended way of doing things is not to try to be too picky about `rules.xml` parameters related to speed and also let the default map size limits in `hints.xml` to their defaults. Do not use them unless debugging stuff. Then the program will resample the map so that the player can play on it at a reasonnable speed. If map is too big, and it’s often the case, then it will downsize it until there are sufficiently few fighters so that the CPU can handle the job. This, of course, is not rocket science. The bench calculation is a somewhat brute-force approach of doing things. Formally, we would have to run the map for good to figure out what is the right speed. Still, this bench gives good approximations.

Previous versions of the game relied heavily on ’fighter-scale’ to resample maps, but this is not the case anymore. The ’fighter-scale’ is now a minor parameter which is used to upsize maps if they are too small. In 99.9% of the cases, the map is first upsized by ’fighter-scale’ for this parameter is by default set low (1.0) then downsized by ’bench-value’ for real-life personnal computers can’t handle 1600x1200 maps in real-time. Not yet.

There are a bazillion options to control map size, including ’min-map-surface’. They are here because it’s important that, ultimately, people can do whatever they want with the game. But for map design, this is another story. Don’t use them. Rely on ’bench-value’ and just care about game speed. This is achieved by changing the “speed” parameter.

#### 3.1.17 Music

It is possible to store your own custom music file within the map directory. You can call it whatever you want (you can keep its original name, which is something music authors usually appreciate, even if there’s no strong “attribution” clause on the license, it can be considered fair use not to fiddle to much with the name) you just have to place it in the same directory than the other files like `map.png` or `texture.jpeg`.

The following formats are known to work with the default SDL_mixer based `mod_ogg` backend:

- `ogg` (Ogg Vorbis files)
- `wav`
- `midi` (extensions `.mid` and `.midi` should both work)
- `mod`, `s3m` and `xm` files, AKA “modules”.

To be more precise, here’s how things work:

- step 1: the game tries to find the file `music-file` (parameter taken from `style.xml` or defined/overriden by player) in the current map directory; step 2: if not found, it will try every path in `music-path` to find this file. This includes the “system” music directory with musics that ship with the game, but also the `./music` subfolder in the user directory; step 3: if still not found, it will try to play a random file, relying on `music-filter` to ignore some files.

#### 3.1.18 Experience (“exp”)

In `rules.xml` you can set a special parameter which is `exp` and allows you to tell “a player can’t load this map if he doesn’t have at least `N` at his/her `exp` rating”. Gaining `exp` (stands for “experience”) isn’t hard, you just need to win a level with `exp=N` to gain `exp=N+1`.

By default, the player’s `exp` is 0 and levels default to 1, so this means only levels with `exp` set explicitely to 0 in `rules.xml` might be used. Then player wins that level and is given access to all maps by default, unless these are explicitely set with `exp` greater than 1.

In solo game, when a player wins a level, he’s automatically redirected to the map which is in the same directory and has exactly the `exp` he just gain. For instance, if you win a map with `exp=5` then you’re chained to the first map (in alphabetical order) which has `exp=6`. By setting up the `exp` parameter the right way, with a map for each `exp` level one can transform a simple map directory in a scenario that player will automatically follow.

Last, but not least, the game, at startup, only allows you to play red, green, blue and yellow. Other colors are unlocked as you progress among levels. Same things with weapons, there are “liberated” continuously through the game.

This mechanics allows the following behavior:

- when game is launched first, only a small subset of maps are accessible
- after you win one map (sort of quite easy) you gain access to the next level, plus many of the maps of the `extra` package.
- after each map you win, you’re redirected to the next map, and regularly, you gain access to new colors/weapons

As a final word, yes, it’s possible to cheat, fool the exp system, but it’s believed this is moot and lame.

Next: Translating, Up: Hacker's guide [Contents][Index]