c8dff33836
Remove @liveblocks/client and @liveblocks/zustand; add ws and a server npm script. Update README (fork attribution preserved, WS backend usage), .env.example (VITE_RT_URL), and pin the /blocs-pro/ base in vite.config.
90 lines
3.6 KiB
Markdown
90 lines
3.6 KiB
Markdown
# 3D Lego-like Brick Builder Web App
|
|
|
|
Build and collaborate in real-time on 3D models using rectangular bricks. This multi-user application lets several people create designs together in a shared 3D space using Lego-like bricks.
|
|
|
|

|
|
|
|
> Fork of [bhushan6/lego-builder](https://github.com/bhushan6/lego-builder) (MIT — see `LICENSE`, attribution preserved). The original used the **Liveblocks** SaaS for real-time collaboration; this fork replaces it with a **self-hosted, sovereign WebSocket backend** (`server/index.js`) — no third-party SaaS, no API key.
|
|
|
|
## Features
|
|
|
|
- **3D Rendering**: Utilizes `three.js` and `react-three-fiber` for efficient and smooth 3D rendering.
|
|
- **Real-time Collaboration**: Self-hosted WebSocket relay (`server/index.js`) synchronizes the shared build (`bricks`, `cursorColors`) and per-user presence/cursors across everyone in a room.
|
|
- **Intuitive UI**: Built with `radix ui`.
|
|
- **State Management**: `Zustand`, with a custom `roomSync` middleware (`src/store/roomSync.js`) that exposes the same store surface the components expect.
|
|
|
|
## Technologies Used
|
|
|
|
- [React](https://reactjs.org/)
|
|
- [three.js](https://threejs.org/)
|
|
- [react-three-fiber](https://github.com/pmndrs/react-three-fiber)
|
|
- [radix ui](https://www.radix-ui.com/)
|
|
- [zustand](https://docs.pmnd.rs/zustand/getting-started/introduction)
|
|
- [ws](https://github.com/websockets/ws) — WebSocket server for the real-time backend
|
|
- [Vite](https://vitejs.dev/)
|
|
|
|
## Real-time architecture
|
|
|
|
- **`server/index.js`** — a standalone Node WebSocket relay (uses `ws`, no build step). One server hosts many rooms; per room it keeps the current shared storage snapshot (`{ bricks, cursorColors }`) plus the connected clients. Clients connect with `ws(s)://HOST/?room=<id>`. JSON protocol:
|
|
- server → client: `init`, `join`, `leave`, `presence`, `storage`, `event`
|
|
- client → server: `presence`, `storage` (last-writer-wins), `event` (ephemeral cursors, relayed to others only, never persisted)
|
|
- **`src/store/roomSync.js`** — a Zustand middleware that drops in for `@liveblocks/zustand`. It exposes `state.liveblocks.{enterRoom, leaveRoom, status, others, room}` where `room` has `broadcastEvent`, `subscribe("event", cb)` and no-op `history.undo/redo` stubs — so the existing components work unchanged.
|
|
|
|
## Local Development
|
|
|
|
### Prerequisites
|
|
|
|
- [Node.js](https://nodejs.org/) (18+; tested on Node 26)
|
|
- [npm](https://www.npmjs.com/)
|
|
|
|
### Setup
|
|
|
|
1. Clone the repository:
|
|
|
|
```bash
|
|
git clone https://git.saillant.cc/electron-rare/lego-builder.git
|
|
cd lego-builder
|
|
```
|
|
|
|
2. Install dependencies:
|
|
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. (Optional) point the client at a specific realtime server. Create `.env`:
|
|
|
|
```bash
|
|
echo "VITE_RT_URL=ws://localhost:8090" > .env
|
|
```
|
|
|
|
If unset, the client falls back to `ws://localhost:8090` in dev, or
|
|
`wss://<your-host>/blocs-rt` when served over HTTPS in production (that path
|
|
is routed to the relay by the deployment infra).
|
|
|
|
4. Start the realtime server (in one terminal):
|
|
|
|
```bash
|
|
npm run server # listens on $PORT (default 8090)
|
|
```
|
|
|
|
5. Start the dev server (in another terminal):
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
6. Open the app at the URL Vite prints (note the `/blocs-pro/` base path,
|
|
e.g. http://localhost:5173/blocs-pro/). Open it in two browsers/tabs and
|
|
join the **same Room ID** to collaborate.
|
|
|
|
### Build
|
|
|
|
```bash
|
|
npm run build # outputs dist/, served under base /blocs-pro/
|
|
```
|
|
|
|
## Contribution
|
|
|
|
Feel free to fork the project, open issues, and submit pull requests. Any contribution is highly appreciated!
|