Pomodoro · Island builder · Streaks · Crew · Sealed saves · PWA · Docker
A deep-work game for desktop and phone: complete timed focus quests, earn crystals & energy, place and upgrade structures on a floating island, and come back tomorrow for streak bonuses.
No backend · No account · Progress lives in your browser
Author: ArdaDDemir · Repo: floating-observatory · Wiki
Most Pomodoro timers are a countdown and a beep.
Floating Observatory turns focus into a place you maintain:
| Loop | What happens |
|---|---|
| Focus | Start 5–60m quests (or custom). Ambient events drip small rewards mid-session. |
| Build | Spend crystals & energy on towers, labs, shields, signal dishes. |
| Return | Daily goals grow streaks. Miss a day → soft comeback gift. Fail → penalty, not a wipe. |
Built as a portfolio-ready web game: polished UI, mobile shell, offline PWA, and clean code you can fork.
|
|
|
|
All audio is generated at runtime with the Web Audio API — no MP3/WAV assets, no third-party packs.
| Area | Examples |
|---|---|
| Session | Start, pause, resume, complete, daily goal, fail, lockout |
| Focus | Event loot / flavor, minute tick, halfway, final stretch |
| Island | Place, upgrade, destroy, relocate, build mode on/off |
| Crew | Select NPC, assign post, new recruit join |
| UI / meta | Research, achievement, toggles, export/import, meteor |
Toggle in Settings → Sound cues (on by default).
Requirements: Node.js 20+ recommended, npm 10+
git clone https://github.com/ArdaDDemir/floating-observatory.git
cd floating-observatory
# install
npm install
# develop
npm run dev# production (enables service worker / offline shell)
npm run build
npm start# build + run on http://localhost:3000
docker compose up --buildOr without Compose:
docker build -t floating-observatory .
docker run --rm -p 3000:3000 floating-observatoryProduction image uses Next.js output: "standalone" when DOCKER_BUILD=1 (see Dockerfile).
Forks the repo into your account and deploys. No env vars required (client-only game).
| Platform | Button |
|---|---|
| Vercel | |
| Netlify | |
| Railway | |
| Render |
Direct links (if a badge fails to load):
Self-host with Docker above, or any host that runs npm run build && npm start (Node 20+).
| Input | Action |
|---|---|
| Space | Pause / resume focus |
| B | Toggle build mode (place tray) |
| M | Open Lab (meta) |
| Z | Zen mode |
| Esc | Close panels / clear selection |
| Click building | Open upgrade / manage card |
| Click NPC | Assign crew to a building post |
| Touch | 1 finger orbit · 2 finger zoom · tap to place / select |
src/
├── app/ # Next.js App Router (layout, PWA icons, manifest)
├── components/
│ ├── Scene.tsx # R3F canvas, island, lights, orbit
│ ├── GameHUD.tsx # Main UI: timer, build, resources
│ ├── buildings/ # Per-type 3D models
│ └── …panels # Settings, Lab, Guide, Stats
├── store/useGameStore.ts# Game state, economy actions, persist
├── lib/
│ ├── gameConfig.ts # Costs, rewards, fail math ← tweak economy
│ ├── meta.ts # Streaks, research, achievements
│ ├── events.ts # Ambient focus events
│ ├── crew.ts # Crew roles & buffs
│ ├── save.ts # Sealed save v3 + hash
│ └── perf.ts # Graphics profile / mobile scale
├── hooks/ # Mobile, wake lock, graphics, hotkeys
public/
├── sw.js # Offline shell service worker
└── offline.html
| Doc | What’s inside |
|---|---|
| GitHub Wiki | Play guide, buildings, crew, sound, Docker, FAQ |
| docs/GUIDE.md | Player-facing systems overview |
| docs/CUSTOMIZING.md | Change economy, buildings, events, branding |
| docs/ARCHITECTURE.md | Data flow, save seal, render pipeline |
| docs/DOCKER.md | Docker / Compose |
| CONTRIBUTING.md | Local workflow & PR notes |
Wiki source lives in wiki/ — publish with pwsh scripts/push-wiki.ps1 after the first wiki page exists on GitHub.
- Next.js 16 App Router · React 19
- React Three Fiber + Drei + postprocessing
- Zustand + persist (sealed)
- Framer Motion · Tailwind CSS 4 · Lucide icons
Note: this repo’s Next version may differ from older tutorials. Prefer the docs under
node_modules/next/dist/docs/when extending framework APIs.
// src/lib/gameConfig.ts
export const STARTING_CRYSTALS = 150;
export const STARTING_ENERGY = 150;
// Rewards ≈ minutes × 1.05 (see rewardsForDuration)
// Building costs live in BUILDINGS record// src/lib/meta.ts — streak multipliers, research costs, daily goal default
export function streakRewardMultiplier(currentStreak: number) { … }Full map of knobs: docs/CUSTOMIZING.md
Real captures from the running app (Playwright · regenerate with npm run screenshots).
Idle hub — resources, streak, tags, duration presets, full 3D island
| Focus session | Build mode |
|---|---|
![]() |
![]() |
| Building picker detail | Field manual |
|---|---|
![]() |
![]() |
| Lab research | Paused session |
|---|---|
![]() |
![]() |
| Island (compact chrome) | Quest sheet |
|---|---|
![]() |
![]() |
| Focus timer | Settings (bottom sheet) |
|---|---|
![]() |
![]() |
Five placeable structures appear on the island and in the build tray:
| Building | Role |
|---|---|
| Energy Core | +% energy from sessions |
| Data Tower | +% crystals from sessions |
| Botany Lab | Dual small bonus |
| Shield Gen | Softens fail penalties |
| Signal Dish | Stronger ambient event loot |
See the build tray screenshot above for costs and icons.
| Role | Buff when assigned |
|---|---|
| Worker | Cheaper upgrades |
| Gardener | Botany Lab bonus |
| Scout | Better event loot |
| Engineer | Energy Core / shield energy |
| Caretaker | Extra fail mitigation |
| Archivist | Data Tower crystals |
| Courier | Small dual bonus on any post |
Start with 2 crew · unlock up to 12 as the observatory levels.
- Cloud optional sync (still local-first)
- Shared island cosmetics packs
- Soundscape packs per tag
- Steam / Capacitor shell (same web core)
PRs and stars appreciated ⭐
MIT — see LICENSE.
Built by ArdaDDemir as a focus toy and a code showcase. Go ship your own island.











