openvibers/breakroomsimulator README.md
README.md
| 1 | # 🏓 Amazon Break Room Simulator |
| 2 | |
| 3 | [](https://simulator.rest) |
| 4 | [](LICENSE) |
| 5 | |
| 6 | A **free, open-source** realtime multiplayer 3D web game recreating an Amazon fulfillment |
| 7 | center break room. Runs on desktop and mobile — no build step, |
| 8 | vanilla JS + Three.js. |
| 9 | |
| 10 | 🎮 **Play it live: [simulator.rest](https://simulator.rest)** · 💻 **Source: [github.com/OpenVibers/BreakRoomSimulator](https://github.com/OpenVibers/BreakRoomSimulator)** |
| 11 | |
| 12 | Issues and pull requests are welcome — map fixes, minigames, props, anything. |
| 13 | |
| 14 | ## Run it |
| 15 | |
| 16 | ```bash |
| 17 | git clone https://github.com/OpenVibers/BreakRoomSimulator.git |
| 18 | cd BreakRoomSimulator |
| 19 | npm install |
| 20 | npm start # → http://localhost:3000 |
| 21 | ``` |
| 22 | |
| 23 | Open the URL on any device on your network (`http://<your-ip>:3000`) and everyone shares |
| 24 | the same break room. `?autoguest` in the URL skips the login screen with a guest account. |
| 25 | |
| 26 | ## The building (the real route, from countless break-room trips) |
| 27 | |
| 28 | You spawn on the **landscaped front walkway** (planter beds, Amazon Tours signs, |
| 29 | food truck, flag pole, bollarded plaza) under the huge white facade with its |
| 30 | blue roofline stripe, wood-band tower with the Amazon smile, and blue |
| 31 | **"main entry"** canopy — then enter the way associates really do: |
| 32 | |
| 33 | **main entry glass doors** → **entry lobby** (blue walls, Amazon Family World |
| 34 | Map mural, green **hedge wall** with the neon *"Welcome to PAE2"* script, red |
| 35 | garland, Enter / Do-Not-Enter lanes) → **badge gates** (E to badge; paddles |
| 36 | open) → **security** (freestanding white **PAE2** desk island, three metal-detector |
| 37 | lanes + x-ray belt feeding the *Safe to Go* arch into the FC, Peccy statue, |
| 38 | *thank you / Exit* band) → through the mural wall's **locker opening** → |
| 39 | **locker hallway** (tan locker banks, teal floor path) → **double |
| 40 | doors by the red clock + flags** → **cafeteria** (avenue C market, dining |
| 41 | zones, couch corner, ping pong, giant Connect 4, chess, arcade, bathrooms, |
| 42 | smoke cage outside). All exterior cafeteria doors are emergency-exit-only. |
| 43 | |
| 44 | ## Admin & level editor |
| 45 | |
| 46 | - The **first registered account** automatically becomes admin |
| 47 | (or grant later: `node server/server.js --admin SomeName`). |
| 48 | - Admins get a 🛠️ button — a **persistent level editor**: place, move, rotate, |
| 49 | scale, and delete props (tables, chairs, couches, lockers, vending, walls, |
| 50 | invisible blockers, …). Edits save to `data/map-edits.json`, sync live to |
| 51 | every connected player, and survive restarts. |
| 52 | |
| 53 | ## Features |
| 54 | |
| 55 | - **Accounts** — register/login (scrypt-hashed passwords, JSON store) or play as a guest. |
| 56 | Vest color and win stats persist per account. |
| 57 | - **Realtime multiplayer** — websocket sync (12 Hz snapshots): avatars, walk/run/sit |
| 58 | animation, name tags, chat with speech bubbles, join/leave feed. |
| 59 | - **The room**: |
| 60 | - Lounge: leather couches inside blue-tape outlines labeled *COUCH*, oriental rug, |
| 61 | coffee tables, bookshelves with board games, palm plants, *Together at Amazon* banner |
| 62 | - Games corner: two JOOLA-style ping pong tables, yellow *PRIME BREAKER* arcade |
| 63 | cabinet, chess table, **two giant Connect 4s**, cornhole board, stacked-chair zone |
| 64 | - Dining hall: 40 clusters of folding tables, ~500 chairs color-zoned |
| 65 | green → brown → orange → yellow, napkin dispensers, *July Newsletter* table tents |
| 66 | - *avenue C* micro-market: glass-door coolers, snack slat-walls, self-checkout kiosks, |
| 67 | Pepsi vending machines, Red Bull cooler, coffee station, microwaves, lockers |
| 68 | - Annex corridor through the wide passage: day lockers, |
| 69 | avenue C café/servery nook, glass-walled wellness room, teal walking-path |
| 70 | tape with red STOP floor decals, second entrance doors |
| 71 | - International flags around the whole perimeter + strung across the hall, |
| 72 | blue-fascia recessed ceiling sections with yellow accent trim, pendant lights, |
| 73 | live red LED clocks, TVs cycling live slides (online count, ping pong ladder), |
| 74 | floor-to-ceiling windows with a parking lot, cars, trees, and a stop sign outside |
| 75 | - **Playable games** (server-authoritative): |
| 76 | - 🏓 **Ping pong** — timing-based rallies, first to 7; solo practice mode |
| 77 | - 🔴 **Giant Connect 4** — click a column to drop; win detection + rematch |
| 78 | - ♟️ **Chess** — casual rules (capture the king), move validation, promotion |
| 79 | - 🕹️ **PRIME BREAKER** — breakout arcade game with server-wide highscore board |
| 80 | shown on the cabinet screen |
| 81 | - 🛒 Grab snacks/drinks/coffee — item shows in your avatar's hand |
| 82 | - **Mobile** — virtual joystick, drag look, touch buttons, fullscreen. |
| 83 | |
| 84 | ## Controls |
| 85 | |
| 86 | | Desktop | Mobile | |
| 87 | |---|---| |
| 88 | | WASD walk, Shift run, Space jump (bhop-friendly), Ctrl crouch | joystick (push far = run), 🔽 crouch, ⤒ jump | |
| 89 | | Mouse (click to lock) to look · V or 📷 first person | drag right side | |
| 90 | | E interact · F use item / swing prop | `E` button | |
| 91 | | 1-6 hotbar · Tab/🎒 inventory (drag & drop) | tap hotbar / 🎒 | |
| 92 | | Click column/square to play boards | tap column/square | |
| 93 | | Enter chat | 💬 button | |
| 94 | |
| 95 | Movement is Source-engine style: ground friction + wish-direction acceleration, |
| 96 | air-strafe control with capped air acceleration, and jumps that preserve |
| 97 | horizontal velocity. Collect snacks (consumable), melee props (paddle, broom, |
| 98 | tape gun, wrench, banana, cardboard tube — swing with F or click in first |
| 99 | person), and clothes (hats/vests) from vending machines and pickups around the |
| 100 | facility. Inventory persists on your account. |
| 101 | |
| 102 | ## Stack |
| 103 | |
| 104 | Node + Express + `ws` (no build step), Three.js frontend served as ES modules. |
| 105 | All textures are procedurally drawn on canvas — flags, signage, vending machines, |
| 106 | the rug — no external assets. Data persists to `data/*.json`. |
| 107 | |
| 108 | ## Website & public hosting (simulator.rest) |
| 109 | |
| 110 | The server serves a marketing landing page at `/` and the game itself at `/play`. |
| 111 | Real screenshots for the landing page live in `public/img/`. |
| 112 | |
| 113 | **Production** ([simulator.rest](https://simulator.rest)) runs the bare-metal setup below: |
| 114 | Cloudflare (proxied DNS) → nginx (Let's Encrypt TLS, websocket proxy, Cloudflare |
| 115 | real-IP restore) → the Node server as the `breakroom` systemd service in |
| 116 | `/opt/BreakRoomSimulator`. Deploying an update there: |
| 117 | |
| 118 | ```bash |
| 119 | ssh <server> 'cd /opt/BreakRoomSimulator && sudo git pull && sudo npm install --omit=dev && sudo systemctl restart breakroom' |
| 120 | ``` |
| 121 | |
| 122 | ### One-command deploy (Docker + Caddy, automatic HTTPS) |
| 123 | |
| 124 | On any Linux server (1 vCPU / 1 GB is plenty to start): |
| 125 | |
| 126 | 1. Point DNS: `A` records for `simulator.rest` and `www.simulator.rest` → your server's IP. |
| 127 | 2. Copy the project to the server (or `git clone` it), then: |
| 128 | |
| 129 | ```bash |
| 130 | docker compose up -d --build |
| 131 | ``` |
| 132 | |
| 133 | That's it. The `game` container runs the Node server (only exposed to localhost), |
| 134 | and the `caddy` container terminates TLS for **simulator.rest** with an automatic |
| 135 | Let's Encrypt certificate and proxies HTTP + websockets through. Player accounts, |
| 136 | highscores and map edits persist in `./data` on the host. |
| 137 | |
| 138 | - First registered account becomes **admin** (or grant later: `node server/server.js --admin NAME` |
| 139 | won't work while the server runs — instead stop, run once with the flag, restart). |
| 140 | - Update: `git pull && docker compose up -d --build`. |
| 141 | - Logs: `docker compose logs -f game`. |
| 142 | |
| 143 | ### Without Docker |
| 144 | |
| 145 | ```bash |
| 146 | npm install |
| 147 | PORT=3000 npm start |
| 148 | ``` |
| 149 | |
| 150 | then put any TLS-terminating proxy in front (the websocket path is same-origin, so a |
| 151 | plain `reverse_proxy`/`proxy_pass` with upgrade headers is all that's needed). Example |
| 152 | nginx location block: |
| 153 | |
| 154 | ```nginx |
| 155 | location / { |
| 156 | proxy_pass http://127.0.0.1:3000; |
| 157 | proxy_http_version 1.1; |
| 158 | proxy_set_header Upgrade $http_upgrade; |
| 159 | proxy_set_header Connection "upgrade"; |
| 160 | proxy_set_header Host $host; |
| 161 | } |
| 162 | ``` |
| 163 | |
| 164 | A systemd unit for bare-metal installs: |
| 165 | |
| 166 | ```ini |
| 167 | [Unit] |
| 168 | Description=Amazon Break Room Simulator |
| 169 | After=network.target |
| 170 | |
| 171 | [Service] |
| 172 | WorkingDirectory=/opt/amazon-break-room-simulator |
| 173 | ExecStart=/usr/bin/node server/server.js |
| 174 | Restart=always |
| 175 | Environment=PORT=3000 |
| 176 | User=www-data |
| 177 | |
| 178 | [Install] |
| 179 | WantedBy=multi-user.target |
| 180 | ``` |
| 181 |