The Rust Imaginary Console Offline
A fantasy console inspired by PICO-8, built with Rust for performance and Lua for scripting.
- Introduction
- Features
- Screenshots
- Installation
- Quick Start
- Sprite Engine
- IDE Engine
- Terminal Engine
- Cartridge & Lua Files
- API Reference
- Examples
- Contributing
- License
- TODO
RICO-32 is a fantasy console that combines the nostalgic charm of retro game development with modern Rust performance. It features a 128×128 pixel game screen with a 16-color palette, Lua scripting support, and a built-in console for debugging and logging.
The console is designed to be simple yet powerful, allowing developers to create games quickly using Lua while benefiting from Rust's performance and safety guarantees. Whether you're prototyping a game idea or creating a full retro-style game, RICO-32 provides the tools you need.
- 128×128 Pixel Display: Classic retro resolution with 4× pixel scaling for modern displays
- 16-Color Palette: Predefined color palette for consistent retro aesthetics
- Lua Scripting: Full Lua 5.4 support with custom module system. Only safe Lua features are enabled, allowing for security when running external cartridges.
- Built-in Console: Integrated console engine for logging and debugging
- Sprite Support: Create custom 16x16 sprites within the console and use and load them in the game
- Built-in IDE: Edit your Lua scripts with syntax highlighting without leaving the console.
- Input Handling: Mouse and keyboard input with frame-accurate state tracking
- Frame Rate Control: Configurable frame rate with delta time support
- Modular Architecture: Clean separation between game engine, console engine, and scripting
- In Memory Reload Support: Restart functionality for rapid iteration and smooth development.
- Full cartridge support: .r32 files are cartridges that can be shared with other users. RICO-32 will make a main.r32 if one doesn't already exist on startup but any cartridge can be loaded and saved to from the inbuilt terminal.
- Full inbuilt terminal: Contains commands to load cartridges, save cartridges to different formats, and export standalone executables.
more examples eventually...
- Rust (1.70 or later)
- Cargo (comes with Rust)
- A C compiler (for building native dependencies) (i think)
-
Clone the repository:
git clone https://github.com/RICO-32/RICO-32.git cd RICO-32 -
Build the project:
cargo build --release
-
Run the project:
cargo run
Or run the release binary directly:
cargo run --release
-
Run RICO-32: Execute
cargo run --releaseand your RICO-32 will start! -
Create your game scripts: Edit
r32/main.luato start building your game. You can use the built-in IDE or your favorite external editor. -
Build the game: Use the sprite engine to create and edit sprites and the console to debug your game.
-
Building a final standalone executable for your game can be done by running the following in the inbuilt terminal.
export <filename>function start()
rico:log("Welcome to RICO-32!")
rico:set_frame_rate(60)
end
function update(dt)
rico:clear("BLACK")
rico:print_scr(10, 10, "WHITE", "Hello, World!")
local mouse = rico:mouse()
if mouse.pressed then
rico:circle(mouse.x, mouse.y, 5, "RED")
end
endRICO-32 includes a built-in sprite editor for creating and managing 16x16 pixel sprites. Access the sprite editor from the main interface to design sprites that can be used in your games.
- 16x16 Sprite Canvas: Edit sprites pixel-by-pixel with a 6× zoomed preview
- 60-Sprite Sheet: Store up to 60 sprites (expandable) in a persistent sprite sheet
- RICO-32 features an inbuilt sprite file spec to store and read the sprite sheet for the engine
- Drawing Tools:
- Pencil: Draw individual pixels with the selected color
- Fill: Flood-fill connected areas with the selected color
- Eraser: Remove pixels (set to transparent)
- Select: Create rectangular selections for advanced editing
- Selection Tools:
- Click and drag to create rectangular selections
- Move selections by clicking inside and dragging
- Copy (Ctrl+C) and paste (Ctrl+V) selections
- Flip horizontal/vertical within selections or entire sprite
- Clear selected areas or entire sprite
- Undo/Redo: Full undo/redo support with keyboard shortcuts
- 16-Color Palette: Quick access to all RICO-32 colors
- Auto-Save Indicator: Changes are marked with an asterisk (*) until saved
- Select a sprite: Click on any sprite in the sprite sheet panel (bottom of screen). Scroll to view more sprites.
- Choose a tool: Click one of the tool buttons (Pencil, Eraser, Fill, Select)
- Pick a color: Click a color from the palette at the top
- Draw: Click and drag on the canvas to draw or use tools
- Save: Click the save button or use Ctrl+S to persist changes to disk
Click the + button at the bottom of the sprite sheet panel to add 6 more sprite slots. The sprite sheet automatically expands to accommodate your needs.
Load and draw sprites in your Lua scripts using the draw() function:
function start()
rico:set_frame_rate(60)
end
function update(dt)
rico:clear("BLACK")
-- Draw sprite 0 at position (48, 48)
rico:draw(48, 48, 0)
-- Draw sprite 5 at position (80, 48)
rico:draw(80, 48, 5)
endRICO-32 features a built-in code editor for Lua scripts, accessible from the "IDE" tab.
- Syntax Highlighting: Code is colored to distinguish keywords, strings, numbers, and comments.
- File Browser: A list of all
.luafiles in ther32/directory is shown at the bottom. Click a file to open it. - Create New Files: Click the
+button to create a new Lua file. - Live External Reload: The IDE automatically detects and reloads files if they are changed by an external editor.
- Status Bar: Displays the current file name, line/column number, and an asterisk (
*) for unsaved changes. - Standard Editing Controls:
- Full mouse support for cursor placement and selection.
- Ctrl+S: Save the current file.
- Ctrl+C: Copy selected text.
- Ctrl+X: Cut selected text.
- Ctrl+V: Paste text from the clipboard.
- Ctrl+Z: Undo the last action.
- Ctrl+R: Redo the last undone action.
- Ctrl+A: Select all text in the file.
- Arrow Keys: Move the cursor.
- Shift + Arrow Keys: Create or modify a selection.
- Tab: Insert 4 spaces.
- Enter: Insert a new line.
- Backspace: Delete characters or the current selection.
RICO-32 features an inbuilt terminal to perform essential RICO-related commands.
load <filepath>: Loads a cartridge into memory, can be a normal.r32cartridge or a base 64 version stored as.r32.txt.save <filepath>: Saves the current loaded cartridge to a file on disk, can be a normal.r32cartridge or a base 64 version stored as.r32.txt.export <filepath>: Exports the current loaded cartridge as a standalone executable for the current operating system. There is currently only support for linux and windows.mv <source> <destination>: Moves or renames a file within ther32/directory. Parent directories for the destination will be created if they don't exist.rm <filename>: Removes a Lua file from ther32/directory.help [cmd]: prints out a list of commands what they do. If a command is specified, gives details on how to use that command and a bit more info about it.
- Lua files are extracted to
r32/next to the executable and cartridge when a game is loaded. - Users can edit files externally with their favorite editor.
- RICO-32 automatically watches the
r32/folder for any changes made through any IDE and auto recompiles the cartridge to be instantly loaded whenever the game is restarted through restarting the whole engine or the inbuilt game restart. - Sprites are never written to r32/, remaining fully in memory and the cartridge, and must be saved to the cartridge using the checkmark within the sprite editor.
- Cartridges fully contain all information related to all RICO-32 games, and thus RICO-32 games can be shared easily by sharing .r32 files or using their Base64 version.
- To convert the formats of your cartridges from
.r32to.r32.txt(the base64 version), simply load whichever format from the inbuilt terminal and then save it back to whichever format.
load cart.r32
save b64.r32.txtNote: all changes made to the r32/ directory while RICO-32 is not running will be discarded and overwritten with the cartridge upon initial RICO-32 startup.
All RICO API functions must be prefixed with rico: to be called in Lua. This does not include the core functions listed below.
Called once at the start of the program. Use this for initialization.
Called every frame. dt is the delta time in milliseconds since the last frame.
Sets the pixel at coordinates (x, y) to the specified color.
Parameters:
x(number): X coordinate (0-127)y(number): Y coordinate (0-127)COLOR(string): One of the 16 color names
Gets the color of the pixel at coordinates (x, y).
Returns: Color name as a string
Fills the entire screen with the specified color.
Fills a rectangle with the specified color.
Parameters:
x, y(number): Top-left corner coordinatesw, h(number): Width and heightCOLOR(string): Fill color
Draws a rectangle outline with the specified color.
Draws a filled circle.
Parameters:
x, y(number): Center coordinatesr(number): RadiusCOLOR(string): Fill color
Draws a line between 2 points. Automatically handles vertical, horizontal, steep lines. Order of the points does not matter.
Parameters:
x, y(number): Coordinates of the first pointx1, y1(number): Coordinates of the second pointCOLOR(string): Fill color
Draws a sprite created in the sprite engine.
Parameters:
x, y(number): Top-left corner coordinatesidx(number): Index of the sprite (check by clicking on it in the sprite tab, should display which sprite is being edited)
Prints text to the screen. Each character is 8×8 pixels.
Prints text with medium-sized characters (4×6 pixels).
Prints text with mini-sized characters (4×4 pixels).
Returns a mouse object with the following properties:
.just_pressed(boolean): Whether the left button was just pressed (lasts 1 frame).pressed(boolean): Whether the left button is currently pressed.x(number): X coordinate in pixels (-1 if outside window).y(number): Y coordinate in pixels (-1 if outside window)
Returns whether the specified key is currently pressed.
Returns whether the specified key was just pressed this frame.
Supported Keys:
- Numbers:
"1"through"0" - Letters:
"A"through"Z" - Arrows:
"Left","Up","Right","Down" - Special:
"Back","Enter","Space"
Prints a message to the console. Messages are displayed in the console panel below the game screen.
Sets the target frame rate. Set to 0 or negative for unlimited frame rate.
The following 16 colors are available:
"BLACK", "WHITE","GRAY", "SILVER""RED", "MAROON", "ORANGE", "YELLOW""GOLD", "GREEN", "OLIVE", "BROWN""BLUE", "TEAL", "PURPLE", "PINK"
The project includes several example games in the examples/ directory:
- Platformer: A simple platformer game
- Shooter: A top-down shooter example
- Tetris: Classic Tetris implementation
To run an example, simply run the following in the inbuilt terminal.
load <filepath>Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes: Follow Rust and Lua best practices
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request: Provide a clear description of your changes
- Follow Rust naming conventions and style guidelines
- Add comments for complex logic
- Update documentation for new API functions
- Test your changes with example games
- Ensure the project builds with
cargo build
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2025 Dhruv Goel
- Sound and music support
- Save/load game state functionality
- Export to web (WebAssembly)
- Additional graphics primitives (lines, polygons)
- Tilemap support
- Physics engine integration
- Networking capabilities for multiplayer games
Made with <3


