Skip to content

v0.2.0

Choose a tag to compare

@sha5b sha5b released this 21 Aug 06:03
· 19 commits to main since this release

sha5b.github.io/Z-Steel-Soldiers — screenshots and the write-up.

The code is now MIT. This project exists for the sport of it, and to see what it takes to translate a 1996 game's logic into Godot, so the reading matters more than the binary. Take the code, port it, reuse it.

Downloads

File Platform
z-remake-0.2.0-1.202608210751.fc44.x86_64.rpm Fedora — installs /usr/bin/z-remake, a desktop entry and the icon tree
z-remake-0.2.0-linux-x86_64 any Linux, one self-contained binary (chmod +x it)
z-remake-0.2.0-windows-x86_64.exe Windows, self-contained
z-remake-0.2.0-macos-universal.zip macOS, universal (x86_64 + arm64), unsigned

SHA256SUMS.txt covers all four.

The macOS app is not signed or notarized, because that needs a Mac and these are cross-built from Linux. First launch needs right-click → Open, or:

xattr -dr com.apple.quarantine "Z Remake (1996).app"

These binaries embed the original game's graphics and sound, which are © The Bitmap Brothers and are not covered by the MIT license. They are here for people who already own the game. The assets are not in the repository — the converters read from your own copy of the retail release.

Fixed in 0.2.0

An exported build loaded none of its content. The worst bug of the cycle, and it was invisible: all 47 test lanes were green in the editor while a packaged game came up with no building defs, no unit folders, no effect art and no map scenes. Godot packs an imported file as a .import sidecar and renames the real texture under .godot/imported/, and it converts text resources to binary. Every directory scan in the project filtered on the source extension (.tres, .png), so in a build they matched nothing. PackFiles folds the packed names back to the project names.

An exported build could not be tested at all. A release binary refuses a scene override on the command line, and main_scene is the title screen, so every test flag was unreachable once packaged — the suite only ever ran the editor's copy. The title screen now hands over to the match scene when it sees a test flag. That is what found the bug above. An editor-only green run proves nothing about a build.

Order paths drew only their last few pixels. Path smoothing collapses an open-ground route to its corners, so a move order comes back as two points, and the walker then drops the first one because it is the cell it already stands on. The path indicator was left with a single point, built no segments, and drew nothing but the destination marker. It now builds its first segment from the unit itself, which is what the original does. --orders-test asserts the path exists, starts at the unit, and spans the move.

Buildings never showed damage. A fort one shot from collapse looked untouched, and the ruin it left sat clean for the rest of the match.

A rebuilt RPM would not replace an installed one. Same name-version-release, different contents, so dnf had no reason to act and you could not tell two builds apart. Release now carries a build stamp.

Ported from the Zod Engine source, not guessed

The 1996 Bitmap Brothers code was never released. The Zod Engine is the open reimplementation this project's asset pack comes from, so it is the reference of record, and each behaviour cites its function in docs/RESEARCH.md.

  • Buildings burn (ZBuilding::ProcessBuildingsEffects). A damaged structure holds a population of effects — max_effects * (1 - hp/max_hp), topped up when short, each placed inside a per-type effects_box — mixed on one rand()%100 roll: 10% big smoke, 10% small fire smoke, 30% fire, 50% little fire. The loop has no destroyed check in the original either, which is exactly why a Z ruin keeps burning. Boxes and caps are verbatim from bfort / brobot / bvehicle / brepair / bradar.
  • Every explosive radius verified against zsettings.cpp SetDefaults: tough 40, light 40, medium 45, heavy 50, missile launcher 80, gun 40, howitzer 40, missile cannon 50, grenade 30, and all the zeros. The splash model matches ZServer::ProcessMissileDamage too — one roll per object, linear falloff, friendly fire off, a circle and not a box.
  • The CPU commits adaptively (ZBot::GoAllOut_3). It compares its share of the map's zones against a fair share and reads two numbers off it: what fraction of the idle army to re-task, and how long until the next cycle. Holding a fair share means a small slice on a slow cadence with a wider target list. Falling behind means a third of the army every few seconds. Targets are collected in the original's priority order and matched by mutual nearest (MatchTargets_3 / GiveOutOrders_3), so the army spreads over objectives instead of swarming one point.

Two items in docs/BUGS.md said "cannot be derived from the art alone". Both only needed somebody to open the file.

Tests

47 headless lanes, green in the editor and green inside the exported binary.

build/linux/z-remake.x86_64 --headless --art-test --quit-after 6000

A lane passes with zero SCRIPT ERROR lines and zero CHECK FAILED lines.