# `CTransition::calc_num_steps` + the viewer step loop — pseudocode (#181 equilibrium fix) Source: Ghidra decompile (patchmem project, PDB-named) of `calc_num_steps` (`0x0050a0b0`) and `find_transitional_position` (`0x0050bdf0`), read 2026-07-06 after the user's retail axiom ("retail camera is rock steady" pressed into walls) contradicted acdream's measured wall-press wander (~0.5 mm/frame forever, headless pin `Issue181WallPressEquilibriumTests`). The BN pseudo-C of the same functions is x87 mush; Ghidra's is clean. ## `calc_num_steps` — 0x0050a0b0 ``` calc_num_steps(this, out offset, out offsetPerStep, out numSteps): if begin_pos == null: offset = 0; offsetPerStep = 0; numSteps = 1; return offset = get_offset(begin_pos, end_pos) r = local_sphere.radius len = |offset| if object_info.state & 4: # VIEWER (bit 2 of the 0x5c camera flags) if len > F_EPSILON: # 2e-4 offsetPerStep = offset * (r / len) # EXACTLY radius-length steps, start-anchored numSteps = floor(len / r) + 1 # the end lands INSIDE the last step else: offsetPerStep = 0; numSteps = 0 # zero-length path → the no-step success path return # non-viewer: equal slices of ~radius (TRANSITIONAL_PERCENT_OF_RADIUS = 1.0, 0x007c6874) steps = len / (TRANSITIONAL_PERCENT_OF_RADIUS * r) if steps > 1: numSteps = ceil(steps); offsetPerStep = offset / numSteps elif offset == 0: offsetPerStep = 0; numSteps = 0 else: offsetPerStep = offset; numSteps = 1 # short move → one whole step ``` ## The step loop's viewer handling — `find_transitional_position` 0x0050bdf0 ``` for i in 0 .. numSteps-1: # VIEWER LAST-STEP REMAINDER: the final step covers exactly what's left, # so the swept path ends exactly at end_pos (no overshoot): if (state & 4) and i == numSteps-1 and len > F_EPSILON: offsetPerStep = offset * ((len - (numSteps-1)*r) / len) global_offset = adjust_offset(offsetPerStep) # The negligible-offset abort is NON-VIEWER-ONLY — a pressed camera keeps # stepping through sub-epsilon adjusted offsets: if (state & 4) == 0 and |global_offset|² < F_EPSILON²: break ... check_pos += global_offset; transitional_insert(3); validate ... if collision_normal_valid and (state & 8): break # PathClipped first-hit stop ``` ## Why this stabilizes the wall-press equilibrium (#181) acdream's pre-fix stepping for ALL movers was `numSteps = ceil(len/r)` equal slices. The camera's convergence loop (sought = lerp(viewer→desired) → sweep → viewer) perturbs `len` by mm every frame: - equal slices: every step boundary shifts with `len`, and at `len` near an exact multiple of r (the measured press pose: 1.5 m = 5 × 0.3 m) the step COUNT flaps ceil-wise, teleporting the colliding step's window ~5 cm — the clip's committed point jumps mm-scale, and the loop orbits a limit cycle instead of a fixed point (the measured ~0.5 mm/frame wander → the #181 flicker excitation); - retail viewer grid: the first `floor(len/r)` steps are constant radius-length increments anchored at the pivot — invariant under mm target drift — and only the remainder step breathes. The colliding step's window is stable, the clip result is stable, the loop reaches retail's fixed point ("rock steady"). Port sites: `Transition.FindTransitionalPosition` (TransitionTypes.cs) — the subdivision block + the per-step loop (last-step remainder + the abort gate). Non-viewer behavior unchanged (already matches).