Planeto is a 3D multiuser application featuring a cluster of planetoids, observable by users represented as "eyes" that can exchange symbols.
- A procedurally generated cluster of planetoids.
- Users are represented as "eyes" that can observe the environment.
- Real-time symbol-based communication between users.
- Procedurally generated textures and dynamic object forms.
- Standard camera controls: zoom and rotate.
- Multiplayer functionality: symbols sent by one user are visible to others.
- Data integrity enforced by Zod schemas.
- Efficient presence: User "eye" data is transmitted efficiently, sending lightweight pings for idle users to maintain visibility without excessive data transfer.
- All celestial bodies drift, collide, and interact within the simulated space.
- Gravitational forces influence the movement of objects.
- Collisions, while infrequent, affect the overall planetoid cluster.
- Next.js (App Router, TypeScript)
- React Three Fiber (@react-three/fiber)
- Drei (@react-three/drei)
- Rapier physics (@react-three/rapier)
- Zod (for domain modeling)
- Zustand (for state management)
npm install
npm run devOpen your browser and navigate to: http://localhost:3000
npm run dev: Starts the development server.npm run build: Builds the application for production.npm run start: Starts the production server.npm run lint: Lints the codebase for potential errors.npm run check: Runs formatting, linting, type-checking, and tests.
- To modify the generation of planetoids, adjust the logic in
src/hooks/usePlanetData.ts. - To change the available symbols, edit the
SYMBOLSarray, likely located in a file withinsrc/domain/.
MIT
- The application simulates a space environment without a central star or fixed point of reference. The focus is on the planetoid cluster and user interactions.
When a user double-clicks, a large green symbol (from a predefined set) appears in the bottom-right of their screen. This symbol is chosen randomly. Users can see symbols generated by others in the 3D space; their own symbol is only visible on their local interface. Symbols are broadcast to all connected users in real-time.
- State Management: Zustand (
src/stores/symbolStore.ts) - Schema Definition: Zod (likely in
src/domain/index.tsor a similar file withinsrc/domain/) - Event Trigger:
src/app/components/Scene.tsx(onDoubleClick event) - Symbol Display:
src/app/components/SymbolDisplay.tsx(for the local user's symbol),src/app/components/Eyes.tsx(for other users' symbols) - To modify the symbols or their appearance, update the relevant components.
This project uses Server-Sent Events (SSE) to share user positions and game events (like symbol inputs) in near real-time among all connected users. Significant effort has been made to minimize bandwidth and server load:
- User Presence: A user's position is sent to the server upon initial connection and then periodically when it changes (throttled by
useEyePositionReporting). If a user remains idle, their data is automatically purged from the server after a period of inactivity (e.g., 30 seconds, configurable inuseEyes.tsand server-side logic) to maintain an accurate list of active users. If the user moves again, their representation will reappear to others. - Symbol Events: Symbol events are triggered by specific actions (e.g., double-click) and are throttled by
useInputThrottlebefore transmission.
For a detailed technical explanation of the real-time architecture and bandwidth optimization strategies, please see docs/realtime-communication.md.
For details on the 3D camera setup, see docs/camera-setup.md.
This application is configured as a Progressive Web App (PWA), allowing it to be installed on devices for a more native-like experience. This is achieved using next-pwa.
Key PWA features implemented:
- Web App Manifest:
public/manifest.jsonprovides metadata about the application. - Service Worker:
next-pwaautomatically generates a service worker for caching and offline capabilities. - Icons: App icons are provided in
public/icons/.
For more details on the PWA setup, refer to the next-pwa documentation and the project's next.config.ts.
This application can be deployed to Fly.io using the provided Dockerfile and fly.toml configuration.
- Install
flyctl: Follow the instructions at https://fly.io/docs/hands-on/install-flyctl/. - Login to Fly: Run
fly auth login.
-
Launch the app on Fly.io (if you haven't already):
fly launch
- Choose an app name (e.g.,
planeto). - Select your organization and a region.
- IMPORTANT: Say "No" when asked to set up a Postgres database or Redis, as this application does not require them.
- A
fly.tomlfile will be generated. The providedfly.tomlin this repository is configured for cost-effectiveness (small machine, auto-stop/start).
- Choose an app name (e.g.,
-
Deploy your application:
fly deploy
After making changes to your application, simply run:
fly deployFly.io will use the Dockerfile to build and deploy your updated application.
- View logs:
fly logs -a <your-app-name> - Open your deployed app:
fly apps open -a <your-app-name> - Access the Fly.io dashboard for more detailed monitoring.
For more detailed deployment and configuration information, see docs/deployment-flyio.md.
For details on API endpoints, please refer to docs/api.md.
