简体中文 README_ZH.md | English
Multiplayer real-time cloud-based aquarium — feed the fish, tap the glass, or simply enjoy the view.
| Layer | Tech |
|---|---|
| Client | React 19 + Vite + TypeScript + Three.js |
| Server | Node.js + Fastify + Socket.IO + TypeScript |
| DB | Supabase (PostgreSQL) — Rooms & Barrages |
| Shared | TypeScript types + Zod schemas |
- 3D Immersive Aquarium: High-fidelity 3D fish tank powered by Three.js and WebGL.
- Real-time Multiplayer: Dynamic sharding system with Socket.IO.
- Bilingual Support: Full English and Chinese localization with path-based routing (
/vs/zh/). - Dynamic Sharding: Direct room allocation based on user's language (zh/en).
- Persistence: Room directory and real-time chat (barrage) history stored in Supabase.
- Performance Optimized: 15Hz server-side physics simulation, client-side linear interpolation.
- Clean URLs: SEO-friendly routing without
.htmlextensions.
# Install all workspace deps (run once from repo root)
npm install
# Terminal 1 — server (port 3001)
npm run dev:server
# Terminal 2 — client (port 5173)
npm run dev:clientOpen http://localhost:5173 in multiple tabs to test multiplayer.
fin-tap/
├── apps/
│ ├── client/ # React + Three.js 前端 (SEO 优化的静态 HTML + TS)
│ └── server/ # Fastify + Socket.IO 游戏服务器
├── packages/
│ └── shared/ # 协议类型、Zod 模式、常量、逻辑共享
└── supabase/
└── schema.sql # 数据库表结构与安全策略 (RLS)
| File | Role |
|---|---|
packages/shared/src/protocol.ts |
All socket message types |
packages/shared/src/constants.ts |
Tick rate, room capacity, physics constants |
apps/server/src/game/room.ts |
Room state management (language, users, fish) |
apps/server/src/game/simulation.ts |
15 Hz physical tick loop & broadcast |
apps/server/src/ws/gateway.ts |
Socket.IO handlers & DB persistence logic |
apps/client/src/utils/language.ts |
Language detection & SEO routing controller |
apps/client/src/scene/AquariumScene.ts |
Three.js scene, fish instancing |
apps/client/src/net/socket.ts |
Socket.IO client, rejoin & lang preference |
supabase/schema.sql |
Database schema for rooms and barrages |
| Action | Description |
|---|---|
| Feed fish | Click "Feed" button or click top of aquarium |
| Tap glass | Click "Tap" button or click aquarium glass |
Ensure your Supabase project contains the tables defined in supabase/schema.sql. This table handles:
- Room Registry: Persists room IDs and languages across server restarts.
- Barrage History: Stores all real-time chat messages for durability.
The system uses apps/client/src/utils/language.ts to manage routing:
- English:
https://.../game - Chinese:
https://.../zh/gamePreference is persisted inlocalStorageto maintain consistent UX.
npm run build # builds shared → server → client
# client output: apps/client/dist/
# server output: apps/server/dist/