Skip to content

Harbour Kit v1 - First Playable Slice

The smallest proof that CaptainsWorld works as a world, not an activity screen

Architecture for this slice

CaptainsWorld SDK (learning / story / mission / visual engines)
        ↓ compiled mission scene JSON
Godot Renderer (movement, tilemap, props, FX, UI shell)

Not: everything inside Godot. Godot draws and handles input only.


Milestone 0 — Walk to the bottle

Proves: top-down map + captain + interactable object.

Map

Tiny 12×10 tile test map:

  • sand shore (bottom)
  • water (top/sides)
  • small dock strip (3×2 tiles)

Assets (6 only)

water_tile_base
sand_tile_base
dock_tile_base
captain_idle_down
message_bottle
sparkle_indicator

Player experience

  1. Captain spawns on sand
  2. Sparkle on bottle at shore edge
  3. Child walks captain to bottle (4-dir movement; walk cycle can be placeholder slide for M0)
  4. Interact → bottle picked up (pop FX optional)

Done when

  • [ ] Godot project runs locally
  • [ ] Tilemap renders at 48×48
  • [ ] Captain moves with keyboard/touch
  • [ ] Bottle interaction triggers once

Do not add Fisherman until M0 passes.


Milestone 1 — First full loop

Proves: Explore → Discover → Read → Meet → Help → Transform → Continue

Player experience

  1. Pick up bottle on shore
  2. Read short message (scroll UI)
  3. Walk to Fisherman on pier
  4. Talk → missing-letter net repair ([[Mission UI Modes#UI Mode 1: Focus Object Mode]])
  5. Net: broken → repaired + stitch/sparkle FX
  6. Fisherman happy state + continue prompt

P0 asset list

# Terrain (M0 + edges minimal)
water_tile_base
sand_tile_base
dock_tile_base

# Captain
captain_idle_down
captain_idle_up
captain_idle_left
captain_idle_right
captain_walk_* (placeholder OK — 1 frame per direction)

# Bottle / story
message_bottle
scroll_open
sparkle_indicator

# Fisherman
fisherman_idle
fisherman_talk
fisherman_worried
fisherman_point
fisherman_happy

# Mission prop
fishing_net_broken
fishing_net_repaired

# UI
dialogue_box_base
letter_tile_base
word_slot_empty

# FX
letter_fly_to_target
stitch_line
sparkle_success
wrong_wobble

Mission data (example)

{
  "location": "harbour_pier",
  "npc": "fisherman",
  "verb": "repair",
  "learningSkill": "missing_letter",
  "visualPattern": "repair_object",
  "uiMode": "focus_object",
  "missionProp": "fishing_net",
  "propState": "broken",
  "successState": "repaired",
  "fx": ["letter_fly_to_target", "stitch_line", "sparkle_success"]
}

Done when

  • [ ] Full loop completable without developer cheats
  • [ ] Wrong answer shows calm wobble, not punishment
  • [ ] Net state persists after mission complete
  • [ ] One child playtest captured in 99 Decisions/

Out of scope (M1)

  • Harbour Master, market, cargo
  • Lighthouse, whale bay, fog route
  • Learning engine adaptive selection (fixed word OK)
  • Numbers missions
  • Mobile export
  • Captain uniform

Godot project structure (target)

captainsworld-godot/          # separate repo or /prototypes/harbour-godot/
├── scenes/
│   ├── harbour_m0.tscn
│   └── harbour_m1.tscn
├── assets/harbour-kit/       # synced from public/assets/world/harbour-kit/
├── scripts/
│   ├── player.gd
│   └── mission_runner.gd     # consumes SDK JSON — stub OK for M1
└── project.godot

Immediate next action

  1. Generate 6 M0 assets (Harbour Kit v1 - AI Asset Prompts)
  2. Clean + import (Harbour Kit v1 - Production Workflow)
  3. Paste Cursor Build Prompt - First Playable Slice into Cursor for Godot scaffold