re: the bark firing sites and the Probability roll
36 of the 64 event names are executable strings, so the string-xref join names the eight sites that raise them; all eight share one entry, sub_8220FA98. Probability is a per-cent roll -- the scaling constant at 0x820856F8 is exactly 100.0. sub_82210670 suppresses an already-queued (speaker, rule) pair, treats a message as eligible only if its bit is clear in the runtime mask at +36, and picks uniformly, then hands Pattern/Priority/EffectiveTime to sub_822109B0. Measured negative: the pick path never reads +20, +24 or +32. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
@@ -4245,3 +4245,56 @@ spending a query on it. The remaining handle is the map's consumer reached via
|
||||
❔ **Still open:** the firing policy proper (who rolls `Probability`, compares
|
||||
`Priority`, ticks `Interval`, what `IntervalFluctuation` randomises); which of
|
||||
the 49 speakers are wingmen.
|
||||
|
||||
---
|
||||
|
||||
## ✅ 2026-08-27 — who fires a bark, and the first half of the firing policy
|
||||
|
||||
Continues the chatter thread; reached through the **call graph**, after the
|
||||
offset-intersection handle was refuted last iteration.
|
||||
|
||||
**Docs checked:** `preset-message-rules.md` (mine), `squadron-orders.md` — it
|
||||
owns `sub_82320B48` as the selector for the twelve-string `0x820AEEB0` enum and
|
||||
warns it is a comms axis. **What it does not say** is that the function is one of
|
||||
**eight bark firing sites sharing a single entry point**, and that it also raises
|
||||
`COUNTER`, `COUNTER_TO_PLAYER` and `FOUND_PLAYER`.
|
||||
|
||||
✅ **36 of the 64 event names are executable strings** (`0x820AEEC8`…`0x820B2160`),
|
||||
so the string-xref join names the firing sites directly: `sub_823800A8` (17
|
||||
events — damage/destruction), `sub_82320B48` (15 — squadron orders + 3),
|
||||
`sub_8237B020` (9 — player state), `sub_823B1438` (ammo), `sub_82381B10`
|
||||
(evasion), and three singles.
|
||||
|
||||
✅ **`sub_8220FA98` is the shared entry** — the only callee common to all eight.
|
||||
Lock around `this+4`; enable byte `[this+8843]`; speaker lookup in the map at
|
||||
`[this+8820]`; index `[this+8816] − 1` into a vector inside that entry (phase is
|
||||
a *reading*, not measured); event-name lookup → the rule object; then the roll.
|
||||
|
||||
✅ **`Probability` is a per-occurrence percentage — now measured, not inferred.**
|
||||
`f0 = rand01 · 100.0` and `f0 > [rule+16]` returns without firing. The constant
|
||||
at `0x820856F8` is exactly **100.0**, read from the image. `sub_8220D970` folds
|
||||
two `rand()` calls into a 16-bit uniform.
|
||||
|
||||
✅ **`sub_82210670` picks the line.** (1) Walks the pending list at
|
||||
`[this+8736]` for a node matching this (speaker, rule) pair and **bails if the
|
||||
same bark is already queued**. (2) Recomputes `MessageCount` from the vector and
|
||||
takes a message as eligible only if its bit is **clear** in `[rule+36]` — the
|
||||
word the loader zeroes — so **`+36` is a runtime exclusion mask** ("already
|
||||
spoken" is the obvious reading; the write site was not found). (3) Uniform pick:
|
||||
`eligible · rand01`, subtract `1.0` (`0x8208583C`) per eligible bit until the
|
||||
counter empties or the accumulator reaches `0.0` (`0x8209FD28`). (4) Reads
|
||||
`[rule+18]` `Pattern`, `[rule+17]` `Priority`, `[rule+28]` `EffectiveTime` and
|
||||
hands them with the chosen message to `sub_822109B0`.
|
||||
|
||||
✅ **Measured negative:** the pick path does **not** read `+20` `Interval`,
|
||||
`+24` `IntervalFluctuation` or `+32` (the disc `Yes` mask). They are consumed
|
||||
after the hand-off. Within the chatter CU (`0x8220C000`…`0x82216000`), `+17` and
|
||||
`+18` are read by exactly **two** functions — the comparator and this one — which
|
||||
is what makes the attribution safe where the binary-wide search was not. **The
|
||||
bounded offset search is sound once the call graph says which functions matter;
|
||||
the unbounded one is what was refuted.**
|
||||
|
||||
❔ **Still open:** everything after `sub_822109B0` — how `Priority` orders the
|
||||
queue, whether `Interval` is a per-event or per-speaker cooldown, what
|
||||
`IntervalFluctuation` randomises, where `+36`'s bits get set, and what reads
|
||||
`+32`. Also still open: which of the 49 speakers are wingmen.
|
||||
|
||||
Reference in New Issue
Block a user