Skip to content

Latest commit

Β 

History

History
143 lines (121 loc) Β· 7.57 KB

README.md

File metadata and controls

143 lines (121 loc) Β· 7.57 KB

Nethook 🎣

A NetHack-style ASCII fishing roguelike to play in a second terminal window while Claude Code is busy. When Claude finishes, the game pings you to reel in.

  🎣 NETHOOK β€” Lake Taupō   🌧rain Β· autumn Β· πŸŒ†dusk Β· 12Β°C Β· πŸŒ•feeding

  ...........~~~~~~..........
  ........~~~~β‰ˆβ‰ˆβ‰ˆβ‰ˆ~~~~,......
  ......~~β‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆ~~"......
  =@~~β‰ˆβ‰ˆβ‰ˆβ‰ˆ F β‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆ~~......
  ......~~β‰ˆβ‰ˆβ‰ˆβ‰ˆβ‰ˆ# β‰ˆβ‰ˆβ‰ˆβ‰ˆ~~......
  ......$..~~~~β‰ˆβ‰ˆβ‰ˆ~~~~.......

  β—‹ Land a trophy catch (+35c)   βœ” Log a new species (+25c)
  πŸ† TROPHY Rainbow Trout β€” 3.1kg, grade S!  +186 pts

  β˜€ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘  🎣Heirloom Rod  πŸͺ±Spinner Lure  β—Ž240c  β˜…186   βœ… Claude ready β€” reel in!
  move: hjkl/arrows Β· f+dir: cast Β· $: shanty Β· q: quit

Why

The spinner-stare while Claude works is dead time. Nethook fills it with a quick, glanceable fishing roguelike β€” and tells you the moment Claude is done.

A plugin can't render a live game inside Claude Code's own terminal (Claude owns that TTY), so Nethook runs as a standalone game in its own window. That's the authentic roguelike model anyway.

Requirements

  • Claude Code (the CLI) β€” to install it as a plugin.
  • Node.js β‰₯ 18 β€” the game is plain Node, zero dependencies.
  • A real terminal you can open a second window/tab/pane in (the game runs in its own window β€” see Why). Works on macOS, Linux, WSL, and Windows Terminal.

Install & play (as a Claude Code plugin)

Run these two slash commands inside Claude Code β€” no build, no npm install, no marketplace approval needed:

/plugin marketplace add ClickClickMedia/Nethook   # 1. register this repo's marketplace
/plugin install nethook@nethook                    # 2. install the plugin (name@marketplace)

That's it. Now, any time Claude is busy and you want something to do:

/gofish                  # opens Nethook in a NEW terminal window
/gofish "Lake Taupō"     # …or jump straight into a specific spot
  • If /gofish can't auto-open a window (headless or an unrecognised terminal) it prints a copy-paste command instead β€” paste it into any separate tab/pane.
  • /nethook:spot "<real place>" has Claude generate a playable Spot Pack for a real location (ASCII map, real species, real tackle, real strategy) and installs it; then /gofish "<place>".

While Claude works, a Stop hook flips the game's status bar to "βœ… Claude ready β€” reel in!" (with a terminal bell), and a PreToolUse hook nudges you to go fish when Claude kicks off a long command (once per session).

To update later: /plugin marketplace update nethook then re-run /plugin install nethook@nethook. To remove it: /plugin uninstall nethook@nethook.

Run it directly (without the plugin)

You don't need Claude Code to play β€” clone and run:

git clone https://github.com/ClickClickMedia/Nethook && cd Nethook
node game/index.mjs                 # play the procedural lake
node game/index.mjs "Lake Taupō"    # …or a named built-in spot

(The plugin's only extra is the /gofish window-launcher and the Claude-ready status handshake; the game itself is the same.)

Gameplay

  • Move with hjkl or arrows; you walk the shore/dock (@).
  • Fish: press f then a direction to cast at adjacent water. On a bite, a reel fight begins β€” r to reel, e to ease. Keep tension in the safe band: let it hit 100% and the line snaps, but let it sit too low and the line goes slack until the hook slips β€” so you can't just coast. Fights come in three flavours (rarer fish pick the nastier ones): a steady haul, a runner that bolts in bursts (ease while it runs, reel when slack), and a pendulum where you reel only while the sweeping lure sits in the green zone.
  • Water: shallow ~, deep β‰ˆ, reeds ", lilypads ,, rocks # (no fish). Different species favour different depths.
  • Shanty ($): spend coins on better rods and bait to unlock deeper water and rarer fish, or deploy a πŸ¦€ crab pot. Gear and coins persist.
  • Crab pot (idle): once deployed, it accrues a little catch in real time while you're away and pays out the next time you launch β€” but the haul decays Fresh β†’ Stale β†’ Rotting if you leave it too long, so check in regularly. Upgrade it at the shanty (Mk 1 β†’ 2 β†’ …) for bigger hauls β€” a late-game coin sink.
  • Complete the logbook: catch every (non-junk) species at a spot and you earn the Golden Rod β€” the best rod in the game, granted once and kept for good.
  • Trips: each launch is one bounded daylight session; at dusk it scores.
  • Bounties: every trip rolls two goals (land a trophy, log a new species, hook an aberration…) that pay a coin + score bonus β€” a fresh objective each launch.
  • Grades & trophies: every catch is graded Fβ†’SSS by how big it is for its species. A top-of-range specimen (or a rare gold strike) lands a πŸ† trophy worth a value bonus β€” the logbook remembers your best grade and trophy count.
  • Aberrations: now and then β€” mostly at dusk or in fog β€” something wrong takes the hook. πŸœ‚ Aberrant variants fight harder and pay far more.
  • Logbook (persistent): species dex, biggest catches, best grades, trophies, totals, best score β€” saved under $XDG_DATA_HOME/nethook (or ~/.local/share/nethook).

Spot Packs

A Spot Pack is JSON describing a real location: an optional ASCII map, a species table with real behaviour, tackle, and strategy. Three ship built-in (game/packs/): Lake Taupō, The Everglades, Lofoten Fjord. Generate more with /nethook:spot. The engine validates every pack (game/pack.mjs) so a bad one can never crash the game; with no pack it builds a procedural lake.

Environment gating: each trip rolls a season and weather, and the day-phase moves with the daylight clock (dawn β†’ day β†’ dusk). Species can gate themselves by time, season, weather, and preferred bait, so a spot plays differently trip to trip β€” the skrei cod run shows up in winter, the kraken only at foggy dusk. Dawn/dusk and rain bite better. Gates are sanitized on load, never trusted.

Grounded bite model (optional realism): a species can declare a water-temp preference (tempOptimum / tempRange Β°C); the engine derives the trip's water temperature from the season around the spot's annual mean (hints.baseTemp), so cold-water fish fade in a summer heatwave. The bite also follows solunar feeding β€” computed in-engine from the moon phase on the trip's real date (no API, no network) β€” strongest around the new and full moon. The header shows the trip's Β°C and a πŸŒ‘πŸŒ“πŸŒ• feeding indicator.

Development

Zero runtime dependencies (pure Node + ANSI). The game core is split so it's testable without a TTY:

npm test        # node game/selftest.mjs β€” 110 assertions over the pure core
node game/launch.mjs --dry-run      # show the window-spawn plan for your env
node game/packcheck.mjs <pack.json> # validate a Spot Pack

game/core.mjs, world.mjs, render.mjs, pack.mjs, logbook.mjs are pure; game/index.mjs is the only file that touches the terminal.

Testing & contributing

Trying it out? See TESTING.md for what to look for and how to report. Want to add a Spot Pack, a species, or a fix? CONTRIBUTING.md has the dev setup and the one rule that matters (keep the core pure). PRs welcome β€” new real-world Spot Packs especially. MIT licensed.