Under the hood

The simulation

The game rules run in a crate of their own, apart from the rendering. The simulation takes a fixed 30 steps a second and is deterministic: the same map and the same commands always give the same result. It handles:

  • movement, with paths over eight neighbours where cliffs and buildings block,
  • fights, with melee reach and a wind-up before the blow lands,
  • the playable area,
  • fog of war for each player,
  • teams: allies never fight each other,
  • training and building, and the gold they cost.

The interface only sends commands and reads state. That is what makes the same game playable over a network later. See the simulation and multiplayer.

How a unit looks does not touch the rules. A unit turns to face its target in about a fifth of a second for a half turn, but orders and blows never wait for it.

Models and effects

Warcraft III models (.mdx and .mdl) are animated on the GPU. The engine blends between animations, uses a lower level of detail for far units, and draws copies of a model in one instanced call, so thousands of units can be on screen. Particle emitters and ribbons run on the nearest 120 units within a set distance of the camera. On Low quality, half the particles are drawn and no ribbons. A unit stays drawn until it is fully off the screen.

Supported: every chunk of MDX version 800, animation with rotation blending, geoset and texture animation, team colour, particle emitters and ribbons, BLP textures with all mip levels, and text .mdl.

Not drawn yet: model particles of the newer kind, event objects that spawn effects or sounds, attachments as points, lights and cameras inside models, some blending filters and environment maps. Reforged (version 1000) models are not supported.

Hit sounds are made in code, one per definition, and follow the effects volume.

Shaders

The default Warcraft III look for units and terrain is a set of WESL shaders. A map's own shaders/*.wesl files apply when its game starts, and the defaults come back after. If a shader fails, the engine falls back to the default and writes the error to the log. See Shaders and your own look with shaders.

Debug overlay

A small text at the top of the window. It starts on, and F3 or /fps goes through three modes:

Mode Shows
Compact The frames a second, and the ping to the server when there is one. In a game it sits in the top bar.
Detailed Also the milliseconds a frame, the window size in pixels, the units alive and total, and the milliseconds the simulation took. In a game it sits at the left under the top bar.
Off Nothing.

The numbers refresh twice a second. The Debug overlay setting and AQUA4_DEBUG_OVERLAY=0 decide the mode the engine starts in.

Command line

Command Does
w4-engine Opens the start screen. w4-engine --menu does the same.
w4-engine <map> Plays a map: a folder with a map.toml, or a .a4m file.
w4-engine --info <map> Prints the map's name, the W4 version and map format that saved it, any migration, the size, the sun, the number of definitions and placed objects, and the package format. Opens no window.
w4-engine --quit-after <seconds> <map> Plays the map and closes the window after that many seconds. The loading screen does not wait for a click. It is for tests.

A package is read straight from the .a4m file into memory. The engine does not write the map's files to disk, so playing a map leaves no folder of its files behind.

Environment variables

You can set these before you start the engine. They win over engine.toml for that run. They are meant for measuring, so you can time one build with different settings.

Variable Does
AQUA4_QUALITY low, medium or high: the Detail setting (how soon distant units use coarser models).
AQUA4_MSAA Edge smoothing samples: 1 (off), 2, 4 or 8.
AQUA4_FXAA, AQUA4_SMAA Any value turns that smoothing pass on.
AQUA4_ANISO Texture sharpness samples: 1, 2, 4, 8 or 16.
AQUA4_UI_WIDTH stretch, centred or safe: the UI width setting (how much of a wide window the interface uses).
AQUA4_SHADOWS The sun's shadow map in pixels a side: 0 is off, 2048 Low, 4096 High.
AQUA4_RENDER_SCALE The share of the window the scene is drawn at, for example 0.75 or 1.5.
AQUA4_MAX_FPS The frame limit. 0 is none.
AQUA4_FULLSCREEN 1 for full screen, 0 for a window.
AQUA4_DEBUG_OVERLAY 0 or off starts with the frame counter off, 1 or on with it on.
AQUA4_HEALTH_BARS always, hurt or never.
AQUA4_UI_SCALE The interface scale, 0.5 to 1.5.
AQUA4_RETRO Any value turns Old PC mode on.
AQUA4_BACKEND vulkan, dx12 or anything else for automatic.
AQUA4_PRESENT mailbox, immediate or fifo: how finished frames reach the screen.
AQUA4_NO_AUDIO Any value: no sound device is opened.
AQUA4_NO_WAIT Any value: the loading screen does not wait for a click.
AQUA4_STATS Any value: prints frame timing and memory lines once a second.

The old Bevy engine's AQUA4_CASCADES, AQUA4_SHADOW_SIZE, AQUA4_STATIC_SHADOWS and AQUA4_INDIRECT have no meaning in the Omicron renderer (one shadow map, culling on the graphics card with AQUA4_GPU_CULL=1) and are gone.

Every setting is in the command palettes

Press Ctrl+K on the start screen or in a game and type a setting's name: every check box and every choice of the settings pages has a line in the category Settings ("Shadows: High", "Full screen: toggle", "Frame limit: 60"). Choosing it saves the setting at once and, in a game, applies it at once; on the start screen it is kept for the next game. A choice that is already set is greyed out ("already set"); a check box shows whether it is on.

Where the engine keeps its files

File What Where
engine.toml Your settings and hotkeys. Written the first time the engine runs. %APPDATA%\W4 on Windows, ~/Library/Application Support/W4 on macOS, ~/.config/w4 (or XDG_CONFIG_HOME) elsewhere
menu.toml The last map you played, and the players you chose for each map. The same folder

engine.toml is plain text, so you can copy it to another computer. It also has a quality key (low, medium or high) that the settings screen does not show. A damaged engine.toml is ignored and the defaults are used.