Confirmed Shot Presentation - Herbertofury/Advent-of-Ascension GitHub Wiki
Confirmed-shot presentation core
Implemented and unit-tested original logic; native integration is still open. This small Java component selects an alternating visual emitter for one trusted weapon/session context. It does not fire a weapon.
Behavior
- A blocked/rejected attempt produces no presentation event and does not advance the sequence.
- Duplicate and late confirmations are ignored. Gaps use the authoritative shot ordinal rather than packet-arrival count.
- Wrong weapon, session or attachment-configuration events are ignored.
- An older snapshot cannot rewind replay history. Unequipping/re-equipping retains the high-water mark.
- Changing emitter count requires a new configuration revision. Snapshot binding never resets the accepted-shot ordinal within a session.
- Projectile-count metadata is preserved. Three visible emitters do not silently change a four-projectile burst into three projectiles or three ammo charges.
The object has constant-sized state and performs no frame polling, file scanning, resource consumption, damage calls or projectile spawning. This is a source-level design property, not a measured game FPS improvement.
Proposed mappings
- Baronator: two emitter slots, upper first then lower.
- Soul Storm: four default slots; five/six-slot attachments get a new resolved configuration revision.
- Discharge: three modeled visual channels can alternate while retaining its original four-projectile burst metadata. This is a proposed presentation mapping, not a change to its original firing class.
Native adapter requirements
- Create the controller from the actual weapon-instance/session lifecycle. Do not accept arbitrary client packets as authoritative merely because a record is called Confirmation.
- Call it on the owning client thread; it is intentionally not a cross-thread synchronization service.
- Feed accepted-shot ordinals and resolved configuration snapshots from the real game path. A new session requires a new controller. Shot ordinals continue across attachment changes within that context.
- Preserve responsive local prediction. This confirmed-event core does not reconcile predicted first-person effects; wiring it in must not introduce a network-round-trip delay or replay an effect already predicted locally.
- Resolve emitter bone handles once on asset load/reload. Verify their count against the resolved build; use a safe original-renderer fallback on mismatches. Do not scan meshes every shot or frame.
- Actual ammo, Spirit, damage, projectile creation, multiplayer authority and save behavior remain with the native game/weapon adapter. This utility must not become a second firing path.
- Exercise blocked shots, rapid input, configuration swaps, reloads, reconnects, prediction correction and multiplayer in the pinned native stack before acceptance.
Test evidence
The same Java 17-targeted class files ran successfully under Java 17 and Java 21. Each run performs 80,031 assertions, including a deterministic cycle sweep over emitter counts 1โ100 and shot ordinals 1โ200, plus replay, snapshot, configuration and integer-boundary cases. This is not 80,031 separate game scenarios.
A development test caught that blindly rebinding a stale snapshot could replay old effects. Binding now preserves its high-water mark and rejects old/mismatched configurations; those cases are regression tests.
Run run_checks.py with --jdk17 pointing to a JDK 17 directory and --java21 to the second Java executable. No Minecraft classes are mocked or invoked: these are tests of the original presentation-state code only. Native animations, sound, particles, prediction and gameplay are untested.
Released AoA event-source audit
In the inspected AoA3.7.1 gun use-tick path, successful virtual fireGun return handling precedes the server-player recoil call. But GunRecoilPacket serializes only a recoil float and firing-time integer. It contains no weapon-instance identity, hand, configuration revision or shot ordinal. The inspected path sends it to the firing player, and its client handler calls ClientOperations.addRecoil.
Do not identify a weapon by recoil amplitude or by whichever item is held when that packet arrives. Rapid swaps, offhand use and observer rendering make that unsafe. A genuinely authoritative identity-bearing native event remains required, without replacing the original firing/resource path. Third-person tracking and responsive prediction need explicit integration tests.
Consume this core rather than duplicating its counter
The Soul Storm R3 presenter takes this core's resolved emitterIndex. Its earlier local arrival counter was rejected after an ordinal-gap test. The existing core passed its unchanged 80,031-assertion suite on Java17/21, and the combined Java-to-Lua mock-context bridge passes 29 assertions on each runtime. This remains isolated logic evidence, not a native packet or renderer test.
Existing original core source ยท R3 combined source/tests
Coverage audit: all 228 first-target firearms
The pinned registry is split into 172 conventional guns/shotguns/snipers/cannons and 56 Spirit blasters. A hash-checked audit of 227 constructor/base classes covered all 228 item registrations. The earlier conventional-only scan was not treated as a complete-arsenal result.
| Released use-tick owner | Registered items | Adapter implication |
|---|---|---|
BaseGun |
172 | Observe its successful virtual fireGun branch without replacing subclass behavior. |
BaseBlaster |
54 | Separate energy/charge path; use its accepted tryFireBlaster result as a candidate event boundary. |
LightSpark |
1 | Overrides use-tick, but still calls inherited tryFireBlaster. |
SoulSpark |
1 | Overrides use-tick, but still calls inherited tryFireBlaster. |
Soul Storm is in the BaseBlaster family. A BaseGun-only hook or recoil-packet listener would not cover its native firing path.
The blaster helper can return success even when fireBlaster returns a null ShotInfo; the optional doFiringEffects callback is skipped in that case. Therefore a firing-effects callback alone is also an incomplete success signal. Keep charge, Spirit consumption, effects, sound and subclass behavior with the original implementation.
This suggests two source-audited event boundaries, rather than separate scans of every weapon every frame. It does not establish a working Mixin or a native compatibility/performance result. Validate actual runtime transformations, hand/instance identity, prediction and observer routing. Do not replace the special LightSpark/SoulSpark use-tick implementations with a generic version.
Per-item class-chain coverage ยท Packet and branch evidence
Reproducible class-audit scripts and source-derived registry inputs. A clean output-directory run reproduced the 228-item result and passed eight source-contract tests.