ROCCO is a browser-based retro console runtime with built-in cartridges. The project is organized for cartridge development through code and AI-assisted editing rather than a visual level editor.
The console is called ROCCO, the main demo cartridge is called ROCCO, and the player character is also Rocco.
ROCCO is a cartridge-oriented console runtime. Its console layer provides rendering, audio, input, effects, persistence, and cartridge loading. Cartridges provide the cartridge content and interact with the runtime through a stable TypeScript SDK surface plus subsystem SDKs.
ROCCO works well with AI-powered coding tools because the codebase is organized around documented concepts: console systems, cartridge infrastructure, built-in cartridges, levels, sprites, effects, and localized text catalogs.
- TypeScript for typed development with explicit SDK interfaces.
- PixiJS for accelerated 2D rendering.
- Dexie and IndexedDB for local persistence.
- Vite for the development server and production build.
- Electron and electron-builder for portable desktop packaging.
- Vitest for tests.
- PWA tooling for installable web builds.
- Graphic planes for layered backgrounds, parallax, procedural generation, and image effects.
- Sprite definitions and instances with animation, actions, movement, depth sorting, and walk maps.
- SCUMM-style radial action menus.
- Generic slot grid menus and text choice lists for cartridge-defined panels, reorderable slots, and carried item payloads.
- Character speech bubbles, thought bubbles, hover titles, and status text.
- Web Audio sound playback and jukebox playlists.
- Scriptable effects such as auto-scroll.
- Cartridge selection menu with localized metadata support and extensible boot-time settings modules.
- CRT-style display profile and fullscreen viewport scaling.
src/
main.ts Entry point
style.css Global page style
console/ Console runtime implementation and SDK surface
audio/ Sound and jukebox systems
cartridges/ Cartridge interfaces, loader, and providers
cartridge-menu/ Boot-time cartridge selection UI
effects/ Per-tick effect system
persistence/ IndexedDB persistence adapter
video/ Rendering systems and visual subsystems
cartridges/ Built-in cartridge implementations
rocco/ Cartridge bootstrap, RPCE runtime, and the rocco-default game
rpce/ Cartridge-local point-and-click runtime
games/rocco-default/ Current game content organized by maps
public/ Static browser assets
scripts/ Windows-friendly development scripts
This project includes scripts that use a portable local Node.js installation when available.
First setup and dev server:
powershell -ExecutionPolicy Bypass -File .\scripts\setup.ps1
powershell -ExecutionPolicy Bypass -File .\scripts\dev.ps1If a compatible global Node installation is already available, standard npm commands also work:
npm install
npm run devSee DEVELOPMENT.md for the full command and validation guide.
The GitHub Actions workflow publishes these downloadable artifacts:
web-app-latestfor the webdist/bundle.macos-latest-dmgfor the unsigned macOS DMG build.windows-latest-portablefor the portable Windows executable.ubuntu-latest-appimagefor the Linux AppImage build.
rocco-default is the main demo cartridge. It implements the Pier exterior, the bait shop interior, the Nether path including the Reset Office branch, the independent final credits level, and the cartridge-owned inventory systems that tie those spaces together.
See src/cartridges/rocco/README.md for cartridge ownership, map structure, interactions, and localization details.
ROCCO uses a console/cartridge architecture:
- The console is the generic host runtime.
- Cartridges are self-contained software cartridges.
- The Rocco cartridge layers
RPCEbetween the cartridge bootstrap and therocco-defaultgame, so the structure readsconsole -> cartridge -> RPCE -> game -> maps -> levels. - Cartridges mount through
RoccoCartridgewith a requiredcontext.sdk; the console kernel is never handed to a cartridge. - Cartridges can contribute boot-time setup and settings modules before a cartridge is mounted.
- The console runtime stays generic; cartridge logic stays inside cartridge folders.
For implementation details, read the README chain under src/console and src/cartridges.