# Asciiquarium Redux đ
[](https://pypi.org/project/asciiquarium-redux/) [](https://cognitivegears.github.io/asciiquarium_redux/) [](https://www.python.org/downloads/) [](https://github.com/cognitivegears/asciiquarium_redux/actions/workflows/ci.yml) [](LICENSE)
A joyful, colorful Python reimagining of the classic terminal aquarium. Watch fish swim, seaweed sway, hooks drop, sharks prowl, and bubbles popâright in your terminal or a windowed Tk screen.
Original Asciiquarium by Kirk Baucom (Perl): [robobunny.com/projects/asciiquarium](https://robobunny.com/projects/asciiquarium/html/)
Status: Playable, configurable, and window-ready (Tk). Bring your own snacks (for the ducks).
đ Try it in your browser (no install): [Live web version](https://cognitivegears.github.io/asciiquarium_redux/)

## Why a Redux?
- Keep the whimsical aquarium alive on modern terminals and platforms
- Offer configurable FPS, colors, sizes, and deterministic playback (seeded RNG)
- Ship as an installable Python package for easy use (e.g., `pipx install`)
## Features
- Faithful animations: fish (with color masks), seaweed lifecycle/sway, waterline, castle, bubbles, and many specials (shark, whale, ship, ducks, swan, dolphins, monster, big fish)
- Decor: treasure chest that sits on the seabed, occasionally bubbles, and periodically opens to release a stream of bubbles (drawn behind fish)
- Fishhook gameplay: one hook at a time, impact pause, configurable dwell time, collisions while lowering/dwelling/retracting
- Smooth rendering: double-buffered terminal drawing to reduce flicker
- Backends: terminal (asciimatics) and windowed Tk canvas (resizable, color)
- Configurable everything: FPS, speed, density, spawn timings/weights, fish bands, colors; TOML-based config
- Deterministic playback (seed) for captures and demos
- Fish turning: fish can occasionally turn around with a smooth shrink/flip/expand animation (configurable)
## đ Documentation
### Quick Start
- **[Getting Started Guide](docs/DEVELOPER_GUIDE.md)** - Setup, installation, and first steps
- **[Configuration Guide](docs/CONFIGURATION.md)** - Complete settings reference and customization
- **[Backend Comparison](docs/BACKENDS.md)** - Terminal vs Web vs TkInter backends
### Technical Reference
- **[Architecture Overview](docs/ARCHITECTURE.md)** - System design and component relationships
- **[API Reference](docs/API_REFERENCE.md)** - Public interfaces and usage examples
- **[Entity System](docs/ENTITY_SYSTEM.md)** - Fish, seaweed, bubbles, and special entity details
### Deployment & Advanced
- **[Web Deployment](docs/WEB_DEPLOYMENT.md)** - Browser setup and GitHub Pages deployment
- **[Sample Configuration](sample-config.toml)** - Example TOML configuration file
## Quick start
From source using uv (already configured in this repo):
```sh
# macOS/Linux
uv run python main.py # terminal backend
# Or use the repo venv directly
source .venv/bin/activate
python main.py
```
Install-free run from PyPI with uvx:
```sh
# Latest published version
uvx asciiquarium-redux
# Pass CLI flags to the app directly
uvx asciiquarium-redux --fps 30 --density 1.2 --seed 123
# Windowed Tk backend
uvx asciiquarium-redux --backend tk
# Refresh cached app to the newest release
uvx --refresh asciiquarium-redux
```
Run with pipx:
```sh
pipx install asciiquarium-redux
# Run
asciiquarium-redux
# Tk backend
asciiquarium-redux --backend tk
# Upgrade later
pipx upgrade asciiquarium-redux
```
Windowed Tk backend:
```sh
uv run python main.py --backend tk
```
## Web mode (run in your browser)
You can run Asciiquarium Redux fully in the browser using Pyodide. The app starts a tiny local web server that serves a static page and installs the package into the browser runtime.
Local run (opens your default browser):
```sh
# From a clone
uv run python main.py --backend web --open
# Or via the installed CLI
asciiquarium-redux --backend web --open
# Choose a port (default 8000) and open manually if you prefer
asciiquarium-redux --backend web --port 9000
# Then visit http://127.0.0.1:9000/
```
Notes
- The web page provides simple controls (FPS, speed, density, color, chest, turn, seed). Changes apply live.
- Keyboard/mouse controls mirror the terminal/Tk versions: q, p, r, h, space, t; click to drop/retract the hook.
- If you update Python code, the server copies the latest wheel into `web/wheels`. Hard refresh the page to pick up changes.
- The browser installs the local wheel first; if not present, it falls back to PyPI.
### Deploy to GitHub Pages
You can publish the web UI as a static site. The browser will install the package from PyPI at load time.
Option A â one-click from VS Code
1) Use the provided task: âDeploy web to GitHub Pagesâ. It creates (or overwrites) a `gh-pages` branch with the contents of `asciiquarium_redux/web/` and pushes it to `origin`.
2) In your GitHub repo Settings â Pages, choose âBranch: gh-pages / rootâ.
3) Visit <https://USERNAME.github.io/REPO/>
Option B â manual commands (equivalent)
```sh
# From the repo root
set -euo pipefail
tmp=$(mktemp -d)
rsync -a --delete asciiquarium_redux/web/ "$tmp/"
cp -f "$tmp/index.html" "$tmp/404.html" || true
origin=$(git remote get-url origin)
git -C "$tmp" init
git -C "$tmp" checkout -b gh-pages
git -C "$tmp" add .
git -C "$tmp" -c user.name='gh-pages' -c user.email='gh-pages@local' commit -m 'Deploy web to GitHub Pages'
git -C "$tmp" remote add origin "$origin"
git -C "$tmp" push --force origin gh-pages
```
Tips
- Paths in `index.html` are relative, so project pages (`/your-repo/`) work without changes.
- If the page canât install the package in the browser, ensure the latest version on PyPI includes the web backend.
- For custom forks, publishing your own release to PyPI ensures the web UI can install cleanly from Pages.
Controls:
- q: quit
- p: pause/resume
- r: rebuild scene (useful after resize)
- h or ?: toggle help overlay
- space: drop/retract fishhook (random position in terminal)
- mouse: left-click to drop a hook at the cursor (or retract if one is active)
- s (Tk): save a screenshot as ./asciiquarium_#.png (auto-incrementing)
- t: force a random fish to turn (useful to preview the turning animation)
- f: feed fish (spawns floating flakes fish will seek and eat)
CLI examples:
```sh
uv run python main.py --fps 30 --density 1.5 --color mono --seed 123 --speed 0.7
# Use a specific config file
uv run python main.py --config ./sample-config.toml
uv run python main.py --backend tk --fullscreen
```
Common flags:
- --fps (int): target frames per second (default 24, clamp 5â120)
- --density (float): density multiplier (default 1.0, clamp 0.1â5.0)
- --color <auto|mono|16|256>: color mode (mono forces white)
- --seed (int): deterministic RNG seed; omit for random
- --speed (float): global speed multiplier (default 0.75)
- --backend <terminal|tk>: choose backend
- --fullscreen: make Tk window fullscreen
- --font-min (int): minimum Tk font size bound for auto-resize
- --font-max (int): maximum Tk font size bound for auto-resize
- --ai / --no-ai: enable or disable Utility AI behaviors
- --port (int): web server port for web backend
## Notes
- Terminal uses `asciimatics`; Tk backend renders to a Canvas with per-cell text.
- Tk resizes by adjusting the character grid to the window size; the scene rebuilds when size stabilizes.
- When Tk font_auto is enabled, font size auto-fits within [font_min_size, font_max_size] so the castle fits; sliders clamp min<=max.
- Ensure a UTF-8 locale and a monospaced font for best results.
Behavior highlights
- Fish can drift vertically (bounded by fish.vertical_speed_max; default 2.0 rows/sec) while keeping mostly horizontal motion.
- Utility AI (when enabled) prioritizes eating fish food; when very hungry and no food is available, larger fish may prey on strictly smaller fish.
- Predation creates a brief splat effect; prey are immediately respawned to maintain population.
- If fish counts remain low for a while, restocking gently replenishes the population.
## Tk backend requirements (Tkinter)
This is only needed if you want to use the Tk backend (`--backend tk`). If tk is not available, the app will fall back to the terminal backend.
The Tk backend needs Python built with tkinter and the system Tk libraries. If Tk isnât available, the app automatically falls back to the terminal backend.
Quick test:
```sh
python -c "import tkinter as tk; print('tk', tk.TkVersion)"
```
macOS
- Recommended: Install Python from python.org (bundles a compatible Tcl/Tk).
- Homebrew (brew):
```sh
brew install python tcl-tk
python3 -c "import tkinter as tk; print('tk', tk.TkVersion)"
```
- If multiple Pythons are installed, ensure uv/venv uses the one with tkinter available.
Linux
- Debian/Ubuntu:
```sh
sudo apt install python3-tk tk
```
- Fedora/RHEL:
```sh
sudo dnf install python3-tkinter tk
```
- Arch:
```sh
sudo pacman -S tk
```
- Some distros package tkinter separately; install both Python and the tkinter/Tk packages.
Windows
- The official Python installer from python.org includes tkinter by default.
- If you see "ModuleNotFoundError: _tkinter", re-run the installer and ensure âtcl/tk and IDLEâ is selected.
- Using MSYS2: install tk and Python via pacman to get tkinter support.
Notes
- Tkinter is not installed via pip; itâs part of the Python build and OS packages.
## Configuration
Default locations checked (first wins):
- `./.asciiquarium.toml`
- `~/.config/asciiquarium-redux/config.toml`
- `$XDG_CONFIG_HOME/asciiquarium-redux/config.toml`
Example `config.toml`:
```toml
[render]
fps = 24
color = "mono" # auto|mono|16|256
[scene]
density = 1.2 # 0.1..5.0
seed = 42 # or "random" (string) for non-deterministic
speed = 0.75 # 0.1..3.0 (lower = slower)
waterline_top = 5 # top row of waterline
chest_enabled = true # show treasure chest decor
chest_burst_seconds = 60.0 # seconds between lid bursts
[spawn]
# Initial delay range before the first special appears (seconds):
start_delay_min = 3.0
start_delay_max = 8.0
# Interval range between specials (seconds):
interval_min = 8.0
interval_max = 20.0
# Relative weights for random special spawns (0 disables a type):
[spawn.per_type] # optional per-type cooldowns in seconds
shark = 0.0
fishhook = 0.0
whale = 0.0
ship = 0.0
ducks = 0.0
dolphins = 0.0
swan = 0.0
monster = 0.0
big_fish = 0.0
[spawn]
max_concurrent = 1
cooldown_global = 0.0
[spawn.specials]
shark = 1.0
fishhook = 1.0
whale = 1.0
ship = 1.0
ducks = 1.0
dolphins = 1.0
swan = 1.0
monster = 1.0
big_fish = 1.0
# Optional extra scaling beyond density for counts
fish_scale = 1.0
seaweed_scale = 1.0
[fishhook]
dwell_seconds = 20.0
[fish]
direction_bias = 0.5 # 0..1 probability of rightward motion
speed_min = 0.6
speed_max = 2.5
bubble_min = 2.0
bubble_max = 5.0
# Turning behavior
turn_enabled = true
turn_chance_per_second = 0.01 # per-second chance (scaled by dt)
turn_min_interval = 6.0 # cooldown between turns (seconds)
turn_shrink_seconds = 0.35 # time to shrink to center
turn_expand_seconds = 0.35 # time to expand after flip
# y_band = [0.2, 0.9] # optional band (fractions of height)
# count_base = 6 # optional count override
# count_per_80_cols = 3.0
[seaweed]
sway_min = 0.18
sway_max = 0.5
lifetime_min = 25.0
lifetime_max = 60.0
regrow_delay_min = 4.0
regrow_delay_max = 12.0
growth_rate_min = 6.0
growth_rate_max = 12.0
shrink_rate_min = 8.0
shrink_rate_max = 16.0
# count_base = 4 # optional count override
# count_per_80_cols = 3.0
[ui]
backend = "terminal" # terminal|tk
fullscreen = false
cols = 120
rows = 40
font_family = "Menlo"
font_size = 14
font_min_size = 10 # lower bound for Tk auto font sizing
font_max_size = 22 # upper bound for Tk auto font sizing
font_auto = true # auto-resize font to fit scene; bounded by min/max
Tk auto font sizing notes
- When using the Tk backend with font_auto = true, the app adjusts the font size so that the minimal scene (waterline + water + castle + margin) fits vertically.
- The font size is recalculated on window resize and can grow or shrink, but it is always clamped between font_min_size and font_max_size to avoid unreadably small or comically large text.
- Very small windows: the app will shrink the font no smaller than font_min_size; if things still donât fit, some tall specials (e.g., big_fish) will be skipped until thereâs enough space.
```
Run with uvx without cloning the repo:
```sh
uvx asciiquarium-redux
```
Place a user config at one of the default paths above (e.g., `~/.config/asciiquarium-redux/config.toml`) to change spawn weights, timing, or scaling without modifying code.
You can also point to a specific config with `--config` (absolute or relative path). See `sample-config.toml` in the repo for a ready-to-edit template.
## Treasure chest (decor)
- Behavior
- Sits near the seabed (like the castle). Drawn in front of seaweed and behind fish, so fish swim in front of it.
- Emits occasional small bubbles while closed.
- On a periodic timer, the lid opens briefly and a stream of bubbles pops out, then it closes again.
- Configuration
- `scene.chest_enabled` (bool, default `true`): toggle the treasure chest on/off.
- `scene.chest_burst_seconds` (float, default `60.0`): seconds between lid openings.
## Fish turning
- Behavior
- Occasionally, a fish slows down while its body visually âcollapsesâ to a single center column, flips to the opposite direction, then expands back out and accelerates the other way.
- The center stays visually anchored during the animation to avoid popping.
- Controls
- Press `t` to force a random fish to turn immediately (handy to preview the effect).
- Configuration (under `[fish]`)
- `turn_enabled` (bool, default `true`)
- `turn_chance_per_second` (float, default `0.01`): random chance per second (scaled by frame time).
- `turn_min_interval` (float, default `6.0`): minimum seconds between turns per fish.
- `turn_shrink_seconds` (float, default `0.35`): time to shrink to the middle.
- `turn_expand_seconds` (float, default `0.35`): time to expand after flipping.
## Differences from the original
- Python 3 implementation
- Config file support and richer CLI options
- Deterministic mode for reproducible animations
- Terminal capability detection and graceful fallbacks
The goal remains fidelity to the original look-and-feel first, with extras opt-in.
## Development
Prereqs
- Python 3.11+ (3.13 recommended)
- [uv](https://github.com/astral-sh/uv) for env + builds (fast, zero-hassle)
- No Node required (web UI is static)
Setup
```sh
# Clone and enter the repo
git clone https://github.com/cognitivegears/asciiquarium_redux.git
cd asciiquarium_redux
# Create a local venv and install deps
uv sync
```
Run (terminal/Tk)
```sh
# Terminal backend
uv run python main.py
# Tk backend (windowed)
uv run python main.py --backend tk
```
Web development
```sh
# 1) Build a wheel (the browser installs the wheel)
uv build
# 2) Start the local web server (auto-copies latest wheel to web/wheels/)
uv run python -c "from asciiquarium_redux.web_server import serve_web; serve_web(port=8000, open_browser=True)"
# or
uv run python main.py --backend web --open
```
Dev loop tips (web)
- Changing Python code: `uv build`, then restart the web server so it refreshes `web/wheels/`. Hard-refresh the page to reinstall the wheel.
- Changing HTML/CSS/JS: just refresh the browser.
- The browser first tries the local wheel (when served locally); on GitHub Pages it installs from PyPI.
Config and CLI
```sh
# Example CLI flags
uv run python main.py --fps 30 --density 1.5 --seed 123
# Use a config file (see sample-config.toml)
uv run python main.py --config ./sample-config.toml
```
Deploy the web UI
- VS Code task: âDeploy web to GitHub Pagesâ (publishes `asciiquarium_redux/web/` to `gh-pages`).
- Or follow the manual commands in âDeploy to GitHub Pagesâ above.
Misc
- Key dep: `asciimatics`
- Entry points: `main.py` (CLI), `asciiquarium_redux/web_server.py` (local web serving)
- Optional sanity check:
```sh
uv run python devtools/verify_shark_evasion.py
```
## Recording a demo GIF (tips)
- macOS: `brew install ffmpeg` then use `asciinema` + `agg` or `ttygif`
- Keep background dark and font mono; target 20â30 FPS; limit palette if needed
## Troubleshooting
- Colors look wrong: try `--color mono` or use a 256-color/truecolor-capable terminal
- Misaligned art: ensure a monospaced font and disable ligatures
- High CPU: lower `--fps` or reduce density; try `ncurses` terminfo with fewer color changes
- Unicode issues: set `LANG`/`LC_ALL` to UTF-8 (e.g., `en_US.UTF-8`)
## Acknowledgements
- Original Asciiquarium by Kirk Baucom (Perl): [robobunny.com/projects/asciiquarium](https://robobunny.com/projects/asciiquarium/html/)
- Community contributors and testers who keep terminal art alive
## License
GPL-2.0-or-later to match the original Asciiquariumâs license. See [LICENSE](LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "asciiquarium-redux",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "aquarium, ascii-art, asciimatics, asciiquarium, terminal",
"author": "cognitivegears",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/de/32/2963a417e861927fe943774ce751ba4ee97622406f6258187eb47463171b/asciiquarium_redux-0.5.0.tar.gz",
"platform": null,
"description": "# Asciiquarium Redux \ud83d\udc20\n\n[](https://pypi.org/project/asciiquarium-redux/) [](https://cognitivegears.github.io/asciiquarium_redux/) [](https://www.python.org/downloads/) [](https://github.com/cognitivegears/asciiquarium_redux/actions/workflows/ci.yml) [](LICENSE)\n\nA joyful, colorful Python reimagining of the classic terminal aquarium. Watch fish swim, seaweed sway, hooks drop, sharks prowl, and bubbles pop\u2014right in your terminal or a windowed Tk screen.\n\nOriginal Asciiquarium by Kirk Baucom (Perl): [robobunny.com/projects/asciiquarium](https://robobunny.com/projects/asciiquarium/html/)\n\nStatus: Playable, configurable, and window-ready (Tk). Bring your own snacks (for the ducks).\n\n\ud83d\udc49 Try it in your browser (no install): [Live web version](https://cognitivegears.github.io/asciiquarium_redux/)\n\n\n\n## Why a Redux?\n\n- Keep the whimsical aquarium alive on modern terminals and platforms\n- Offer configurable FPS, colors, sizes, and deterministic playback (seeded RNG)\n- Ship as an installable Python package for easy use (e.g., `pipx install`)\n\n## Features\n\n- Faithful animations: fish (with color masks), seaweed lifecycle/sway, waterline, castle, bubbles, and many specials (shark, whale, ship, ducks, swan, dolphins, monster, big fish)\n- Decor: treasure chest that sits on the seabed, occasionally bubbles, and periodically opens to release a stream of bubbles (drawn behind fish)\n- Fishhook gameplay: one hook at a time, impact pause, configurable dwell time, collisions while lowering/dwelling/retracting\n- Smooth rendering: double-buffered terminal drawing to reduce flicker\n- Backends: terminal (asciimatics) and windowed Tk canvas (resizable, color)\n- Configurable everything: FPS, speed, density, spawn timings/weights, fish bands, colors; TOML-based config\n- Deterministic playback (seed) for captures and demos\n- Fish turning: fish can occasionally turn around with a smooth shrink/flip/expand animation (configurable)\n\n## \ud83d\udcda Documentation\n\n### Quick Start\n\n- **[Getting Started Guide](docs/DEVELOPER_GUIDE.md)** - Setup, installation, and first steps\n- **[Configuration Guide](docs/CONFIGURATION.md)** - Complete settings reference and customization\n- **[Backend Comparison](docs/BACKENDS.md)** - Terminal vs Web vs TkInter backends\n\n### Technical Reference\n\n- **[Architecture Overview](docs/ARCHITECTURE.md)** - System design and component relationships\n- **[API Reference](docs/API_REFERENCE.md)** - Public interfaces and usage examples\n- **[Entity System](docs/ENTITY_SYSTEM.md)** - Fish, seaweed, bubbles, and special entity details\n\n### Deployment & Advanced\n\n- **[Web Deployment](docs/WEB_DEPLOYMENT.md)** - Browser setup and GitHub Pages deployment\n- **[Sample Configuration](sample-config.toml)** - Example TOML configuration file\n\n## Quick start\n\nFrom source using uv (already configured in this repo):\n\n```sh\n# macOS/Linux\nuv run python main.py # terminal backend\n\n# Or use the repo venv directly\nsource .venv/bin/activate\npython main.py\n```\n\nInstall-free run from PyPI with uvx:\n\n```sh\n# Latest published version\nuvx asciiquarium-redux\n\n# Pass CLI flags to the app directly\nuvx asciiquarium-redux --fps 30 --density 1.2 --seed 123\n\n# Windowed Tk backend\nuvx asciiquarium-redux --backend tk\n\n# Refresh cached app to the newest release\nuvx --refresh asciiquarium-redux\n```\n\nRun with pipx:\n\n```sh\npipx install asciiquarium-redux\n\n# Run\nasciiquarium-redux\n\n# Tk backend\nasciiquarium-redux --backend tk\n\n# Upgrade later\npipx upgrade asciiquarium-redux\n```\n\nWindowed Tk backend:\n\n```sh\nuv run python main.py --backend tk\n```\n\n## Web mode (run in your browser)\n\nYou can run Asciiquarium Redux fully in the browser using Pyodide. The app starts a tiny local web server that serves a static page and installs the package into the browser runtime.\n\nLocal run (opens your default browser):\n\n```sh\n# From a clone\nuv run python main.py --backend web --open\n\n# Or via the installed CLI\nasciiquarium-redux --backend web --open\n\n# Choose a port (default 8000) and open manually if you prefer\nasciiquarium-redux --backend web --port 9000\n# Then visit http://127.0.0.1:9000/\n```\n\nNotes\n\n- The web page provides simple controls (FPS, speed, density, color, chest, turn, seed). Changes apply live.\n- Keyboard/mouse controls mirror the terminal/Tk versions: q, p, r, h, space, t; click to drop/retract the hook.\n- If you update Python code, the server copies the latest wheel into `web/wheels`. Hard refresh the page to pick up changes.\n- The browser installs the local wheel first; if not present, it falls back to PyPI.\n\n### Deploy to GitHub Pages\n\nYou can publish the web UI as a static site. The browser will install the package from PyPI at load time.\n\nOption A \u2014 one-click from VS Code\n\n1) Use the provided task: \u201cDeploy web to GitHub Pages\u201d. It creates (or overwrites) a `gh-pages` branch with the contents of `asciiquarium_redux/web/` and pushes it to `origin`.\n2) In your GitHub repo Settings \u2192 Pages, choose \u201cBranch: gh-pages / root\u201d.\n3) Visit <https://USERNAME.github.io/REPO/>\n\nOption B \u2014 manual commands (equivalent)\n\n```sh\n# From the repo root\nset -euo pipefail\ntmp=$(mktemp -d)\nrsync -a --delete asciiquarium_redux/web/ \"$tmp/\"\ncp -f \"$tmp/index.html\" \"$tmp/404.html\" || true\norigin=$(git remote get-url origin)\ngit -C \"$tmp\" init\ngit -C \"$tmp\" checkout -b gh-pages\ngit -C \"$tmp\" add .\ngit -C \"$tmp\" -c user.name='gh-pages' -c user.email='gh-pages@local' commit -m 'Deploy web to GitHub Pages'\ngit -C \"$tmp\" remote add origin \"$origin\"\ngit -C \"$tmp\" push --force origin gh-pages\n```\n\nTips\n\n- Paths in `index.html` are relative, so project pages (`/your-repo/`) work without changes.\n- If the page can\u2019t install the package in the browser, ensure the latest version on PyPI includes the web backend.\n- For custom forks, publishing your own release to PyPI ensures the web UI can install cleanly from Pages.\n\nControls:\n\n- q: quit\n- p: pause/resume\n- r: rebuild scene (useful after resize)\n- h or ?: toggle help overlay\n- space: drop/retract fishhook (random position in terminal)\n- mouse: left-click to drop a hook at the cursor (or retract if one is active)\n- s (Tk): save a screenshot as ./asciiquarium_#.png (auto-incrementing)\n- t: force a random fish to turn (useful to preview the turning animation)\n- f: feed fish (spawns floating flakes fish will seek and eat)\n\nCLI examples:\n\n```sh\nuv run python main.py --fps 30 --density 1.5 --color mono --seed 123 --speed 0.7\n# Use a specific config file\nuv run python main.py --config ./sample-config.toml\nuv run python main.py --backend tk --fullscreen\n```\n\nCommon flags:\n\n- --fps (int): target frames per second (default 24, clamp 5\u2013120)\n- --density (float): density multiplier (default 1.0, clamp 0.1\u20135.0)\n- --color <auto|mono|16|256>: color mode (mono forces white)\n- --seed (int): deterministic RNG seed; omit for random\n- --speed (float): global speed multiplier (default 0.75)\n- --backend <terminal|tk>: choose backend\n- --fullscreen: make Tk window fullscreen\n- --font-min (int): minimum Tk font size bound for auto-resize\n- --font-max (int): maximum Tk font size bound for auto-resize\n- --ai / --no-ai: enable or disable Utility AI behaviors\n- --port (int): web server port for web backend\n\n## Notes\n\n- Terminal uses `asciimatics`; Tk backend renders to a Canvas with per-cell text.\n- Tk resizes by adjusting the character grid to the window size; the scene rebuilds when size stabilizes.\n- When Tk font_auto is enabled, font size auto-fits within [font_min_size, font_max_size] so the castle fits; sliders clamp min<=max.\n- Ensure a UTF-8 locale and a monospaced font for best results.\n\nBehavior highlights\n\n- Fish can drift vertically (bounded by fish.vertical_speed_max; default 2.0 rows/sec) while keeping mostly horizontal motion.\n- Utility AI (when enabled) prioritizes eating fish food; when very hungry and no food is available, larger fish may prey on strictly smaller fish.\n- Predation creates a brief splat effect; prey are immediately respawned to maintain population.\n- If fish counts remain low for a while, restocking gently replenishes the population.\n\n## Tk backend requirements (Tkinter)\n\nThis is only needed if you want to use the Tk backend (`--backend tk`). If tk is not available, the app will fall back to the terminal backend.\n\nThe Tk backend needs Python built with tkinter and the system Tk libraries. If Tk isn\u2019t available, the app automatically falls back to the terminal backend.\n\nQuick test:\n\n```sh\npython -c \"import tkinter as tk; print('tk', tk.TkVersion)\"\n```\n\nmacOS\n\n- Recommended: Install Python from python.org (bundles a compatible Tcl/Tk).\n- Homebrew (brew):\n\n```sh\nbrew install python tcl-tk\npython3 -c \"import tkinter as tk; print('tk', tk.TkVersion)\"\n```\n\n- If multiple Pythons are installed, ensure uv/venv uses the one with tkinter available.\n\nLinux\n\n- Debian/Ubuntu:\n\n```sh\nsudo apt install python3-tk tk\n```\n\n- Fedora/RHEL:\n\n```sh\nsudo dnf install python3-tkinter tk\n```\n\n- Arch:\n\n```sh\nsudo pacman -S tk\n```\n\n- Some distros package tkinter separately; install both Python and the tkinter/Tk packages.\n\nWindows\n\n- The official Python installer from python.org includes tkinter by default.\n- If you see \"ModuleNotFoundError: _tkinter\", re-run the installer and ensure \u201ctcl/tk and IDLE\u201d is selected.\n- Using MSYS2: install tk and Python via pacman to get tkinter support.\n\nNotes\n\n- Tkinter is not installed via pip; it\u2019s part of the Python build and OS packages.\n\n## Configuration\n\nDefault locations checked (first wins):\n\n- `./.asciiquarium.toml`\n- `~/.config/asciiquarium-redux/config.toml`\n- `$XDG_CONFIG_HOME/asciiquarium-redux/config.toml`\n\nExample `config.toml`:\n\n```toml\n[render]\nfps = 24\ncolor = \"mono\" # auto|mono|16|256\n\n[scene]\ndensity = 1.2 # 0.1..5.0\nseed = 42 # or \"random\" (string) for non-deterministic\nspeed = 0.75 # 0.1..3.0 (lower = slower)\nwaterline_top = 5 # top row of waterline\nchest_enabled = true # show treasure chest decor\nchest_burst_seconds = 60.0 # seconds between lid bursts\n\n[spawn]\n# Initial delay range before the first special appears (seconds):\nstart_delay_min = 3.0\nstart_delay_max = 8.0\n# Interval range between specials (seconds):\ninterval_min = 8.0\ninterval_max = 20.0\n# Relative weights for random special spawns (0 disables a type):\n[spawn.per_type] # optional per-type cooldowns in seconds\nshark = 0.0\nfishhook = 0.0\nwhale = 0.0\nship = 0.0\nducks = 0.0\ndolphins = 0.0\nswan = 0.0\nmonster = 0.0\nbig_fish = 0.0\n[spawn]\nmax_concurrent = 1\ncooldown_global = 0.0\n[spawn.specials]\nshark = 1.0\nfishhook = 1.0\nwhale = 1.0\nship = 1.0\nducks = 1.0\ndolphins = 1.0\nswan = 1.0\nmonster = 1.0\nbig_fish = 1.0\n# Optional extra scaling beyond density for counts\nfish_scale = 1.0\nseaweed_scale = 1.0\n\n[fishhook]\ndwell_seconds = 20.0\n\n[fish]\ndirection_bias = 0.5 # 0..1 probability of rightward motion\nspeed_min = 0.6\nspeed_max = 2.5\nbubble_min = 2.0\nbubble_max = 5.0\n# Turning behavior\nturn_enabled = true\nturn_chance_per_second = 0.01 # per-second chance (scaled by dt)\nturn_min_interval = 6.0 # cooldown between turns (seconds)\nturn_shrink_seconds = 0.35 # time to shrink to center\nturn_expand_seconds = 0.35 # time to expand after flip\n# y_band = [0.2, 0.9] # optional band (fractions of height)\n# count_base = 6 # optional count override\n# count_per_80_cols = 3.0\n\n[seaweed]\nsway_min = 0.18\nsway_max = 0.5\nlifetime_min = 25.0\nlifetime_max = 60.0\nregrow_delay_min = 4.0\nregrow_delay_max = 12.0\ngrowth_rate_min = 6.0\ngrowth_rate_max = 12.0\nshrink_rate_min = 8.0\nshrink_rate_max = 16.0\n# count_base = 4 # optional count override\n# count_per_80_cols = 3.0\n\n[ui]\nbackend = \"terminal\" # terminal|tk\nfullscreen = false\ncols = 120\nrows = 40\nfont_family = \"Menlo\"\nfont_size = 14\nfont_min_size = 10 # lower bound for Tk auto font sizing\nfont_max_size = 22 # upper bound for Tk auto font sizing\nfont_auto = true # auto-resize font to fit scene; bounded by min/max\n\nTk auto font sizing notes\n\n- When using the Tk backend with font_auto = true, the app adjusts the font size so that the minimal scene (waterline + water + castle + margin) fits vertically.\n- The font size is recalculated on window resize and can grow or shrink, but it is always clamped between font_min_size and font_max_size to avoid unreadably small or comically large text.\n- Very small windows: the app will shrink the font no smaller than font_min_size; if things still don\u2019t fit, some tall specials (e.g., big_fish) will be skipped until there\u2019s enough space.\n```\n\nRun with uvx without cloning the repo:\n\n```sh\nuvx asciiquarium-redux\n```\n\nPlace a user config at one of the default paths above (e.g., `~/.config/asciiquarium-redux/config.toml`) to change spawn weights, timing, or scaling without modifying code.\n\nYou can also point to a specific config with `--config` (absolute or relative path). See `sample-config.toml` in the repo for a ready-to-edit template.\n\n## Treasure chest (decor)\n\n- Behavior\n - Sits near the seabed (like the castle). Drawn in front of seaweed and behind fish, so fish swim in front of it.\n - Emits occasional small bubbles while closed.\n - On a periodic timer, the lid opens briefly and a stream of bubbles pops out, then it closes again.\n- Configuration\n - `scene.chest_enabled` (bool, default `true`): toggle the treasure chest on/off.\n - `scene.chest_burst_seconds` (float, default `60.0`): seconds between lid openings.\n\n## Fish turning\n\n- Behavior\n - Occasionally, a fish slows down while its body visually \u201ccollapses\u201d to a single center column, flips to the opposite direction, then expands back out and accelerates the other way.\n - The center stays visually anchored during the animation to avoid popping.\n- Controls\n - Press `t` to force a random fish to turn immediately (handy to preview the effect).\n- Configuration (under `[fish]`)\n - `turn_enabled` (bool, default `true`)\n - `turn_chance_per_second` (float, default `0.01`): random chance per second (scaled by frame time).\n - `turn_min_interval` (float, default `6.0`): minimum seconds between turns per fish.\n - `turn_shrink_seconds` (float, default `0.35`): time to shrink to the middle.\n - `turn_expand_seconds` (float, default `0.35`): time to expand after flipping.\n\n## Differences from the original\n\n- Python 3 implementation\n- Config file support and richer CLI options\n- Deterministic mode for reproducible animations\n- Terminal capability detection and graceful fallbacks\n\nThe goal remains fidelity to the original look-and-feel first, with extras opt-in.\n\n## Development\n\nPrereqs\n\n- Python 3.11+ (3.13 recommended)\n- [uv](https://github.com/astral-sh/uv) for env + builds (fast, zero-hassle)\n- No Node required (web UI is static)\n\nSetup\n\n```sh\n# Clone and enter the repo\ngit clone https://github.com/cognitivegears/asciiquarium_redux.git\ncd asciiquarium_redux\n\n# Create a local venv and install deps\nuv sync\n```\n\nRun (terminal/Tk)\n\n```sh\n# Terminal backend\nuv run python main.py\n\n# Tk backend (windowed)\nuv run python main.py --backend tk\n```\n\nWeb development\n\n```sh\n# 1) Build a wheel (the browser installs the wheel)\nuv build\n\n# 2) Start the local web server (auto-copies latest wheel to web/wheels/)\nuv run python -c \"from asciiquarium_redux.web_server import serve_web; serve_web(port=8000, open_browser=True)\"\n# or\nuv run python main.py --backend web --open\n```\n\nDev loop tips (web)\n\n- Changing Python code: `uv build`, then restart the web server so it refreshes `web/wheels/`. Hard-refresh the page to reinstall the wheel.\n- Changing HTML/CSS/JS: just refresh the browser.\n- The browser first tries the local wheel (when served locally); on GitHub Pages it installs from PyPI.\n\nConfig and CLI\n\n```sh\n# Example CLI flags\nuv run python main.py --fps 30 --density 1.5 --seed 123\n\n# Use a config file (see sample-config.toml)\nuv run python main.py --config ./sample-config.toml\n```\n\nDeploy the web UI\n\n- VS Code task: \u201cDeploy web to GitHub Pages\u201d (publishes `asciiquarium_redux/web/` to `gh-pages`).\n- Or follow the manual commands in \u201cDeploy to GitHub Pages\u201d above.\n\nMisc\n\n- Key dep: `asciimatics`\n- Entry points: `main.py` (CLI), `asciiquarium_redux/web_server.py` (local web serving)\n- Optional sanity check:\n\n```sh\nuv run python devtools/verify_shark_evasion.py\n```\n\n## Recording a demo GIF (tips)\n\n- macOS: `brew install ffmpeg` then use `asciinema` + `agg` or `ttygif`\n- Keep background dark and font mono; target 20\u201330 FPS; limit palette if needed\n\n## Troubleshooting\n\n- Colors look wrong: try `--color mono` or use a 256-color/truecolor-capable terminal\n- Misaligned art: ensure a monospaced font and disable ligatures\n- High CPU: lower `--fps` or reduce density; try `ncurses` terminfo with fewer color changes\n- Unicode issues: set `LANG`/`LC_ALL` to UTF-8 (e.g., `en_US.UTF-8`)\n\n## Acknowledgements\n\n- Original Asciiquarium by Kirk Baucom (Perl): [robobunny.com/projects/asciiquarium](https://robobunny.com/projects/asciiquarium/html/)\n- Community contributors and testers who keep terminal art alive\n\n## License\n\nGPL-2.0-or-later to match the original Asciiquarium\u2019s license. See [LICENSE](LICENSE).\n",
"bugtrack_url": null,
"license": "GPL-2.0-or-later",
"summary": "A Python port of Asciiquarium with asciimatics",
"version": "0.5.0",
"project_urls": {
"Homepage": "https://github.com/cognitivegears/asciiquarium_redux",
"Issues": "https://github.com/cognitivegears/asciiquarium_redux/issues",
"Source": "https://github.com/cognitivegears/asciiquarium_redux"
},
"split_keywords": [
"aquarium",
" ascii-art",
" asciimatics",
" asciiquarium",
" terminal"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7a30fda3fa0e33b7603d9708f9059b92c2f9e974f8d2dda6563c25c837b7122f",
"md5": "0745a0463b78dffdd0a55aa78c10ca59",
"sha256": "34fd599162b46c21eca9e288d4d140def1230ccb6c0747fff200684f7f3f8056"
},
"downloads": -1,
"filename": "asciiquarium_redux-0.5.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0745a0463b78dffdd0a55aa78c10ca59",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 149219,
"upload_time": "2025-08-19T01:33:18",
"upload_time_iso_8601": "2025-08-19T01:33:18.313323Z",
"url": "https://files.pythonhosted.org/packages/7a/30/fda3fa0e33b7603d9708f9059b92c2f9e974f8d2dda6563c25c837b7122f/asciiquarium_redux-0.5.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "de322963a417e861927fe943774ce751ba4ee97622406f6258187eb47463171b",
"md5": "78dbf1d776aca8ca546227d8a943ffbf",
"sha256": "d55946777311199330ff87339f249fef525215345f233cd325c56a0082c32250"
},
"downloads": -1,
"filename": "asciiquarium_redux-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "78dbf1d776aca8ca546227d8a943ffbf",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 108163,
"upload_time": "2025-08-19T01:33:19",
"upload_time_iso_8601": "2025-08-19T01:33:19.830358Z",
"url": "https://files.pythonhosted.org/packages/de/32/2963a417e861927fe943774ce751ba4ee97622406f6258187eb47463171b/asciiquarium_redux-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-19 01:33:19",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cognitivegears",
"github_project": "asciiquarium_redux",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "asciiquarium-redux"
}