Highlights
- Stateless egui widget that renders a classic ASCII aquarium to a single monospace label
- Deterministic pacing (fixed timestep) with a minimal, calm vibe
- Environment: waterlines with wave motion, swaying seaweed, castle, bubbles
- Entities: ship (surface), shark and whale (with spout), fish schools
- Fish UX: correct facing (auto-mirroring), subtle jitter, occasional bounce variance
- Despawn/respawn cycles for large entities; schools traverse and despawn off-screen
- Optional color mode with a palette; classic mask chars (?) become subtle motion trails
Install
[dependencies]
egui = "0.27"
asciiquarium_rust = { git = "https://github.com/gitcoder89431/asciiquarium-rust", tag = "v0.1.0" }
Quickstart
use asciiquarium_rust::{
get_all_fish_assets, update_aquarium, AsciiquariumTheme, AsciiquariumWidget,
AquariumState, FishInstance,
};
let assets = get_all_fish_assets();
let mut state = AquariumState { size: (80, 24), ..Default::default() };
state.fishes.push(FishInstance { fish_art_index: 0, position: (2.0, 3.0), velocity: (12.0, 0.0) });
update_aquarium(&mut state, &assets);
let theme = AsciiquariumTheme {
text_color: egui::Color32::from_rgb(180, 220, 255),
background: Some(egui::Color32::from_rgb(8, 12, 16)),
wrap: false,
enable_color: false,
palette: None,
};
ui.add(AsciiquariumWidget { state: &state, assets: &assets, theme: &theme });
Optional color mode
- Set enable_color = true and provide a palette (maps ~,^ to water, . to bubbles, ? to a subtle water_trail). Falls back to plain text when disabled.
Example
use asciiquarium_rust::widgets::asciiquarium::AsciiquariumPalette;
let palette = AsciiquariumPalette {
water: egui::Color32::from_rgb(120, 180, 255),
water_trail: egui::Color32::from_rgba_unmultiplied(120, 180, 255, 120),
seaweed: egui::Color32::from_rgb(60, 180, 120),
castle: egui::Color32::from_rgb(200, 200, 200),
ship: egui::Color32::from_rgb(230, 230, 230),
bubble: egui::Color32::from_rgb(200, 230, 255),
shark: egui::Color32::from_rgb(180, 200, 210),
whale: egui::Color32::from_rgb(160, 190, 210),
fish: egui::Color32::from_rgb(255, 200, 120),
};
let mut theme = AsciiquariumTheme { enable_color: true, palette: Some(palette), ..theme };
Notes
- Monochrome mode skips ? masks entirely.
- Color mode uses palette.water_trail for ? to emulate subtle motion trails.
- All animation logic is deterministic and state-driven; the widget remains stateless.