re: refute the projectile hypothesis; the count inflation is 2x duplication + arrivals
Three checks kill "the fast turrets are shots": - persistence: 42/42 survived 15s, including 22/22 of the FAST (>300/s) ones; - hull at the documented pos+0x154 is a clean per-type constant -- 1000.0 for DeltaSaber_T, 100.0 for e007_Turret, with one turret at 79.0 (damaged); - the speed was never suspicious: isl-builtins.md already records e007's MaximumVelocity 500 / CruisingVelocity 280 and notes the data models turrets as mobile. My premise "a turret is a fixed emplacement" was an inference from the NAME that the corpus had already contradicted from the DATA. The inflated count is two measured effects, neither mis-typing: exact 2x duplication (64 raw -> 32 deduped, every per-name count halving, commonest offset gap 0x1000 = one page), and a growing population (42 -> 60 raw in 15s, matching the documented wave arrivals). So "101 vs 42" compared different mission times with at least one count un-deduplicated. Left open: whether the earlier 101 was raw or deduped (it is odd, so not a pure 2x artifact); whether the 0x1000 spacing is a real second copy or page aliasing; and which of the two enumerations is the entity list, since they describe different sets.
This commit is contained in:
82
docs/re/entity-count-discrepancy-resolved.md
Normal file
82
docs/re/entity-count-discrepancy-resolved.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# ❌ The "82 turrets are projectiles" hypothesis is refuted — the count inflation is page duplication plus wave arrivals
|
||||||
|
|
||||||
|
Measured 2026-08-26, fresh boot, save slot 01, Stage 01, live flight HUD,
|
||||||
|
movers precondition checked first (**23 798** in the entity window).
|
||||||
|
|
||||||
|
## ❌ Refuted: they are not projectiles
|
||||||
|
|
||||||
|
[The previous note](entity-readout-working.md) flagged 82 objects typed
|
||||||
|
`UN_e007_ADAN_Turret` moving at ~375/s and suggested they were shots carrying
|
||||||
|
their shooter's definition pointer. Three independent checks all say no.
|
||||||
|
|
||||||
|
**1. They persist.** Enumerated, waited 15 s, re-enumerated:
|
||||||
|
|
||||||
|
```
|
||||||
|
survivors: 42/42
|
||||||
|
of the FAST (>300/s): 22/22 survived
|
||||||
|
of the SLOW (<=300/s): 20/20 survived
|
||||||
|
```
|
||||||
|
|
||||||
|
Every fast object was still there 15 seconds later. A shell fired at a target
|
||||||
|
2–5 km away does not live 15 s.
|
||||||
|
|
||||||
|
**2. They carry a per-type hull at `pos+0x154`,** the documented anchor:
|
||||||
|
|
||||||
|
| entity | speed | hull `+0x154` |
|
||||||
|
|---|---|---|
|
||||||
|
| `UN_f001_TCAF_DeltaSaber_T` | 850.0 | **1000.0** |
|
||||||
|
| `UN_e007_ADAN_Turret` | 354.2 | **100.0** |
|
||||||
|
| `UN_e007_ADAN_Turret` | 354.2 | **79.0** |
|
||||||
|
|
||||||
|
Clean round numbers, constant within a type and different between types — and one
|
||||||
|
turret reading **79.0** against its siblings' 100.0, i.e. a unit that has taken
|
||||||
|
damage. A projectile does not carry a damageable per-type hull.
|
||||||
|
|
||||||
|
**3. The speed was never suspicious in the first place.**
|
||||||
|
[`structures/isl-builtins.md`](structures/isl-builtins.md) already records that
|
||||||
|
`UN_e007_ADAN_Turret`'s definition carries `MaximumVelocity` **500** and
|
||||||
|
`CruisingVelocity` **280** — "the data models turrets as if mobile". 354–375/s
|
||||||
|
sits inside that envelope. My hypothesis rested on "a turret is a fixed
|
||||||
|
emplacement", which is an inference from the *name* that the corpus had already
|
||||||
|
contradicted from the *data*. Fifth time this session that grepping first would
|
||||||
|
have been cheaper than measuring.
|
||||||
|
|
||||||
|
## ✅ What the inflated count actually is
|
||||||
|
|
||||||
|
**Two effects, both measured, neither of them mis-typing.**
|
||||||
|
|
||||||
|
**(a) Exactly 2× duplication.** In one enumeration: **64 raw hits → 32 after
|
||||||
|
deduplicating by (name, rounded position)**, and every per-name count halves
|
||||||
|
exactly —
|
||||||
|
|
||||||
|
| name | raw | dedup |
|
||||||
|
|---|---|---|
|
||||||
|
| `UN_e007_ADAN_Turret` | 32 | 16 |
|
||||||
|
| `UN_e010_ADAN_Attacker_S` | 16 | 8 |
|
||||||
|
| `UN_f001_TCAF_DeltaSaber_T` | 14 | 7 |
|
||||||
|
| `UN_f001_TCAF_DeltaSaber_T_Player` | 2 | 1 |
|
||||||
|
|
||||||
|
The commonest gap between consecutive hit offsets is **`0x1000`** (52 of 63) —
|
||||||
|
one page. So each entity is found twice, one page apart. `entities2.py`'s `main()`
|
||||||
|
already dedups by `(name, rounded pos)`; a caller using `typed()` directly does
|
||||||
|
not, and will double-count.
|
||||||
|
|
||||||
|
**(b) The population grows.** The same enumeration 15 s later returned **60**
|
||||||
|
where it had returned 42 — consistent with the wave arrivals in
|
||||||
|
[`mission-wave-arrivals.md`](mission-wave-arrivals.md).
|
||||||
|
|
||||||
|
So comparing "101 from the `+0x130` method" against "42 from the vtable scan" was
|
||||||
|
never a fair comparison: the two numbers came from different mission times, and at
|
||||||
|
least one of them was un-deduplicated.
|
||||||
|
|
||||||
|
## ❔ Not settled
|
||||||
|
|
||||||
|
* Whether the earlier **101** figure was raw or deduplicated — it is odd, so it
|
||||||
|
cannot be a pure 2× artifact, and I did not re-check which of the two numbers
|
||||||
|
the tool prints at that point.
|
||||||
|
* Whether the `0x1000` duplication is a genuine second copy of the object or the
|
||||||
|
same physical page appearing at two file offsets. The exact one-page spacing
|
||||||
|
suggests aliasing, but nothing here distinguishes them.
|
||||||
|
* The two enumerations still describe **different sets** — the vtable scan sees
|
||||||
|
asteroids and the `_Player`, the `+0x130` method mostly sees combatants — so
|
||||||
|
"which is the entity list" remains open even though the count gap is explained.
|
||||||
Reference in New Issue
Block a user