Archive of https://git.etawen.dev/earthonion/luabr3w — Luac0re + LuaGB/LuaPSX/PSN64 launcher for PS5 https://git.etawen.dev/earthonion/luabr3w
  • C 94.1%
  • Lua 1.8%
  • Python 1.5%
  • Assembly 1%
  • C++ 0.8%
  • Other 0.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-31 23:59:08 -04:00
browser browser: web-link entries + sceSystemServiceLaunchWebBrowser probe 2026-08-31 23:59:08 -04:00
docs browser: web-link entries + sceSystemServiceLaunchWebBrowser probe 2026-08-31 23:59:08 -04:00
homebrew Luac0re + LuaGB / LuaPSX / PSN64 launcher for PS5 2026-08-31 23:17:46 -04:00
Luac0re Luac0re + LuaGB / LuaPSX / PSN64 launcher for PS5 2026-08-31 23:17:46 -04:00
.gitignore Luac0re + LuaGB / LuaPSX / PSN64 launcher for PS5 2026-08-31 23:17:46 -04:00
LICENSE Luac0re + LuaGB / LuaPSX / PSN64 launcher for PS5 2026-08-31 23:17:46 -04:00
README.md README: Kimi K3 attribution 2026-08-31 23:25:53 -04:00

Homebrew Browser

An on-screen, gamepad-driven homebrew launcher for the PS5, baked into the Luac0re savedata. Trigger the exploit (OPTIONS → HALL OF FAME in Star Wars Racer Revenge) and the menu is simply there — pick a title, press Cross, play. No PC, no network, no payload sender at runtime.

No kernel exploit required. Everything runs in userland inside the ps2emu sandbox.

Bundled titles:

  • LuaGB — Game Boy / Game Boy Color
  • LuaPSX — PlayStation
  • PSN64 — Nintendo 64

Controls

DualSense Action
D-Pad navigate
Cross launch / select
Circle back to the Homebrew Browser (from any emulator's picker)
R1 (hold) quit the browser to the Luac0re remote Lua loader (TCP 9026)

Requirements

  • A PS5 running Luac0re from the Star Wars Racer Revenge (CUSA03474 / CUSA03492) savedata — see Luac0re/README.md
  • Build host: gcc, binutils, make, python3
  • garlic-savemgr on the console for the one-time save install and updates

Build and install

browser/tools/stage.sh

This builds the browser and every emulator under homebrew/, then assembles browser/saveimage/ — the exact tree that goes into the savedata image (--skip-emulators skips the emulator builds while iterating on the menu):

lua/auto.lua                  the orchestrator Luac0re boots into
browser/menu.bin              the on-screen menu payload
homebrew/<Title>/payload.bin  one per emulator
homebrew/<Title>/manifest     launch metadata (see docs/DEVELOPING.md)

Then, with garlic-savemgr running on the console:

browser/tools/install_save.py <savemgr-ip> <save-index>

It mounts the save, uploads the staged tree, prints the used/free space against the 42.25 MB image budget, and always unmounts afterwards. Game assets are your own: GB/GBC/N64 ROMs go in roms/, the PS1 BIOS (scph7002.bin) in bios/. Do the install with the game closed.

To update later, re-run both commands.


Repository layout

  • browser/ — the launcher itself: Lua orchestrator (lua/auto.lua), the native menu payload (src/), staging/install tooling (tools/), and a JIT capability probe (tools/jitprobe.lua)
  • homebrew/ — the bundled emulators, each with a dist target producing the payload.bin + manifest pair the browser installs
  • Luac0re/ — the delivery substrate (vendored from Gezine/Luac0re)
  • docs/DEVELOPING.md — how to write your own homebrew for this launcher

Writing your own homebrew

See docs/DEVELOPING.md. Short version: a title is a directory homebrew/<Title>/ in the save containing a freestanding static-PIE x86_64 payload.bin and a four-line manifest. The browser loads it into JIT memory and calls it; when it returns, the menu comes back.


Limitations

  • LuaPSX discs do not fit in the save — they live in /temp0 (uploaded with LuaPSX's own flow) and do not survive a reboot.
  • The touch web controller (port 9030) is not available for browser-launched titles; use the DualSense.
  • The screen goes black for a moment between menu and game — the menu payload is reloaded each time. Normal.
  • The JIT pool is three 256 KB chunks per session, shared by menu and games; a title can reserve at most 768 KB. Payloads that allocate must release, or the Nth launch fails.

Troubleshooting

  • Run browser/tools/jitprobe.lua once via Luac0re/payload_sender.py before installing on a new firmware — it validates the JIT assumptions and logs to UDP 9027 (nc -u -l -p 9027). It spends the JIT pool, so relaunch the game afterwards.
  • The browser and every payload log to UDP 9027 (subnet broadcast). When something hangs, the last log line names the stage.

Credits

  • Luac0re — Gezine (MIT) — exploit chain and Lua runtime
  • LuaGB / LuaPSX / PSN64 — soniciso1 — the bundled emulators
  • Emulation cores: fixGB (FIX94), PCSX-ReARMed, mupen64plus / parallel-n64 / cen64 (angrylion)
  • PS5 runtime pattern: EmuC0re by egycnq / EgyDevTeam
  • remote_lua_loader by shahrilnet — the pattern Luac0re's Lua side derives from

No copyrighted content (BIOS, ROMs) is included in this repository.


This project was made with Kimi K3.