The brief's gate ('Human or Zuul draws nothing, every other species draws')
is incomplete in two places, found by reading FUN_00820af0 before touching a
guest: species 1 (Hiver) short-circuits too, and the ROUTE OWNER's species is
a gate of its own. The species enum is read from the InitTable jump table as
bytes: 0 Human, 1 Hiver, 2 Tarkas, 3 Liir, 4 _NPC, 5 Zuul, 6 Morrigi.
Corpus counted against the predicate (rule 28 practice 5): 0 of 30. 24 saves
hold a Tarka AI - a drawing species - but tscr is 253 in every one, so the AI
has no Commerce Raiding and never rolls. The workload has to be built.
Tarkas chosen: the tech data gives it a 100% path to CCC_ComRaid via
CCC_FTLEcon, where Hiver has 0% on both edges.
207 lines
16 KiB
Markdown
207 lines
16 KiB
Markdown
# `z` — the raid interception word, and the species that pays it
|
||
|
||
- **Type:** control-flow (static decode of the gate + live measurement)
|
||
- **Owner / date:** lane AZ · 2026-09-09 · guest **VM141** (`sots-re-win10-b`, 192.168.10.143)
|
||
- **Status:** predictions committed; results to follow
|
||
- **Decides:** the `z` term of lane AR's `k + s + z` tail model
|
||
(`findings/control-flow/raid-target-pick-verdict.md` §4.2) — **never observed through
|
||
`Slot13RngCalleeB` by any lane**, because every raid this campaign has run was Human
|
||
- **Instrument:** lane Z's return-address ledger (`draw_sites`) + lane H's entry probes at
|
||
**`probes=8`**, the byte-neutral set. **Not `probes=11`** (lane H bisected index 8 as not
|
||
byte-neutral, and lane AC's turn totals are not calibration data because of it)
|
||
|
||
---
|
||
|
||
## 1. Predictions, committed before the build (rule 2)
|
||
|
||
*Everything in §1 was written and committed before the shim was built, before the workload was
|
||
played and before any counter was read. It is not edited after the fact — only annotated with
|
||
verdicts below the line.*
|
||
|
||
### 1.0 What the brief said, and the two ways it is incomplete
|
||
|
||
My brief — inherited from lane AR's §4.2 and lane AG's §5.2 — states the gate as:
|
||
|
||
> A **Human or Zuul** raider intercepts and draws nothing. **Every other species draws a word.**
|
||
|
||
That is **wrong in two places**, and both were found by reading `FUN_00820af0` from the
|
||
instruction stream on the host before any guest was touched (rule 18's corollary: static reading
|
||
is for explaining, but here it is also for *not wasting a workload*). The function has **three**
|
||
short-circuits and they are a disjunction; the campaign has only ever named the third.
|
||
|
||
```
|
||
FUN_00820af0(TradeManager* this, Vector3* out, TradeRoute* rt, StarFleet* fleet) ; 0x00820af0
|
||
|
||
ebx = registry_lookup(S+0x84, rt->tro) ; the ROUTE OWNER (ServerPlayer)
|
||
...
|
||
00820bc2 cmp DWORD PTR [ebx+0x5c],0x1 ; ServerPlayer+0x5c is the serialised `Species` tag
|
||
00820bc6 je 0x820bf6 ; SC1 -- route owner is species 1
|
||
00820bcf call 0x81a2d0 ; StarFleet_GetCrewSpeciesForIntercept(fleet)
|
||
00820bd7 cmp eax,0x1
|
||
00820bda je 0x820bf6 ; SC2 -- RAIDER's crew species is 1
|
||
00820bdd call 0x81a2d0 ; again, same value
|
||
00820be3 call 0x545cc0 ; SpeciesDef_Get(k) -> 0x00b10a00 + k*0x184
|
||
00820bed call 0x53baf0 ; SpeciesDef_HasInterceptFlag: [ecx+0x144] != 0
|
||
00820bf4 je 0x820bf8 ; SC3 -- flag clear: fall through to the draw
|
||
00820bf6 mov al,0x1
|
||
00820bf8 fldz ; fstp [ebp+0xc] ; frac = 0.0
|
||
00820bfd test al,al
|
||
00820bff jne 0x820c33 ; short-circuited: NO DRAW
|
||
00820c1b call 0x47d830 ; <<< NextFloat, ONE WORD -- this is `z`
|
||
```
|
||
|
||
**Correction 1 — species 1 short-circuits too, and species 1 is Hiver.** `SC2` is a plain
|
||
`== 1` test on the raider's own crew species and has nothing to do with `SpeciesDef+0x144`.
|
||
It is not mentioned in AR's §4.2 disjunct list as a *species* test at all (AR annotates it
|
||
"raider is Species 0 -- no", which is true of AR's state and hides the rule).
|
||
|
||
**Correction 2 — the route owner's species is a gate too.** `SC1` tests the *route owner*, not
|
||
the raider. A route owned by a species-1 empire is intercepted with **no draw whoever raids it**.
|
||
My brief does not mention this conjunct at all, and it is a way for this lane's run to come out
|
||
zero for a reason that has nothing to do with the raider.
|
||
|
||
### 1.1 The species enum, named from the image
|
||
|
||
`SpeciesDef_InitTable 0x005453a0` selects the `Species/%s/...` data-path prefix through
|
||
`jmp DWORD PTR [eax*4+0x545b60]`. Reading the seven-entry jump table **as bytes** (not by the
|
||
order the case bodies happen to be laid out in, which is a different order and would give the
|
||
wrong answer):
|
||
|
||
| index | jump-table target | string |
|
||
|---|---|---|
|
||
| **0** | `0x005453f2` | **`Human`** |
|
||
| **1** | `0x005453f9` | **`Hiver`** |
|
||
| **2** | `0x00545400` | **`Tarkas`** |
|
||
| **3** | `0x00545407` | **`Liir`** |
|
||
| **4** | `0x0054541c` | **`_NPC`** |
|
||
| **5** | `0x0054540e` | **`Zuul`** |
|
||
| **6** | `0x00545415` | **`Morrigi`** |
|
||
|
||
`SpeciesDef_Get 0x00545cc0` bounds-checks `k <= 6`, so **there are exactly seven**, and
|
||
`0x00b10a00 + k*0x184` is the element. This independently confirms lane AR's "species 5 = Zuul"
|
||
and "species 0 = Human", and it names 1, 2, 3, 4 and 6 for the first time in this campaign.
|
||
|
||
The `+0x144` flag word is written only at `0x0054562f` (`or [ebx+0x144],2` when the element's
|
||
index is **5**) and `0x00545638` (`or [ebx+0x144],1` when it is **0**) — AR's read, reproduced.
|
||
|
||
### 1.2 The gate as a predicate, and the corpus counted against it (rule 28 practices 1 and 5)
|
||
|
||
> **`0x00820c1b` draws one word through `Slot13RngCalleeB` iff**
|
||
> **(a)** the route's owner is **not species 1 (Hiver)**, **and**
|
||
> **(b)** the raider fleet's crew species is **not 1 (Hiver)**, **and**
|
||
> **(c)** the raider fleet's crew species is **not 0 (Human) and not 5 (Zuul)**.
|
||
>
|
||
> Equivalently: the raider's crew species is one of **2 Tarkas, 3 Liir, 4 _NPC, 6 Morrigi**,
|
||
> and the route owner is not Hiver.
|
||
|
||
`StarFleet_GetCrewSpeciesForIntercept 0x0081a2d0` returns the fleet **owner's** `Species`
|
||
(`FUN_0071e280(fleet)->+0x5c`) on every path except one: when that species is **4 (`_NPC`)** it
|
||
scans the fleet's ships for a `design->+0x14->+0xac..+0xb4` record and returns that record's
|
||
`+0x4`. So for a player-owned fleet, crew species == owner species, full stop.
|
||
|
||
**Corpus count, all 30 saves in `verify/results/saves/`, read with `save_reader.py --json`:**
|
||
|
||
| species present | saves |
|
||
|---|---|
|
||
| 0 Human (player 0) + 2 Tarkas (the AI) + 4 `_NPC` | **24** |
|
||
| 5 Zuul (both players) + 4 `_NPC` | 6 |
|
||
| 1 Hiver, 3 Liir, 6 Morrigi | **0** |
|
||
|
||
**Corpus count against the predicate: 0 of 30.** And the near miss is instructive: **24 saves
|
||
already contain a Tarka empire**, which is a *drawing* species — but it is the **AI**, and
|
||
`tscr` is `253` in every one of them (bit 0 set = player 0 permitted, **bit 1 clear** = the AI has
|
||
no Commerce Raiding). So the AI never rolls, `A` never fires for it, and no amount of patience on
|
||
an existing save reaches `z`. **The "an AI of another species already raids" option my brief asked
|
||
me to consider is dead, and the corpus count is what killed it** — the state has to be built.
|
||
|
||
**And the tech data says which species can even be a raider.** From
|
||
`verify/results/data-catalogs/tech_tree.json` (`MasterTechList.tech`, per-race
|
||
availability percentages as written):
|
||
|
||
| edge | rp | Human | Zuul | Hiver | Tarkas | Liir | Morrigi |
|
||
|---|---|---|---|---|---|---|---|
|
||
| `CCC_FTLBrdB -> CCC_FTLEcon` | 18,000 | 100 | **0** | 100 | 100 | 100 | 100 |
|
||
| `CCC_FTLBrdB -> CCC_ComRaid` | 5,000 | 0 | **100** | 0 | 0 | 0 | 0 |
|
||
| `CCC_FTLEcon -> CCC_ComRaid` | 12,000 | 100 | 0 | **0** | **100** | **100** | **100** |
|
||
|
||
So **Hiver can never research Commerce Raiding at all** (0% on both edges) — which makes `SC2`
|
||
unreachable for a Hiver *player* through `vslot13`, and leaves it as either a defensive test or
|
||
the path for an `_NPC`-owned fleet with a Hiver-crewed design. And the species that can both raid
|
||
and draw are exactly **Tarkas, Liir and Morrigi**.
|
||
|
||
**This lane picks Tarkas (species 2).** Liir is rejected on movement (their early game is a
|
||
sublight crawl, and this workload lives or dies on parking a fleet on a distant node), Morrigi on
|
||
their fleet-size-dependent drive. Tarkas is a plain node-drive empire with a 100% path to
|
||
Commerce Raiding, and it is the species the AI already is in the lineage every other trade lane
|
||
has used, so the route-owner side is a known quantity.
|
||
|
||
### 1.3 The workload
|
||
|
||
A **new single-player game on VM141** with the species pool cut to **Tarkas only** — lane V's
|
||
trick from the Zuul save, which makes *both* players Tarkas and so pins the route owner's species
|
||
to 2 as well, satisfying `SC1` by construction rather than by luck. Create-game parameters as
|
||
close as I can get to lane AC's `MyGamel3trade` (`NSys 28`, `MaxP 2`, `PCol 10`,
|
||
`PSav 9,850,000`, `PTech 15`, `IncM 1.48`, `ResM 1.46`), because that is the setup that put a
|
||
human raider on a trade sector by turn 20 and gave the AI four trade routes by turn 22.
|
||
|
||
Then: research `CCC_FTLBrdB -> CCC_FTLEcon -> CCC_ComRaid` (34,000 RP on this branch), build
|
||
**several separate single-ship long-range fleets**, and park them on a trade sector that **sources
|
||
a route**. Separate fleets, not one fleet — the roll is per fleet (lane AD) at
|
||
`ODDS + 0.01·nShips`, so `m` one-ship fleets roll `m` times and one `m`-ship fleet rolls once.
|
||
|
||
**Cruisers if their range reaches, destroyers if not.** Cruisers roll at
|
||
`(double)0.2f + (double)0.01f = 0.21` per fleet-turn against a destroyer's `0.06` — three and a
|
||
half times the signal per fleet-turn — and a raider is **displaced off the node by its own
|
||
success** (AR §4.3), so each fleet contributes at most one success per parking and the arm
|
||
exhausts itself. That is the structural constraint on this workload and it is why hull choice
|
||
matters more than turn count.
|
||
|
||
**The route set moves between turns and this map is not AD's map.** Lane AR's geometry table is
|
||
for the `MyGamel3trade` lineage only. I will re-read `trdmgr` on the state I actually build and
|
||
pick the target sector from *that* `trfr` set, preferring a sector that sources **one or two**
|
||
routes: `bound = n - 1`, so `n = 1` gives mask 0 and `n = 2` gives mask 1, and in both cases
|
||
`RNG_NextInt` **cannot reject** and `0x0088b613` costs exactly one word. At `n >= 3` the rejection
|
||
loop is live and `s` stops being one word per success.
|
||
|
||
### 1.4 The numbered predictions
|
||
|
||
| # | prediction |
|
||
|---|---|
|
||
| **P0** | The species enum is `0 Human, 1 Hiver, 2 Tarkas, 3 Liir, 4 _NPC, 5 Zuul, 6 Morrigi`, read from the jump table at `0x00545b60` as bytes. Falsifiable live: the save I build will carry `Species 2` on both `ServerPlayer` records and the game will have been created with **Tarkas** selected in the UI |
|
||
| **P1** | `FUN_00820af0` short-circuits on **three** conjuncts, not one. The campaign's published sentence ("Human or Zuul draws nothing, every other species draws") is incomplete: **Hiver raiders draw nothing** (`SC2`), and **a Hiver-owned route is intercepted without a draw whoever raids it** (`SC1`) |
|
||
| **P2** | The short-circuit sets `frac = **0.0**`, **not `1.0`** as both lane AG §5.2 and lane AR §4.2 write it. Traced through the x87 stack at `0x00820bf8`–`0x00820c33`: `fldz; fstp [ebp+0xc]` on the short-circuit arm, and `0.0 + (1.0 - 0.0)*NextFloat()` on the draw arm. The interception point is therefore at the route's **source** end for a Human or Zuul raider, not its destination. Word count unaffected; the published sentence is wrong (rule 28 practice 6 — read the polarity before the count) |
|
||
| **P3** | Corpus count against the predicate is **0 of 30**, and the "an AI of another species already raids" option is **dead**: 24 saves hold a Tarka AI, but `tscr = 253` in every one, so the AI lacks Commerce Raiding and never rolls |
|
||
| **P4** | **`OnAllCombatDone_Tail` costs `k + 2s` words** on this state, where `k` = permitted Tarka raiders parked with `Pos` bit-equal and `s` = successes on a route-sourcing sector. This is `k + s + z` with **`z = s`**, and it is the term no lane has ever observed |
|
||
| **P5** | `draw_sites` shows, on a turn with `s` successes: `NextFloat 0x00820e18` `calls == words == k`; `NextInt 0x0088b613` `calls == words == s`; and **`NextFloat 0x00820c1b` `calls == words == s`**. Bracket residual **0** on every turn |
|
||
| **P6** | **The `0x00820c1b` row is attributable to `B` and not to `CreateRaidEncounter` exactly when `NextInt 0x008939ee` reads `calls = 0` on the same turn.** Proof, and it is proof-carrying rather than a convention: `FUN_00820af0` has **exactly two `E8` callers in the whole image** — `0x0082cf65` and `0x0088b62c` — verified by an image-wide relative-call scan; `0x0082cf65` sits in `FUN_0082ce00`, whose only caller is `0x00892700` inside `FUN_00892640`, which `CreateRaidEncounter` calls at `0x00893a25`; and `0x008939ee` is on the **straight-line path** from the empty-list gate to `0x00893a25` with no branch around it (`0x008939c9 -> 0x008939ee -> 0x00893a25`, decoded). So `0x008939ee` at zero means the other caller never ran. If it is non-zero on a measured turn I will call that turn's attribution ambiguous and use another turn, not argue |
|
||
| **P7** | `B`'s cost on a success is **2** words for a Tarka raider. Lane AG §5.2's "1 (NextInt) + 1 (NextFloat)" is right for a drawing species; lane AR's measured **1** is right for Human and Zuul; AG's committed §3.3 figure of "3 words on a succeeding turn" is right for `k = 1` **and a drawing species**, and was wrong only because the lineage was Human |
|
||
| **P8** | The `hooks=off` control **will agree with itself** (two fresh processes, byte-identical autosaves) — I am predicting lane AR's outcome, not lane AD's, **and I am not confident**. AD's variation was confined to one AI player's decision sub-tree on a state ten turns earlier in a *different* game; a resolver is looking at the discrepancy now and neither outcome is safe to assume. If my control varies I will localise it by sub-tree with `state_checksum.py --tree` and state exactly which leaves my measurement depends on and whether *those* reproduce |
|
||
| **P9** | With `k` one-cruiser fleets at `p = 0.21` per fleet-turn (`(double)0.2f + (double)0.01f`) I expect the first success within the first two or three instrumented turns. Any zero is reported as a **binomial probability**, never as "unremarkable" (rule 20), and an entry probe on `B` separates "did not fire" from "fired and found nothing" |
|
||
| **P10** | **Not settled by this lane, predicted in advance** (rule 15): the freighter doubling of the raid odds; the `design+0x12c > 1` short-circuit; `bestScale` (`0x009f8d48 = 0.33f` when `ship+0x18 & 0x100000`); the rejection loop at `0x0088b613` for a candidate list of three or more; and whether `SC2` is reachable at all for a *player* (the tech data says no) |
|
||
|
||
### 1.5 The falsifier, stated as the sentence I will have to write
|
||
|
||
> **If a Tarka raider parked on a route-sourcing sector succeeds, `Slot13RngCalleeB` is entered,
|
||
> `NextInt 0x0088b613` fires — and there is still no `NextFloat 0x00820c1b` row — then the species
|
||
> flag is not the only thing gating that draw**, and the two conjuncts ahead of it become the live
|
||
> suspects. In that case I will report, per rule 28, exactly which conjunct I satisfied and which I
|
||
> did not: `SC1` is checkable in the save I built (the route owner's `Species`), `SC2` is checkable
|
||
> the same way (the raider's owner's `Species`), and if both check out then `SpeciesDef+0x144` is
|
||
> not what `0x0053baf0` is reading and the static decode is retired.
|
||
|
||
That is a real result and it is the more interesting one, because it would mean two lanes' static
|
||
reads of the same twelve-byte function produced a confident wrong answer.
|
||
|
||
### 1.6 What could go wrong with the *workload*, and what each failure looks like
|
||
|
||
| way it fails | symptom |
|
||
|---|---|
|
||
| the Tarka AI never builds a trade route in the turns I can afford | `trdmgr` holds zero `rt` records; no sector sources a route; `A` fires and `B` returns at `G_B4` with 0 words — the exact zero lanes AC and AD measured, for AC's reason not mine |
|
||
| no Tarka hull reaches a route-sourcing sector | `A` never fires (`G4` fails, `Pos` not bit-equal); probe 5 reads 0 |
|
||
| I cannot get Commerce Raiding in the session | `tscr` stays `252`; `vslot13`'s `G3b` rejects; probe 2 fires and probe 5 reads 0 |
|
||
| the target sector sources three or more routes | `0x0088b613` `words > calls` and `s` stops being one word per success — reported, not hidden |
|
||
| the encounter query eats a scripted End Turn | detected from the `Done` pixel at (233,673) before every End Turn, per AR §10 |
|
||
|
||
---
|
||
|
||
*Results, and the verdicts, follow below. Nothing above this line is edited after the run.*
|