| Crates.io | rustmaton |
| lib.rs | rustmaton |
| version | 0.3.0 |
| created_at | 2023-02-07 01:47:05.895863+00 |
| updated_at | 2026-01-04 18:55:54.958443+00 |
| description | A text editor for Conway's Game of Life |
| homepage | https://github.com/deweyjose/rustling |
| repository | https://github.com/deweyjose/rustling |
| max_upload_size | |
| id | 778426 |
| size | 4,136,865 |
A terminal-based Conway's Game of Life editor built with Rust, ratatui, and crossterm.
curl --location https://github.com/deweyjose/rustling/releases/download/0.3.0/install.sh | sh
Requires Rust 1.70.0 or later.
git clone https://github.com/deweyjose/rustling.git
cd rustling
cargo build --release
Binary location: target/release/rustmaton
# Run with default patterns.json in current directory
rustmaton
# Specify a custom patterns file
rustmaton --patterns path/to/patterns.json
# Make grid larger than viewport (default multiplier: 3)
rustmaton --multiplier 5
| Key | Action |
|---|---|
↑ ↓ ← → |
Move cursor |
Tab / Shift+Tab |
Move cursor by 4 |
b / e |
Jump to start/end of line |
a |
Set cell alive |
d / Backspace |
Set cell dead |
1-9 |
Place pattern at cursor |
l |
Place last pattern again |
r |
Rotate last pattern 90° |
p |
Cycle pattern type |
g |
Enter pattern gallery |
s |
Toggle simulation |
Space |
Step simulation forward |
+ / - |
Speed up / slow down |
c |
Clear grid (reset on resize) |
h |
Show help |
q / Ctrl+C |
Quit |
g to enter)| Key | Action |
|---|---|
↑ / ↓ |
Navigate tree |
← |
Collapse type or go to parent |
→ |
Expand type or enter children |
Enter |
Select pattern |
g / Esc |
Exit gallery mode |
Patterns are loaded from patterns.json. The file contains pattern types (categories) with named patterns:
[
{
"name": "oscillators",
"patterns": [
{
"name": "blinker",
"matrix": [[1,1,1]],
"rotation_count": 0
}
]
}
]
matrix: 2D array where 1 = alive, 0 = deadrotation_count: Optional (0-3), represents 0°/90°/180°/270° rotationIf no patterns file is found, a default blinker pattern is loaded.
src/
├── main.rs # Entry point, CLI parsing, pattern loading
├── app.rs # Application state (App, AppMode, GalleryCursor)
├── orchestrator.rs # Game loop, event handling, command execution
├── commands.rs # Event → Command mapping, mode-aware dispatch
├── renderer.rs # Layout composition, widget orchestration
├── user_input.rs # Crossterm event polling
├── grid.rs # Conway's Game of Life engine
├── viewport.rs # Grid-to-screen coordinate conversion
├── pattern.rs # Pattern/PatternType data structures
├── health.rs # Cell state enum (Alive/Dead)
├── coordinates.rs # 2D position struct
├── size.rs # Width/height dimensions
├── theme.rs # UI styling (colors, modifiers)
└── widgets/
├── mod.rs
├── game_canvas.rs # Grid rendering widget
├── header_bar.rs # Title bar widget
├── footer_bar.rs # Status bar widget
├── help_popup.rs # Help overlay widget
└── pattern_gallery.rs # Tree-view pattern browser (StatefulWidget)
flowchart TB
subgraph Entry["Entry Point"]
Main[main.rs]
end
subgraph State["Application State"]
App[app.rs<br/>App, AppMode, GalleryCursor]
Theme[theme.rs<br/>UI Styling]
end
subgraph Control["Control Layer"]
Orchestrator[orchestrator.rs<br/>Game Loop & Commands]
Commands[commands.rs<br/>Mode-aware Dispatch]
UserInput[user_input.rs<br/>Event Polling]
end
subgraph Rendering["Rendering Layer"]
Renderer[renderer.rs<br/>Layout Composition]
subgraph Widgets["Widgets"]
GameCanvas[game_canvas.rs]
HeaderBar[header_bar.rs]
FooterBar[footer_bar.rs]
HelpPopup[help_popup.rs]
PatternGallery[pattern_gallery.rs]
end
end
subgraph Core["Core Game Logic"]
Grid[grid.rs<br/>Conway Engine]
Viewport[viewport.rs<br/>Coordinate Mapping]
Pattern[pattern.rs<br/>Pattern Data]
end
subgraph Primitives["Primitives"]
Health[health.rs]
Coordinates[coordinates.rs]
Size[size.rs]
end
Main --> Orchestrator
Main --> Pattern
Orchestrator --> App
Orchestrator --> Renderer
Orchestrator --> Commands
Orchestrator --> Grid
Commands --> UserInput
Renderer --> Widgets
Renderer --> Theme
Widgets --> App
Grid --> Viewport
Grid --> Primitives
Viewport --> Primitives
Widget or StatefulWidget traitListState for automatic scroll-to-selectionmain.rs parses CLI args, loads patterns, initializes OrchestratorTerminal::draw()Renderer composes layout and delegates to widgets| Crate | Purpose |
|---|---|
| ratatui | Terminal UI framework |
| crossterm | Cross-platform terminal manipulation |
| clap | CLI argument parsing |
| serde / serde_json | Pattern file serialization |
# Run in development mode
cargo run
# Run tests
cargo test
# Build release
cargo build --release
When gameplay changes, update the demo GIF in docs/img/gol.gif:
# Install tools
brew install asciinema agg
# Record gameplay session
asciinema rec demo.cast
# Run the game and demonstrate features
cargo run --release -- --grid-multiplier 2
# (play the game, then exit)
# Convert to optimized GIF
agg --speed 10 demo.cast docs/img/gol.gif
MIT OR Apache-2.0