feat(reverse): isolate original physics substeps
Expose the original detail-derived integration count, active-ball count, gravity, maximum speed, and movement flags in live traces. Allow probes to force one physics substep so a single collision response can be observed without the default three-step timer batch obscuring intermediate state. Record the dynamically verified type-2 rail response: resolve velocity in the registered line's normal/tangent basis, apply the two original Real48 coefficients, then advance from the previous position using that response. Test Plan: - `ruff check original/tools/trace_original_state.py original/tools/inject_original_state.py` -- passed - one-substep probes against both vertical shooter walls -- passed - ordinary rail responses matched 0.6 normal rebound and 0.1 tangent coupling - `git diff --cached --check` -- passed
This commit is contained in:
@@ -31,8 +31,12 @@ CLAW_FRAME = 0x086D
|
||||
CLAW_TARGET_FRAME = 0x086F
|
||||
CLAW_SPRITE_BANK = 0x0873
|
||||
CLAW_ANIMATION_BLOCKED = 0x0874
|
||||
PHYSICS_SUBSTEPS = 0x0871
|
||||
|
||||
# Recovered offsets in the live game-window object.
|
||||
MAXIMUM_SPEED = 0x0056
|
||||
GRAVITY_PER_SUBSTEP = 0x005A
|
||||
ACTIVE_BALL_COUNT = 0x0061
|
||||
VELOCITY_X = 0x0BAA
|
||||
VELOCITY_Y = 0x0BAE
|
||||
PREVIOUS_BALL_X = 0x0BBA
|
||||
@@ -44,6 +48,8 @@ RIGHT_FLIPPER_POSITION = 0x0BD6
|
||||
LEFT_FLIPPER_DOWN = 0x0BDA
|
||||
RIGHT_FLIPPER_DOWN = 0x0BDB
|
||||
BALL_SUSPENDED = 0x0BDF
|
||||
BALL_ACTIVE = 0x0BDD
|
||||
COLLISION_DISABLED = 0x0BD8
|
||||
OBJECT_READ_SIZE = 0x0BE0
|
||||
|
||||
|
||||
@@ -208,6 +214,10 @@ CSV_FIELDS = [
|
||||
"elapsed_us",
|
||||
"player_count",
|
||||
"current_player",
|
||||
"physics_substeps",
|
||||
"active_ball_count",
|
||||
"maximum_speed_milli_per_tick",
|
||||
"gravity_milli_per_substep",
|
||||
"ball_x_milli",
|
||||
"ball_y_milli",
|
||||
"next_ball_x_milli",
|
||||
@@ -222,6 +232,8 @@ CSV_FIELDS = [
|
||||
"right_flipper_position",
|
||||
"left_flipper_down",
|
||||
"right_flipper_down",
|
||||
"ball_active",
|
||||
"collision_disabled",
|
||||
"ball_suspended",
|
||||
"claw_active",
|
||||
"claw_frame",
|
||||
@@ -235,6 +247,10 @@ def sample_state(data: bytes, obj: bytes) -> tuple[int, ...]:
|
||||
return (
|
||||
data[PLAYER_COUNT],
|
||||
data[CURRENT_PLAYER],
|
||||
unpack_u16(data, PHYSICS_SUBSTEPS),
|
||||
obj[ACTIVE_BALL_COUNT],
|
||||
unpack_i32(obj, MAXIMUM_SPEED),
|
||||
unpack_i32(obj, GRAVITY_PER_SUBSTEP),
|
||||
unpack_i32(data, BALL_X),
|
||||
unpack_i32(data, BALL_Y),
|
||||
unpack_i32(data, NEXT_BALL_X),
|
||||
@@ -249,6 +265,8 @@ def sample_state(data: bytes, obj: bytes) -> tuple[int, ...]:
|
||||
unpack_u16(obj, RIGHT_FLIPPER_POSITION),
|
||||
obj[LEFT_FLIPPER_DOWN],
|
||||
obj[RIGHT_FLIPPER_DOWN],
|
||||
obj[BALL_ACTIVE],
|
||||
obj[COLLISION_DISABLED],
|
||||
obj[BALL_SUSPENDED],
|
||||
data[CLAW_ACTIVE],
|
||||
unpack_u16(data, CLAW_FRAME),
|
||||
|
||||
Reference in New Issue
Block a user