Skip to content

Own backend: units (step 10) - #55

Merged
jeany55 merged 2 commits into
trigscript-4from
units
Oct 23, 2026
Merged

jeany55 merged 2 commits into
trigscript-4from
units

Conversation

@jeany55

@jeany55 jeany55 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Step 10 of the way off eudplib: units on a map of our own. The ledger's step 10 is 99 of 99 (it was 0); no row of
another step moved. Unit events (on.*) stay step 11's rows and underMouse step 12's.

compiler/backend/units.ts is a pass before the heap's, as texts.ts and heap.ts are. The emitter itself only
exports STATEMENT_KINDS; the eudplib build is untouched.

What it does

  • A unit is two numbers: the EPD of its record (0 for none) and its place's uniqueness byte. A kept unit is checked
    before use in one trigger of four conditions (EPD, sprite, order not Die, same uniqueness byte), as the Python side's
    when_alive.
  • Fields are read through the current player, as eudplib reads: one write of the pointer, then the bits read at player
    13, then the pointer given back. A read in place would make each bit's condition a place of the unit. Writes are one
    masked Set Deaths, stopped at the simulator's tops.
  • Verbs (kill, remove, damage, heal, order, locate, give) and select() mirror the Python side: an order through a
    4-pixel box, give as eudplib's cgive, and select()'s command written into the game's queue.
  • A loop or pick walks the table oldest first (place 0, then 1699 down) to the lowest place ever handed out, a
    map-wide cell each walk moves down. The game hands never-used places out last, in order (scm-sim
    docs/specs/unit-lists.md §3), so nothing is counted per place. eudplib's walk counts units against the game's
    in-use count: a trigger and a record read at every place.
  • A turn is: the loop's test, the filter in one trigger (the order asked only of what it lets through), and the step.
    Small bodies are unrolled to two places a turn. nearest pre-tests a box through the current player.

Weighed (probes/own-units.ts, lifted game, Remastered's weights, 193 units; ours / eudplib):

Ours eudplib
every unit counted 0.021 ms 0.040 ms
a player's Marines counted 0.024 ms 0.046 ms
a pick that finds none 0.024 ms 0.044 ms
every Zergling's hit points added 0.089 ms 0.293 ms
the nearest Zergling (115 in one cluster) 0.298 ms 0.333 ms
a pick's fields, locate, a loop 0.085 ms 0.217 ms
writes, damage, heal, compare 0.035 ms 0.075 ms
weakest-unit function + 8 random picks 0.224 ms 0.497 ms
the map (CHK) 2.86 MB 1.82 MB

Not yet good enough, listed in the plan's Open list:

  • A plain walk is about 2× eudplib, not more.
  • nearest is about even with eudplib when the box rejects nothing.
  • The map is bigger: inlined reads, and the loop body written up to three times.
  • give() leaves the game's counts stale (both builds).

Checked

  • tests/emitter.test.ts "a map of our own, units": the payload walked over a unit table laid out as the game's,
    against the simulator. Covers loops with every filter, break and continue (including a continue inside a switch), a
    full table of 1700 units, fields and flags, picks, writes, damage and heal, kill, arrays and kept units.
  • The probe built both ways in the lifted game: every line the same and "ok", including select() and a cutscene
    walk.
  • Full suite: 1298 passed. The only failure was the two select() rows' first lines, since fixed.

To play: Maps/TrigScript/own-step10-units.scx with its answer sheet.

🤖 Generated with Claude Code

https://claude.ai/code/session_01En4SHqafb1QFJ4xgbUkAe5

jeany55 and others added 2 commits October 22, 2026 18:54
Step 10 of the way off eudplib: every unit row of the ledger (99 of 99) is a map of
our own's. A pass of its own (compiler/backend/units.ts) makes each unit two numbers
— the EPD of its record and its place's uniqueness byte, a kept unit checked before
use — reads its fields through the current player, writes them with masked Set
Deaths, and lowers the verbs and select() as the Python side does.

A loop or a pick walks the table oldest first down to the lowest place the game has
ever handed out, a cell for the map that each walk moves down: nothing is counted
on the way. A turn is the loop's test, the filter in one trigger and the step; small
bodies take two places a turn. In the lifted game a walk costs about half of
eudplib's, a sum of hit points a third (probes/own-units.ts, the plan's table).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01En4SHqafb1QFJ4xgbUkAe5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01En4SHqafb1QFJ4xgbUkAe5
@jeany55
jeany55 merged commit 6ab8f11 into trigscript-4 Oct 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant