Find where each racer's held powerups are stored (runtime spike) #19
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
mintopia/blur#19
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Find out at runtime on
BLUR_ENGINE=recompwhether we can read which powerups every racer is holding (all slots, in order), for local, AI and remote racers, so the feed can show them to spectators (follow-up ticket). Also decode the channel-9 pickup events that mean "collected" and "used". Research spike: a throwaway hook, memory snapshots and a log; write up the findings; don't change the feed.Spectating is the use case. Showing opponents' held powerups in a live LAN race is accepted.
What we already have
0x535770(this= hub0x111d1e8; argschannel, event_id, a2, payload) insrc/host/hit_hook.cpp. Channel 9 = pickups. Event 4 (hit) and event 14 (shield activation,+0x8racer,+0xc= 7) are decoded (#17). Event 2 = pickup ended, 12 = hit world/projectile.src/host/race_scan.cpp(ADR 0013);race_scan_racer(index)returns the racer address. Powerup enum (0xf6ea80): 0 Nitro, 1 Shock, 2 Shunt, 3 Bolt, 4 Barge, 5 Mine, 6 Repair, 7 Shield.What static analysis found (shipped
Blur.exe, sha256dba0264b...), not checked at run timeEvery channel-9 send through
0x535770:0xba86f0(this= pickup manager0x12223cc; argsa1 != -1, racer index (0x14= none),a3)a3probably the kind. Payload built by0xbabbe0(1, 0, racer, a3, ...)0xbe2310,0xbe9f50,0xbea470,0xbf1f60(per-powerup classes)0xbe3030,0xbe44100xb7cdf0,0xbe4e900xba86f0is called from0xbadcf0(looks local) and0xbaad50(looks like a network message handler, which also calls the net send0xbc06e0), so collection is probably replicated and seen on every LAN instance.0x540(count at+0x298) in the object returned by0x42b600->0x42b6f0. The Lua binding0xb8cfe0writes thePickupSlotssetting (string0xed34f8) to record+0x2d8;0xbaa530uses record+0x308. That is the slot count, not the held pickups.Hud.lua,HUD_Helpers.lua) has no pickup API.Steps
0x535770for channel 9: logevent_idand the first 0x30 payload bytes for events 0, 2, 4, 10, 11, 12, 14, with wall time, and call the original.-1/0xfffor empty, that fills on collect and empties on use. If it isn't on the racer, follow pointers from the racer, the per-player record (+0x2d8..) and the pickup manager0x12223cc.tools/modes/plans,work/ws-capture). Fire with virtual pad A (keyboard fire doesn't work in the driver, #17).Deliverable
A findings comment on this ticket:
race_scan.cppvs events) and a proposed ADR extending 0013/0016.Out of scope
Feed and websocket changes (follow-up ticket), anything Unicorn-only.
Feed contract for the follow-up ticket (agreed for the live-timing example app,
examples/live-timing/):Inside each
standingsentry, names lowercase, same words ashitevents (nitro,shock,shunt,bolt,barge,mine,repair,shield):null= empty slot, in slot orderPickupSlotsis a setting, don't assume 3)Spike findings (recomp, SP career race, 19 AI + local racer; split-screen and LAN NOT run). Full write-up: docs/decisions/0017-held-powerups-from-racer-queue.md (proposed ADR, commit
11595c0). Throwaway hook not committed.Held: racer +0xeac -> array of 0x18-byte entries {kind i32, 0xff, 1, 0, counter, float}; +0xeb4 count (0..3), +0xeb0 capacity; +0xea0 = entry 0 kind, -1 empty (156/156 match). Collect appends at tail; use removes (mostly tail). +0xea4/+0xea8 = currently active powerup. Same for AI and local racer. Remote/LAN untested.
Events (ch 9): event 0 = FIRED (not collected): +8 u8 racer, +0x10 kind, +0x1c serial; ~75% coincide with same kind leaving entry 0, rest are bolt volley repeats. Event 11 shares the serial with event 0. Event 2 = pickup ended. Event 10 = ~300/s per-frame floats, ignore. No channel-9 event on collect; Nitro/Repair use event 4 only.
Availability: SP AI yes, SP local yes; split-screen / LAN local+remote not tested.
Recommend: poll +0xeb4/+0xeac in race_scan.cpp (5 Hz), use events 0/4 for uses; ADR 0017 extends 0013/0016.
Gotcha: work/recomp/m3/gen predated the 0x535770 hook (hook never fired until emit.py re-run).
Update: split-screen and 2-instance LAN now run (ADR 0017 updated, commit
aba9d91).Note: I killed two stale ws_tap.py recorders (ports 9101/9102, started 13:32) while setting up the LAN run.
Completed and merged by Harmonic (task 19).