feat(character): add an animated low-poly police officer - #17
Merged
Conversation
doodlewind
marked this pull request as ready for review
September 8, 2026 17:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the desktop Soldier and static handheld actors with one original Blender patrol-police officer. Idle, Walk, Run, Fire, Reload, Hit and Death share an editable 17-bone rig, skinned GLB and quantized handheld bake. Walk/Run plant the feet using offline IK and follow distance travelled; the full 1.25-second death action owns recoil, collapse and settling. Bots animate actual shots, hits and magazine reloads.
The PSP uses GE vertex morphing, one indexed draw per visible actor and frustum culling. Held poses read one frame through a second index table. The asset has 1,390 triangles, 847 handheld vertices and 504,818 bytes; the shared immutable pose cache is 1,971,816 bytes. Six visible actors measured 58.91 fps and 0.412 ms of actor CPU work over 3,600 physical frames, compared with about 30 fps and 8.24 ms before morphing. The full 1/3/6 animation sweep contains 10,800 frames and deliberately omits gameplay simulation.
Full combat additionally exposed HUD stalls and missed refresh opportunities. All combat text now uses fixed cells, paint changes use the framework's property batch, and damage/feed fades run as native tweens. HUD event subscriptions are cleaned up on unmount. After GPU synchronization the host accepts a new, already-open blanking interval; a display-vcount guard retains at most one tick/swap per refresh.
Physical combat A/B, release de_dust2 at 333/166 MHz with an 18 MiB heap cap:
These measurements include synchronous benchmark I/O. Occasional missed refreshes remain, and the busiest manual viewpoint is not equivalent to the scripted routes. This does not claim locked 60 fps at every camera position/map or a separate PSP-1000 result.
Validation: eight core/character Rust tests; all seven GLB actions in Pocket3D and Blender-to-bake error below two game units; ten PSP emulator character scenarios including the held final Death pose; 60/60 spawn/walk/fire frames matching five updated goldens; PSP/Vita TypeScript/capability checks and Symbian guest compilation. Golden changes are confined to fixed HUD number cells; central gameplay pixels are unchanged. A release build without scripted input or benchmark logging is running on the physical PSP, and the normal eight-map Memory Stick package was rebuilt locally.
Character hardware report · Combat measurements and reproduction. Local raw logs, binary hashes, captures and receipts are under out/hardware-20260907/ and out/combat-20260907/. Cooked maps, device captures and map-bearing packages remain local.
Fresh human acceptance of the busy combat viewpoint and overall character feel remains pending, so this stays Draft. Character work remains separate from merged upstream-update PR #16.