Roadmap
← POPSLoader docs · view on GitHub ↗
Last updated: 2026-07-27 (rolling dev = v1.1.1-dev; released line 1.1.0)
ROADMAP
This is the forward plan. For current runtime state, the canonical Known-Issues list, the Preservation Contracts, the Behavioral Invariants, and the per-case Hardware Status, see STATE.md — those volatile/shared facts live there and are not re-enumerated here.
Status Snapshot
- Public release is 1.1.0 (tag
1.1.0, 2026-07-21; previously 1.0.1 2026-07-13, 1.0.0 2026-07-10, BETA-12 2026-06-18).rolling-release.ymlpublishes fromdev, stampedv1.1.1-dev(tip moves per push; seegit log). - The 2026-06 (BETA-12-era) deliverables: HDD-resident settings save + in-app HDD
.hide(boot-partition RW take-over viaEnsureBootPartitionWritable), PAL native 640×512 full-screen render + auto-revert display-change confirm, thebdma_mode.txtmarker rename (legacy names still read), the POPSTARTER Memory Card Folder toggle + BDMA⟺folder interlock, the launch-args auto-launch consumer, and the live CI luac syntax gate. See STATE.md > Repo-Verified Runtime State for the detail. - The BETA-13 session added: gated analog-stick→d-pad fold + frame-counted nav auto-repeat + frame-counted description scroll (all hardware-confirmed), the Boot sound On/Off setting (hardware-confirmed), the layered
cover_default.png+cover_missing.pngcover placeholder (replacing the removedMISSING.png, −62 KB ELF), the OPL-style Overscan (CRT inset) render-inset adjuster, the HDD save-after-scan fix + Proposal A scan-slot steering, a 6-finding Codex audit pass, POPSTARTER.ELF / SMB-pack release-zip packaging, and per-device POPSTARTER.ELF resolution (PLDR.ResolveLaunchPopstarterPath; removable order: explicit custom/absolute-profile path → the game's own<device>:/POPS/POPSTARTER.ELF→ launcher cwd →mc0:/mc1:net; APA order: custom →hdd0:__common/POPS/POPSTARTER.ELFvia the same__commonpartition machinery → cwd → net — an explicit custom path now wins and Profiles act as presets, superseding the earlier device-local-first precedence; commits28e40bb/9f2477c/26bb06c, not yet hardware-tested). See STATE.md > Repo-Verified Runtime State. - The 2026-07-09 wave added: Adaptive BDMA (issue #509; per-launch BDMA variant staging with an equipped-check-before-write, launch-cancel on a staging failure, and an adaptive-off restage of the chosen mode), partition-installed POPS games on the HDD (PFS) page (HDDOSD/PSBBN
PP./__.one-partition-per-game installs via the newHDD.ListPartitionsAPA enumerator + anIMAGE0.VCDmount-probe; launch argv0PP.<partition>.ELF), the boot chime re-encode (22.05 kHz mono, −190.9 KB raw, zero code changes), and HDD-page diagnostics for the open non-HDD-boot list failure (real mount rc surfaced, dir-read-fault toast, status re-probe instead of a dead latch). Commits6d6a368..3eff270, adversarially reviewed pre-push (8 confirmed findings, all fixed), none hardware-tested. See STATE.md. - Hardware status, preservation contracts, and known issues are tracked in STATE.md — see STATE.md > Reported Hardware Status, > Preservation Contracts, and > Known Issues. In short: D-10/D-14/D-15, DKWDRV-from-MC, and BOOT.ELF-from-USB (L-07) remain hardware-PASS contracts; U-10 (BOOT.ELF from HDD-booted POPSLoader), DKWDRV-from-custom-HDD-path, and the Class-A HOSDmenu / some-wLE start failures are now RESOLVED (no longer known-broken); the 2026-06 HDD/PAL/BDMA features are implemented / boot on PCSX2 / HDD RW confirmed on hardware (provato) / full flow validating on hardware.
- CAUTION — load-order regression risk. A boot brick (PLDR.HDD methods defined before
PLDR.HDDexisted) made recent HDD-feature rolling builds un-bootable; fixedd4b04be(2026-06-17). Runtime nil-global / type / load-order errors are invisible toluac -pand CI — only the syntax gate is automated. Re-test HDD-feature builds on PCSX2/hardware before trusting a green CI.
Infrastructure landed post-release:
- .github/workflows/rolling-release.yml — automated rolling-release artifact publication on push to dev. PR events still build and run the gates, but the publish step is if: success() && github.event_name == 'push', so a PR can no longer republish the channel (gated since PR #511, 2026-07-16).
- docs/archive/DOCUMENTATION_FOLLOWUP_AUDIT.md — handoff plan for the post-BETA-10-5 doc cleanup work (now completed; see "Documentation cleanup" under Secondary Work).
SMB (v1) network game browsing is implemented (CI + Rolling green; browse + launch hardware-confirmed on a static IP config, DHCP path fixed in bb62f2be but unconfirmed): the SMB carousel page / GSMBNET scene with network settings, an install-toggle SMB module pack, lazy connect-on-entry, share browse, and POPStarter launch via smb:/POPS/SB.<name>.ELF — see Secondary Work §1 for the detail. ILINK remains an intentionally unimplemented menu entry. HDD (exFAT) is also implemented (BDMA Mode ATA, df2eb9d) and is validating on hardware; the launch-args path routes -page=ata/-mode=ata (and ata0/ataN) to it (opt 3, scene GBDMHDD), while -page=hdd/apa/pfs target the classic PFS page (opt 4) — 3d89631.
Immediate Priorities
1) Cut BETA-13 — DONE (shipped as 1.0.0 on 2026-07-10, then 1.0.1 2026-07-13 and 1.1.0 2026-07-21; kept below as history)
- The BETA-13 input/UX/cover work is in and the headline items are hardware-confirmed: up/down + analog-stick nav land on individual items with smooth continuous scroll (oldman63), boot sound saves and survives reboot (oldman63), cover art loads via the Cover/details folder setting (FifthFox, 2026-06-30), and "everything working fantastically" on the latest rolling (Nuno6573). See STATE.md > Reported Hardware Status.
- Remaining BETA-13 eyeballs before the cut (none currently believed broken — all "awaiting a look"): the Overscan (CRT inset) render-inset on a real CRT; the
cover_default.png+cover_missing.pngoverlay registration against the jewel-case window on both NTSC and PAL; the description right-stick scroll feel; and the HDD Proposal A scan-slot steering (deliberate HW test — see #5 below). - Cutting BETA-13 needs the tree-adopting merge to
master(the proven-s ours+read-tree+ verify-empty-diff mechanic;masterdiverges from the dev branch, so a plain merge is wrong). The mechanic is archived atdocs/archive/RELEASE_BETA13.md(with its gate checklist alongside it): preconditions/HW gate, release-prep on the dev branch, then the verified merge + tag + publish sequence. It is written for the BETA-13 cut specifically and names branches that were since renamed, so read it as the pattern rather than as steps to run verbatim — 1.0.0, 1.0.1 and 1.1.0 were all cut this way.
2) µs-as-ms timer-unit sweep — DONE
- Root-cause fact:
Timer.getTime()returns microseconds on PS2 (rawclock()tick;CLOCKS_PER_SEC=1e6 — source-verified). Nav auto-repeat and description scroll were already moved to frame-counting (the canonical Enceladus idiom). - The sweep finished the rest in
9c3f64f+a8e61f3: the PathEditor key-flash + caret blink and the launch-watchdog label are unit-correct (Timer.getTime()/1000); the deadMIN_ACTION_MSaction debounce was removed (edge-triggering is the real gate); and the scene-fade / boot-fade / carousel were frame-paced preserving their current feel.os.clock()was deliberately not introduced (frame-counting is the idiom); it stays unused. Only cosmetic/inert sites (busy-overlay throttle, saving marquee, disabled debug log) intentionally remain.
3) Settings UI redesign (Berion mockup) — RESUMED incrementally
- RESUMED 2026-06-22 (maintainer call), built incrementally on
dev(then still namedBETA-13-PLAY) for tester access (luac/CI green, NOT HW-verified): the OPL-style focused-list now has a focus-following scroll viewport + scrollbar, and collapsible/expandable sections (6d26819— each section header folds; X toggles, Left collapses, Right expands; session-only collapse state, no new persisted key). Backup branchcheckpoint/pre-settings-redesign-2026-06-22. - Banked next steps (do not forget): (a) the icon menu / overlay from the 2nd 2026-06-22 mockup — Settings / Save Changes / Restore Default / Joypad Configuration / Memory Card Manager / About / Exit; (b) a Joypad Configuration screen; (c) optionally default-collapse the heavier sections (Carousel Devices, Game List) so the page opens compact; (d) persist collapse state if users want it (currently session-only). The 2026-06-22 screenshots supersede the missing Berion PNGs for the scroll/submenu work specifically.
- Blocked on Berion's mockup PNGs landing at
C:\Users\natha\Documents\assets\and being committed todocs/mockups/for the full per-screen redesign. Without the visual oracle, the deeper Lua port is hard to start. - The original launch-path hardware blockers (D-10/D-14/D-15/DKWDRV-MC/BOOT.ELF, and now U-10) are settled. However, the 2026-06 HDD-resident settings save, in-app HDD
.hide, and PAL-512 features are still validating on hardware (boot on PCSX2; HDD RW confirmed on hardware by provato; full flows not yet broadly hardware-confirmed). Per the maintainer, don't kick off the redesign until those settle, so the redesign builds on a verified settings/persistence base. See STATE.md > Reported Hardware Status. - Scope: Context menu, Settings (per-category pages superseding the OPL focused-list), Joypad configuration, On-screen keyboard. Boot/splash and game list are out of scope.
- Full implementation prompt and per-screen pixel specs live in
docs/archive/GUI_OVERHAUL_PROMPT.md.
4) Layer C full lazy IRX loading
- Precursor (pre-IRX device classification hint) landed in PR #458.
mmcemandeferral — SHIPPED (PR #471, merged; commitd10ec56). MMCE boots load mmceman eagerly (gate atsrc/main.cpp:503); USB/MC/MX4SIO/HDD boots defer it and lazy-load on demand viaPLDR.EnsureMmceReadyOnce()(bin/POPSLDR/system.lua:1206—System.ensureMmceman+System.reinitPad). MMCE pad-input behavior hardware-confirmed (FifthFox, commit9f2d550). The vendored mmceman blob was later dropped in favor of ps2sdk'smmceman(noiop/embed/mmceman.irxin-tree).ds34btdeferral (Bluetooth pads) — DECLINED (2026-06-22).ds34bthard-importsusbdand there is no clean "BT pad present" boot signal (pads pair after boot), so any defer gate risks dropping BT input for a small gain.usbddeferral — DECLINED (2026-06-22), the high-risk one.ds34usbandds34btboth hard-importusbd, and the boot-device hint classifies the boot medium not pad transport, so deferring strands USB/BT controller input on every non-USB boot — unrecoverable without a reboot. Keepusbd+ds34usb+ds34bteager.- Decision: Layer C is closed at the
mmcemanwin. The projected 30-50% pre-Lua gain indocs/archive/LAUNCH_HYGIENE.mdassumed all three deferrals; withds34bt/usbdoff the table the realistic remaining gain is small and not worth the unrecoverable input-loss risk.
5) Display, HDD, and UX verification
- Overscan (CRT inset) — new OPL-style render-inset shipped but not yet eyeballed on a CRT.
Screen.setOverscan(permille)/getOverscan()(src/luaScreen.cpp) drive agraphics.cpptransform that wraps everygsKit_prim_*draw site inOVX()/OVY()(identity at permille 0, so inert by default; math identical to OPLrmSetOverscan). The live adjuster is Settings → "Overscan (CRT inset)" (bin/POPSLDR/ui.lua:3649, ±5 step, live preview, discard restores). Confirm the inset on a real CRT. - HDD Proposal A — the game scan now steers off the live boot pfs slot (
b159a43; the boot/settings partition lives on the boot slot, "NEVER reuse"), and the boot RW mount is re-validated on the save path so settings save after a scan (8d1e67a). Still wants a deliberate HW test (Nuno) that game partitions still mount/list when forced off the boot slot. See STATE.md and memoryreference-hdd-pfs-slot-model. U-06targets the PAL native 640×512 full-screen render (the menu fills the screen, no letterbox; NTSC is 640×448). On PAL hardware confirm the full-screen fill and the auto-revert display-change confirm prompt (reverts if the new mode isn't confirmed, like OPL). See STATE.md > Reported Hardware Status (U-06row).- Re-run
U-08/U-09on slower/large libraries to judge whether busy overlays communicate activity clearly enough.
6) Coverage and documentation
- Add concrete run logs for: D-13 device switching without runtime locks, S-09 keyboard layout persistence, U-11 boot-device label display.
Resolved Since BETA-10-5 (no longer blocking)
The items previously parked here as "pragmatically accepted / known-broken" are now resolved — see STATE.md > Known Issues (Recently resolved) and > Reported Hardware Status for the canonical record:
- U-10 BOOT.ELF from HDD-booted POPSLoader — RESOLVED via PR #479 (
reboot_iop=0). Investigation archived underdocs/archive/U10_INVESTIGATION.md. - DKWDRV from custom HDD path — RESOLVED via PRs #486/#487 (partition-aware path + live pfs-slot scan).
- Class-A start failures (HOSDmenu / some wLaunchELF builds) — RESOLVED (maintainer-confirmed 2026-06-15).
- HDD read-write — achieved via the
EnsureBootPartitionWritableboot-partition remount take-over (the launcher owns its boot pfs slot and remounts it RW), not the oldps2hdd-osd.irx→ps2hdd.irxIRX-swap probe. provato confirmed the HDD is RW-writable on real hardware; the old swap-probe item is dropped. HDD-resident settings save + in-app HDD.hidenow ship on this path (still validating the full flow on hardware).
Secondary Work
1) Menu paths
SMB (v1)network game browsing — implemented (CI + Rolling green; browse + launch HARDWARE-CONFIRMED by the maintainer, who has been launching SMB games successfully for some time on a static IP configuration). End to end: an SMB carousel page (sceneGSMBNET, main-menuOPT==7) with a network SETTINGS section (server IP, share, user/password, DHCP-or-static IP assignment, port, games path/cwd, link mode — IP addressing only), a BDMA-style "SMB modules" install toggle (copies the 6-IRX in-game SMB streaming pack —poweroff/ps2dev9/ps2ip/ps2smap/smbman/SMSUTILS— intomc:/POPSTARTERand generatesIPCONFIG.DAT+SMBCONFIG.DATfrom the settings; OFF removes only those SMB files), lazy connect (the network stack and share open only on entering the SMB page or on a settings action — never at boot; Path B = OPL's netman recipe, dev9 shared once across HDD + SMB viag_dev9_loaded), share browse listing VCD games like any other device, POPStarter launch via argv0 selectorsmb:/POPS/SB.<name>.ELF, disconnect on leaving the page (also tears down a failed connect so no half-open session lingers), a blank-shareGETSHARELISTpicker (persisted to settings + the in-gameSMBCONFIG.DAT, then reconnects), and.DATbackfill on every settings save when the pack is installed. NetBIOS is not supported (deferred —nbns.irxis OPL-custom, not stock ps2sdk; address type must be IP). Commits onBETA-13-PLAY: settingsee4d454, module toggle121823d, build0cf7f81, connect/browse43033dc, launch68f9ed5, Increment-3 polish154c872,.DATbackfill5d0e302, connect-failure session-leak fixf5ac26c, in-UI share picker1169dbc. Hardware status: the argv0 device prefix (smb:/POPS/SB.<name>.ELF) and the connect handshake are confirmed — the maintainer's static-IP setup has been launching SMB games for some time. Still unconfirmed: the DHCP path and the blank-ShareGETSHARELISTDMA. DHCP was broken from the start and hid behind exactly this static-only confirmation: POPStarter has no DHCP of its own, so it needs a literal address inmc?:/POPSTARTER/IPCONFIG.DAT, andSyncSmbDatdeleted that file whenever IP assignment was DHCP — the shipped default. A default install therefore browsed fine on the loader's own lease and then died at the handoff (issue #560, elvengf). Fixed inbb62f2be, which writes the leased address instead of deleting the file; guarded by harnessT43.ILINK— intentionally not implemented; surface "not supported" if entered.HDD (exFAT)is implemented as amass:backend via BDMA ModeATA(validating on hardware).
2) Art/asset behavior
- Keep current cover behavior stable, and read STATE.md > Cover art plus the EXP71/EXP73 bullets before touching it — the detail is canonical there, not here. In short: the seeker returns exactly ONE candidate (
<device>:/ART/<gamefilename>_COV.png; APA/PFShdd0:__common/POPS/ART/<gamefilename>_COV.png), the selectable folder row was removed in EXP35, and the disc-stripped family name, thePOPS/fallback and the legacy<name>.pngare gone. Ignore below: the cover<name>.png(and its matching<name>.txtdetails sidecar, which rides the same candidate list) is built byBuildCoverCandidates(83e81cf, selectable7f9b5fa). On removable devices the lookup folder is user-selectable (ART_LOCATION/ Settings → Game List → Cover/details folder):POPS/ART(default), the game's ownPOPS/folder beside the.VCD, or a top-level<device>:/ART/; the game's ownPOPS/folder is always also checked as a fallback so older art never stops showing. HDD/PFS is fixed athdd0:__common/POPS/ART/<game>.png(from the__commonpartition). Within each folder the disc-marker-stripped name is tried first (one art/details file serves every disc of a multi-disc game), then the exact per-disc<full-name>.pngfor back-compat.CoverCache:GetOrLoadloads viaGraphics.loadImage/fopenwith noopen()existence pre-probe (ps2sdk routesopenandfopenthrough the same_open, so the probe was redundant, not a cover fix); don't reintroduce it and don't drop the always-appendedPOPS/fallback. - The no-cover / preview-off cover box now draws the layered
cover_default.pngbase (+cover_missing.pngoverlay when a game has no cover);MISSING.pngwas removed and is no longer a fallback anywhere;default.pngstays an optional legacy cover override. The canonical detail (asset layering, the embed-mechanism's 3 coordinated edit sites, the ELF-size delta) lives in STATE.md > Cover art — don't re-enumerate it here.
3) Install/build clarity
- Keep CI package layout and docs synchronized.
ps2dev/ps2devimage is pinned tov2.0.0in.github/workflows/compilation.ymland.github/workflows/rolling-release.yml(post-release pin at commitba8f0d0).- The embedded-Lua syntax gate (
luac5.4 -ponbin/POPSLDR/*.lua+etc/boot.lua) is now LIVE — it used to silently skip because the ps2dev image shipped noluac; the workflows nowapk add lua5.4and hard-fail on a syntax error. It catches SYNTAX only — runtime nil-global / type / load-order errors stay invisible to CI (see thed4b04beload-order boot brick). See STATE.md > CI / release. - Rolling release workflow publishes two assets —
POPSLOADER-rolling-release.zipand the barePOPSLOADER.ELF— to the canonicalrolling-releaseGitHub Release, overwriting them each time. Only a push todevpublishes; PR events build and gate but skip the publish step (gated since PR #511, 2026-07-16). - Redistributable launcher in the zips.
POPSTARTER.ELF(the redistributable POPStarter homebrew launcher — the POPS engine binaries are not redistributable and are not shipped) now ships in both zips:rolling-release.ymlputs it at the zip root next toPOPSLOADER.ELFand inPOPS/, and also ships aPOPSTARTER/pack folder (BDMA/SMB modules) +POPS/PATCH_5.BINat the rolling root;compilation.yml(the strict-verifiedPS1_POPSLOADER/install zip) shipsPOPSTARTER.ELFinPS1_POPSLOADER/(next toPOPSLOADER.ELF) andPOPS/.
4) Settings UI redesign
- 2026-05-19/20 OPL-style focused-list shipped (Settings page rewrite). Hardware verification deferred per the launch-path retest sequence.
- Berion-mockup-driven GUI overhaul is queued (see #5 below). The OPL focused list is intended to be replaced when that overhaul lands, so further iteration on the focused list is paused unless a specific bug appears.
5) Full GUI overhaul (Berion mockups)
- 2026-05-24: graphics-team mockups by Berion and the matching PNG asset set landed (
f8fec64). Full implementation prompt and per-screen pixel specs live indocs/archive/GUI_OVERHAUL_PROMPT.md. - Scope: Context menu, Settings (per-category pages superseding the OPL focused-list), Joypad configuration, On-screen keyboard. Boot/splash and game list are out of scope.
- Prereq: the launch-path hardware verification (DKWDRV-on-HDD, wLaunchELF, U-10) has now settled — all resolved (see STATE.md > Known Issues). The remaining gate is the 2026-06 HDD-resident settings save + in-app HDD
.hide+ PAL-512 features, which are still validating on hardware; the category-page Settings model in the prompt replaces the OPL focused-list, so coordinate retest sequencing once those settle. - Mockup HTML/JSX wrapper from Berion's package is referenced by the prompt but not yet committed; either commit the mockup files or use a screenshot/hosted-mockup oracle before starting the Lua port.
6) Documentation cleanup (per docs/archive/DOCUMENTATION_FOLLOWUP_AUDIT.md) — DONE 2026-06-17
- Completed 2026-06-17. The doc set was consolidated: the volatile status facts were merged into the canonical
STATE.md(including the formerTRUTHSHEET.md), the obsolete/superseded docs were archived underdocs/archive/, and the doc set was de-duplicated so each fact lives in exactly one place. The original three-PR plan (source-of-truth sync, agent/handoff cleanup, architecture/component/release polish) is folded into this consolidation. - Was out of scope (and stayed so): any change to runtime code or to CI/build/release workflows; this was doc-only.
Deferred Ideas
- Additional themes/skins.
- Broader network/backend support building on the
SMB (v1)baseline (implemented; browse + launch hardware-confirmed on a static IP config) and onceILINKhas a defined baseline. - More ambitious artwork cache policy after current launch/runtime issues are stable.