Daily Vibe Challenge

A new AI vibe-coding challenge every day

Daily AI vibe-coding challenges with copy-paste starter prompts for Claude Code, Cursor, Replit Agent and Lovable.

Get it daily by email — free  Submit a build

Latest challenge · #005 · 2026-10-15

The Lighthouse Keeper: A Text Adventure with an Agent NPC

Intermediate2–4 hoursText adventures with agents

Build a small parser text adventure set in a storm-battered lighthouse where the one character you meet, the old keeper, is an LLM agent. The twist: the game engine owns the truth. The keeper can only change the world through a few typed tools (give an item, unlock a door, reveal a clue), so the conversation feels free-form while the puzzle stays fair, winnable and impossible to talk your way around.

Build "The Lighthouse Keeper", a short browser text adventure with one LLM-powered NPC. Use a single index.html plus engine.js and keeper.js, vanilla JS, no build step. The game must also run with NO API key using a scripted fallback keeper (see below).

World and engine (engine.js, fully deterministic, the single source of truth):
- 6 rooms: Shore, Keeper's Cottage, Lighthouse Base, Spiral Stairs, Lamp Room, Cellar. Each room has a description, exits and items.
- Items: lantern, oil can, brass key, logbook, matches, fuse. Inventory limit of 4.
- Parser verbs: look, go <dir>/n/s/e/w/up/down, take, drop, use <item> [on <thing>], inventory, talk <message> (or say "..."), help. Unknown input gets a helpful hint, never a crash.
- Goal: relight the lamp before the ship offshore runs aground. A turn counter (40 turns) is the storm clock; show it in the status bar.
- Puzzle chain: the Cellar is locked (brass key), the lamp needs oil + a fuse + matches, and the fuse's location is only written in the logbook, which the keeper holds.

The keeper agent (keeper.js):
- The player talks to the keeper with "talk ..." when in the Cottage. Send the LLM a system prompt with his persona (gruff, superstitious, secretly kind), the current visible game state, the last 8 exchanges, and a strict tool list:
  give_item(item), unlock(door), reveal_clue(clue_id), refuse(reason).
- Ask the model for JSON: {"say": "...", "tool_calls": [{"name": "...", "args": {...}}]}. Validate every call against the engine: he can only give items he actually holds, only unlock doors he has keys for, and only reveal clues from a fixed list (clue ids: "fuse_location", "cellar_key", "storm_lore"). Rejected calls are dropped and logged, never applied.
- Conditions the engine enforces (not the model): he hands over the logbook only after the player brings him the lantern, and gives the brass key only after the player asks about the cellar. The model can decide WHEN and HOW he says it, not whether the rules apply.
- Config: an API key field stored in localStorage and an OpenAI-compatible endpoint + model name field. Handle errors and timeouts by falling back to the scripted keeper for that turn.
- Scripted fallback: keyword matching (cellar, key, lantern, logbook, fuse, storm, ship) with a few canned lines per topic that call the same tools, so the game is fully completable offline.

UI:
- Dark terminal look: scrolling transcript, input line with command history (Up/Down arrows), status bar with room, turns left and inventory.
- Keeper lines in a different color. A "Debug" toggle shows the raw JSON from the model and any rejected tool calls.
- Save/load to localStorage; a "New game" button.

When done, explain how the engine/agent boundary works, list the tool validation rules, and give a walkthrough that wins in under 30 turns.

Open full challenge →

Recent challenges

Full archive →

⚡ Get tomorrow's challenge before everyone else

One fresh challenge + copy-paste starter prompt in your inbox every morning, plus a weekly roundup of the best community builds. Free, no spam, unsubscribe in one click.

Or follow on Bluesky · RSS/Atom · Newsletter archive