Skip to content

perf: cut per-frame allocations and redundant work on hot paths#79

Merged
blugart-dev merged 2 commits into
mainfrom
perf/per-frame-hotspots
Jun 19, 2026
Merged

perf: cut per-frame allocations and redundant work on hot paths#79
blugart-dev merged 2 commits into
mainfrom
perf/per-frame-hotspots

Conversation

@blugart-dev

Copy link
Copy Markdown
Owner

Summary

Three behavior-preserving hot-path cleanups for the 0.3.x finalization gate. No feel changes — these only remove redundant per-frame work.

1. SpringResolver.get_all_bone_names() — cache the rig-name list

The getter rebuilt a PackedStringArray from _bones.keys() on every call, and it's read every physics frame across ~12 call sites (controller stagger/recovery/ragdoll loops, foot-IK, HUD). The bone key set is fixed once _init_bones() runs, so it's now cached there and the getter returns the cached array (callers already only iterate it read-only).

2. ActiveRagdollController — compute balance once per stagger frame

_compute_balance_state() sums center-of-mass over every rig body. During stagger it was computed twice per frame — once inside _apply_active_resistance() and once in _update_stagger(). Bodies don't move between those two reads (only spring strengths change), so the result is identical; it's now computed once and passed in.

3. StrengthDebugHUD — disable _process while off

The overlay starts off and is toggled with F3, but _process ran every frame regardless. It now set_process(false) at _ready() and toggles processing with the detail level, so there's zero per-frame cost until shown.

Validation

  • Headless import: clean (exit 0, no errors)
  • GUT suite: 112/112, 3× stable
  • Scene-smoke (--quit-after 150): clean on euphoria_showcase (exercises the active-resistance/stagger path) and demo

Visual sign-off

Per the gate process, this wants a quick in-editor spot-check (stagger feel unchanged, F3 HUD still toggles correctly) before merge — though the changes are allocation/scheduling only and shouldn't alter feel.

🤖 Generated with Claude Code

Three hot-path cleanups, all behavior-preserving:

- SpringResolver.get_all_bone_names() now returns a PackedStringArray cached
  at _init_bones() instead of rebuilding it from _bones.keys() on every call.
  The key set is fixed once the rig is built, and the getter is read every
  physics frame across ~12 call sites (controller, HUD, foot-IK).

- ActiveRagdollController computes _compute_balance_state() once per stagger
  frame and passes it into _apply_active_resistance(), instead of each
  computing its own. It sums center-of-mass over every body; bodies don't
  move between the two reads (only spring strengths change), so the shared
  value is identical — was being computed twice per stagger frame.

- StrengthDebugHUD calls set_process(false) while the overlay is off (it
  starts off) and re-enables it on F3 toggle, so it does no per-frame
  queue_redraw work until actually shown.

Validated: headless import clean; GUT 112/112 (3x stable); scene-smoke clean
on euphoria_showcase + demo.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@blugart-dev blugart-dev merged commit 13c6984 into main Jun 19, 2026
1 check passed
@blugart-dev blugart-dev deleted the perf/per-frame-hotspots branch June 19, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant