Skip to content

Cut party UI redraws while a party member is in combat - #28

Open
absol89 wants to merge 1 commit into
masterfrom
claude/project-thread-u8o0na
Open

absol89 wants to merge 1 commit into
masterfrom
claude/project-thread-u8o0na

Conversation

@absol89

@absol89 absol89 commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

Requested by Eric · project thread

Addresses tiltedphoques#940 (a periodic stutter while a party member fights, which goes away when the party disbands, the member dies, or the party UI is disabled).

Cause

  • In combat a member's health percentage changes on almost every 500 ms tick, from damage and then regeneration. RunPlayerHealthUpdates sends the raw float, so a setHealth goes out about twice a second.
  • Every setHealth re-emits the group, the party *ngFor (which has no trackBy) rebuilds its elements, and the list flashes even when the value is unchanged.
  • Each overlay repaint is expensive. OverlayRenderHandlerD3D11::OnPaint in TiltedUI copies the whole screen into the texture (it ignores dirty rects) while holding the lock that the game's render thread takes every frame. A higher resolution makes this worse. The same cost would explain why the debug overlay alone, which updates once a second, also stutters.

Changes

  • Client: round the sent health percentage up to a whole number (so 0 still means dead), so it only goes out when the bar visibly changes.
  • UI: round incoming values the same way, ignore updates that don't change a member's health, and only flash the party list on a real change.
  • UI: track party members by id so their elements are reused, and drop the 0.8 s width transition. With elements reused, the transition would repaint the overlay for 0.8 s on every update.

Follow-up (not in this PR)

The repaint cost itself sits in the TiltedUI submodule: copy only the dirty rects, and do the copy outside the lock the game thread waits on. That would make every overlay update cheaper, including chat and the debug view.

Testing

  • ng build passes and Prettier is clean on the changed files.
  • CI builds pass on Windows x64 and Linux amd64/arm64.
  • Not tested in game yet.

🤖 Generated with Claude Code

https://claude.ai/code/session_018fvQxPkaY5xU6UUaRU3L8h

A party member's health percentage changed on nearly every 500 ms tick
during combat (damage, then regeneration), and every update rebuilt the
party list and made the overlay repaint. Each overlay repaint copies the
whole screen into a texture, which shows up as a periodic frametime spike.

- Round the sent health percentage up to a whole number, so it only goes
  out when the bar visibly changes and 0 still means dead.
- Ignore health updates that don't change a member's value, and only
  flash the party list on a real change.
- Track party members by id so their elements are reused, and drop the
  width transition, which would otherwise repaint for 0.8 s per update.

See tiltedphoques#940.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fvQxPkaY5xU6UUaRU3L8h
@absol89 absol89 self-assigned this Nov 4, 2026
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.

2 participants