diff --git a/docs/re/structures/isl-builtins.md b/docs/re/structures/isl-builtins.md index 915f859..fb4c063 100644 --- a/docs/re/structures/isl-builtins.md +++ b/docs/re/structures/isl-builtins.md @@ -191,7 +191,51 @@ value, and built-in 15 either sets it, restores it, or hands it the constant. The shipped scripts only ever use mode 3: slot 8 is the double tag in **1961/1961** call sites, so the two defaulting modes are never exercised. -#### ❌ The consumer is NOT identified — two filters failed +#### ✅ `+192` is a MIN over the group's members — seeded with `FLT_MAX` + +The spawn routine `sub_8232B538` settles what the field *is*, without needing its +consumer: + +``` +8232B5B0 lfs f0, 25184(r11) ; r11 = 0x820B0000 -> 0x820B6260 = 3.4028235e38 +8232B5B4 stfs f0, 192(r30) ; seed +192 with FLT_MAX + … per member … +8232B674 lfs f13, 164(r3) ; the member's own value +8232B67C lfs f0, 192(r30) +8232B680 fsubs f11, f13, f0 +8232B688 fsel f0, f11, f0, f13 ; f0 = min(f0, f13) +8232B68C stfs f0, 192(r30) + … later … +8232BA10 lfs f0, 192(r30) +8232BA28 stfs f0, 196(r30) ; +196 starts equal to +192 +``` + +The seed being **`FLT_MAX`** is what makes this unambiguous: `+192` is the +**minimum of `[member+164]` across the members**, and `+196` starts there. + +🔑 **So built-in 15's target is a GROUP, not an individual unit** — this file and +my earlier notes both called it a unit. `sub_82348830` hands back a per-member +object and the reduction runs over all of them. + +#### 🟡 That reading survives the turret anomaly + +A minimum over members is exactly how a **formation limit** works: the group can +only go as fast as its slowest ship. On that reading `+192` is the natural cap and +`+196` the effective one, with built-in 15 either lowering it, restoring it +(mode 1), or handing it a global constant (mode 2). + +And a *cap* explains the turrets, where a commanded speed could not. Capping a +static object at 400 is a **no-op** — nothing makes it move — so a designer can +set it uniformly from a unit template without consequence. The asteroid's +invariant `0` is consistent with the same reading. + +❔ I have **not** shown mode 2's constant is `FLT_MAX`. It is +`[r27 + 13912]` where `r27` is loaded from a runtime pointer at `0x8232C718`, not +a static base, so it cannot be resolved from the image alone. If it is `FLT_MAX` +then mode 2 is literally "uncapped" and the three modes are +set / uncap / restore — tidy, and unproven. + +#### ❌ The consumer is still NOT identified — three filters failed Recorded so the next attempt does not repeat them: @@ -204,8 +248,11 @@ Recorded so the next attempt does not repeat them: *definition* object** (vtable `0x820af844`), not the spawned entity built-in 15 writes to. It does not apply here, and it would be an easy wrong turn. -What would settle it is the object's identity: pin the spawned-entity struct -first, then read `+196`'s consumers within it. +The object's identity is now partly pinned — it is a group with a member list, +not a single craft — but the struct is not bounded: the two constructors that +write vtable `0x820AF030` are 28 and 30 instructions and touch neither field, and +the image has **no RTTI at all** (0 of 1150 vtables), so class names are +synthetic. Bounding the group struct is the remaining prerequisite. ### ✅ Four built-ins are TUTORIAL-ONLY — 85 sites, every one in S18–S23