diff --git a/ROADMAP.md b/ROADMAP.md index a2ed7ea4..6e30517c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -13,10 +13,15 @@ for a memory/CPU optimization survey specifically targeting the PSP build 3. Update entity interaction, triggers, chunk management, and other systems that currently assume tile-based positioning so they work with the new 3D positioning/movement code. -4. Investigate and fix poor UI rendering performance. Rendering the - console alone tanks framerate despite the existing mesh - optimizations, so there is likely more headroom to find in the - vertex/text rendering path. +4. Investigate and fix poor UI rendering performance. First pass done + (2026-07-31): slider/tab/frame/textbox now cache their sprite + geometry instead of rebuilding it every frame, and the console's + vertex buffer is fixed-size instead of alloc/free churn (see + `STATUS.md`'s "UI rendering performance" note for detail). Still + open: per-widget material/color changes still force a sprite-batch + flush each time (color is per-material, not per-vertex), so a row of + alternating highlighted widgets still costs one draw call per + widget. 5. Create UI elements for displaying status indicators, e.g. network connection state and save-in-progress. 6. Fully test saving end-to-end on all supported platforms. @@ -62,14 +67,23 @@ fix: `docker/vita/` reference `-DDUSK_TARGET_SYSTEM=vita`, but no `cmake/targets/vita.cmake` exists, so the build is currently broken. Either implement it or remove the dangling scripts/Dockerfile. -4. Add per-PR CI build coverage for at least one non-Linux target (PSP, - Knulli, GameCube, Wii currently only build on tag push, so - regressions there are invisible until a release). -5. Tackle milestone 4 above (poor UI rendering performance) with a - concrete lead: extend `uiconsole.c`'s cached-mesh pattern (rebuild - only on dirty) to the general widget framework - (`uiframe.c`/`uilabel.c`/buttons/menus), which currently rebuilds and - re-uploads geometry via `spriteBatchBuffer`/`meshFlush` every frame. +4. Per-PR CI build coverage for non-Linux targets: first pass added + 2026-07-31 as `run-tests-gamecube-dolphin`/`run-tests-wii-dolphin` + (build the ISO, boot it in Dolphin under Xvfb) and + `run-tests-psp-ppsspp` (build the EBOOT, boot it in PPSSPPHeadless) + in `.github/workflows/test.yml`, plus matching + `scripts/test-*-dolphin.sh`/`scripts/test-psp-ppsspp.sh` (+ `-docker` + variants). Marked `continue-on-error: true` since none of these have + actually been exercised on a real runner yet -- verify they pass + before relying on them, and drop the flag once they do. Knulli still + has no per-PR coverage at all. +5. Milestone 4 above (poor UI rendering performance) has a first pass + in (2026-07-31, see `STATUS.md`) -- remaining concrete lead: sprite + batch flushes are keyed on shader+material (including tint color), + so per-widget color changes (e.g. focus highlight) still force a + flush per widget; moving tint to per-vertex color would let a whole + row of widgets batch into one draw call regardless of highlight + state. 6. Revisit the GameCube/Wii networking static-IP workaround in `networkdolphin.c` -- it's standing in for an unresolved suspected memory-corruption bug in `if_config()`'s DHCP path. diff --git a/STATUS.md b/STATUS.md index 581b14d2..4b43b603 100644 --- a/STATUS.md +++ b/STATUS.md @@ -6,14 +6,14 @@ whenever picking a new roadmap milestone) rather than trusting it blindly. See `ROADMAP.md` for the ordered feature milestones this status feeds into, and `CLAUDE.md` for coding conventions. -Last surveyed: 2026-07-30, at commit `e61914ba`. +Last surveyed: 2026-07-31, at commit `8f8fa8f8`. ## Core engine (`src/dusk/`) | Subsystem | Maturity | Notes | |------------|------------------------------------|-------| | asset | Mature, fully wired | Model loading's "async" path is actually synchronous (`assetmodelloader.h`) -- only real stub found in core. | -| script | Mature for its current scope | Registered modules: `modulePlatform`, `moduleComponent`, `moduleEntity`, `moduleScene` only. No typed per-component JS wrappers (all components go through the generic `Component`). No unit tests. | +| script | Mature for its current scope | Registered modules: `modulePlatform`, `moduleComponent`/`moduleComponentList` (typed Position/Physics/Renderable wrappers), `moduleEntity`, `moduleScene` (with `Scene.set()` module lifecycle), `moduleMesh`, `moduleTime`, `moduleRequire` (CommonJS-style `require()`/`module.exports`). Entry point is `scripts/init.js`, which does `require('./overworldscene.js')` + `Scene.set()`. Has unit tests (`test/script/`). | | entity | Mature | Engine-level prefab lists are empty sentinels; all real prefabs live in `duskrpg`. | | scene | Mature | Same prefab-delegation pattern as entity. No JSON serialize/deserialize (removed by design). | | save | Mature, but undocumented | Slot-based, yyjson + CRC32, platform stream hooks. Not covered in `CLAUDE.md`, no tests. | @@ -21,21 +21,39 @@ Last surveyed: 2026-07-30, at commit `e61914ba`. | physics | Mature, recently churned | Recent revert/re-disable of "old ent code" suggests component wiring around physics isn't fully settled. Well tested. | | animation | Early/mid-stage | Keyframes + easing only, no blend trees or state machines. Terse commit history ("ANIM") suggests still iterating. | | display | Most mature/battle-tested | Backbone of the engine; dominated by platform optimization commits. | -| ui | Actively churning | Widget framework has had features added and ripped out repeatedly (story/battle UI added then removed). Rendering path is the likely root cause of roadmap item 4 (see below). No tests at all. | -| console | Small, finished for its scope | Already has the cached-mesh optimization pattern the rest of `ui/` lacks. | +| ui | Actively churning, perf pass done | Widget framework has had features added and ripped out repeatedly (story/battle UI added then removed). No JS bindings yet (from-scratch surface if that's picked up). Sprite-cache pass landed for slider/tab/frame/textbox (see roadmap item 4 below); still no scripted pointer/hit-testing. Has unit tests for the new caching logic (`test/ui/`), but nothing exercises actual draw calls -- see below. | +| console | Small, finished for its scope | Fixed-size cached mesh (no more alloc/free churn), same pattern the rest of `ui/` now follows. | | event | Clean, small, finished | Pub/sub, rebuilt to replace the old input system. | | game | Intentionally header-only | Real implementation lives in `duskrpg/game/game.c`. | ### UI rendering performance (roadmap item 4) -Confirmed root-cause candidate: `src/dusk/ui/debug/uiconsole.c` caches a -persistent mesh and only rebuilds on dirty/scroll change. The rest of the -widget framework (`uiframe.c`, `uilabel.c`, buttons, menus, settings -screens) still goes through `spriteBatchBuffer`/`spriteBatchFlush` and -re-uploads vertex data via `meshFlush` every frame, with a full flush -forced on every shader/material change. This is almost certainly what -"tanks framerate" on PSP. Fix direction: extend the console's cached-mesh -pattern to the general widget path (rebuild only on dirty, not every -frame). +First pass landed 2026-07-31: `uislider`/`uitab` now cache their non-text +quads (track/fill/markers, tab background) relative to origin and only +rebuild on state change, translating into position at draw time. +`uiframe.c` grew `uiFrameDrawCached()`, which skips rebuilding its 9-slice +sprites when x/y/width/height match the last call; wired into the +confirm dialog, settings panel, and textbox (each owns its own +`uiframecache_t`). `uitextbox` no longer does one `spriteBatchBuffer` call +per visible glyph -- it builds a per-page glyph cache once and slices a +prefix by scroll each frame. `uiconsole` dropped its alloc/free vertex +buffer for a fixed 512-glyph array. `uifps` skips its label rebuild when +the formatted FPS string hasn't changed. + +Still open: every widget still issues its own `spriteBatchBuffer` call +per material/color, so a row of alternating highlighted/plain widgets +still forces a GPU flush per widget (color is applied via material, not +per-vertex) -- that's the next real win if PSP framerate is still an +issue. No scripted pointer/hit-testing exists either; input is still +100% gamepad/keyboard directional-focus (`ui/focus/`). + +Test coverage caveat: `test/ui/` and `test/display/test_spritebatchsprite.c` +cover the new caching *logic* (geometry math, exercised by constructing +widget structs directly) but cannot exercise `uiXxxDraw()`/`uiFrameDraw()` +themselves -- those need `FONT_DEFAULT`/`UI_FRAME`'s GL texture, which +needs a live GL context this test binary doesn't have (confirmed: calling +`fontInitDefault()` in a test asserts in `texturegl.c`). This is true of +the whole rendering layer, not something newly introduced -- there's no +GL-backed test harness anywhere in the repo yet. ## Game layer (`src/duskrpg/`)