Skip to content

Alexandru2984/vix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VixArena

VixArena is a lightweight real-time 2D multiplayer spatial sandbox deployed at https://vix.micutu.com. It demonstrates a C++ backend handling HTTP routes, WebSocket messaging, an authoritative in-memory game loop, global chat, and a plain browser canvas frontend.

Vix.cpp v2.5.2 was installed and evaluated on this VPS. Its HTTP listener did not honor localhost-only binding in this environment, so the deployed production server uses a Boost.Beast fallback to satisfy the security requirement that the app bind only to 127.0.0.1.

Features

  • Shared 2D world with server-authoritative movement, bounds, and static obstacles.
  • Collectible orb pickups with server-authoritative scoring and score feedback effects.
  • Temporary speed powerups with server-authoritative boost timers.
  • Server-authoritative abilities: dash, shield/phasing, and magnet.
  • Server-side bots fill the arena for solo play when humans are connected.
  • Contested central control zone that grants passive points only when one player holds it.
  • Orb Run mini quest: every 3 orb pickups grants a server-authoritative bonus.
  • Live leaderboard, arena event feed, minimap, objective HUD, edge target markers, score popups, and local score HUD.
  • WebSocket join, input, ability, chat, ping/pong, and snapshot messages.
  • 20 ticks/sec server loop with low-cost full snapshots for v1.
  • In-memory chat history for the last 50 messages.
  • Responsive canvas frontend with interpolation, HUD, chat, mobile chat badge, floating touch joystick, and connection metrics.
  • HTTP endpoints for health, sanitized state, stats, docs, and the game page.

Stack

  • C++20
  • Vix.cpp SDK v2.5.2 installed on the VPS
  • Boost.Beast fallback server for production HTTP/WebSocket binding
  • CMake + Ninja
  • nlohmann/json
  • systemd service: vix-arena.service
  • Nginx reverse proxy with Certbot TLS

Build

cd /home/micu/vix
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/home/micu/.local
cmake --build build

Run Locally On The VPS

cd /home/micu/vix
./build/vix-arena

The app reads .env from the project root and binds only to localhost.

Environment Variables

.env is intentionally ignored by Git.

APP_HOST=127.0.0.1
APP_PORT=18080
WS_HOST=127.0.0.1
WS_PORT=18081
PUBLIC_URL=https://vix.micutu.com

APP_PORT serves HTTP and WebSocket on /ws, bound to APP_HOST. WS_PORT is kept equal to APP_PORT for operational clarity. Nginx exposes both under https://vix.micutu.com.

Systemd

Service name: vix-arena.service

Installed path:

/etc/systemd/system/vix-arena.service

Local example:

systemd/vix-arena.service.example

Common commands:

sudo systemctl status vix-arena.service
sudo journalctl -u vix-arena.service -n 100 --no-pager
sudo systemctl restart vix-arena.service

Nginx

Config path:

/etc/nginx/sites-available/vix.micutu.com

Enabled path:

/etc/nginx/sites-enabled/vix.micutu.com

Nginx proxies / and /ws to APP_PORT; /ws includes WebSocket upgrade headers and long proxy timeouts.

Public URL

  • Game: https://vix.micutu.com
  • WebSocket: wss://vix.micutu.com/ws
  • Docs: https://vix.micutu.com/docs

WebSocket Protocol

Client messages:

{"type":"join","name":"Micu"}
{"type":"input","up":true,"down":false,"left":false,"right":true,"seq":123}
{"type":"ability","ability":"dash"}
{"type":"ability","ability":"shield"}
{"type":"ability","ability":"magnet"}
{"type":"chat","message":"salut"}
{"type":"ping","t":1710000000000}

Server messages:

{"type":"welcome","id":"p-1","world":{"width":2000,"height":1200,"obstacles":[]}}
{"type":"snapshot","players":[{"id":"p-1","name":"Micu","x":100,"y":200,"color":"#66ccff","score":10,"boostMs":0}],"orbs":[{"id":"o-1","x":400,"y":300,"value":5,"color":"#66ccff"}],"powerups":[{"id":"u-1","kind":"speed","x":700,"y":350,"durationSeconds":6,"color":"#c9a7ff"}],"controlZone":{"x":1000,"y":600,"radius":150,"pointsPerSecond":2},"round":{"number":1,"phase":"active","secondsRemaining":180},"events":[{"id":1,"type":"orb","text":"Micu collected +5","timestamp":"2026-05-03T17:00:00Z"}]}
{"type":"chat","from":"Micu","message":"salut","timestamp":"2026-05-03T17:00:00Z"}
{"type":"player_joined","id":"p-1","name":"Micu"}
{"type":"player_left","id":"p-1"}
{"type":"pong","t":1710000000000}

API Endpoints

  • GET /health returns status, service name, player count, and uptime.
  • GET /api/state returns player count, world size, obstacles, current orbs, speed powerups, round state, and control zone metadata.
  • GET /api/stats returns connected players, max players, uptime, tick target, total connections, total chat messages, orb pickups, powerup pickups, rounds, and control-zone points.
  • Bot counters are included in /health, /api/state, and /api/stats.
  • GET /docs explains controls, protocol, endpoints, and limitations.
  • GET / serves the browser game.

Controls

  • WASD or arrow keys: move.
  • Space: dash.
  • Shift: shield/phasing.
  • E: magnet.
  • Touch joystick: move on mobile/touchscreen devices. On touchscreens, dragging directly on the arena also starts a floating joystick.
  • Ability buttons work on desktop and touch devices.
  • Quick ping buttons send short team-style chat messages.
  • Collect glowing orbs for instant points.
  • Grab violet boosts for temporary speed.
  • Hold the central control zone for passive points.
  • Complete Orb Run by collecting 3 orbs for a bonus.
  • Follow the objective HUD and edge markers to find nearby orbs, boosts, or the control zone.
  • Enter: focus chat.
  • Esc: unfocus chat.

Deployment Notes

  • Work is contained in /home/micu/vix.
  • The app binds to 127.0.0.1 only.
  • Vix.cpp v2.5.2 was installed and tested, but its HTTP listener did not honor localhost-only binding on this VPS. The production server therefore uses a Boost.Beast fallback while preserving the requested C++ real-time app behavior.
  • Nginx is the public reverse proxy.
  • Certbot manages the public TLS certificate.
  • Existing services should not be stopped or killed.
  • If a port is occupied, use scripts/find_free_port.sh and update .env.

Troubleshooting

curl -fsS http://127.0.0.1:${APP_PORT}/health
curl -fsSI https://vix.micutu.com/
sudo nginx -t
sudo systemctl status nginx
sudo systemctl status vix-arena.service
sudo journalctl -u vix-arena.service -n 100 --no-pager
ss -ltnp | grep vix-arena

Security Notes

  • No secrets are exposed to the frontend.
  • Display names and chat messages are length-limited and control-character cleaned.
  • Invalid JSON and unknown WebSocket message types are rejected.
  • Chat is throttled per connection.
  • Input messages are throttled server-side.
  • WebSocket payloads are capped before JSON parsing.
  • The arena caps active joined players.
  • Movement is authoritative and clamped server-side.
  • Abilities and cooldowns are authoritative server-side.
  • No shell commands, user file paths, database, or arbitrary code execution are exposed.
  • Nginx adds basic security headers and handles TLS.
  • Cloudflare sits in front of the VPS. App-level throttles are still kept because Nginx per-IP limits require correct Cloudflare real IP handling or Cloudflare-side WAF/rate-limit rules.

Performance Notes

  • State is in memory and intentionally small.
  • The target tick rate is 20 ticks/sec.
  • Snapshots are compact JSON and include players, scores, boost timers, active orbs, powerups, round state, event feed, and control-zone metadata.
  • The design should handle 20-50 connected players for v1 on a small VPS.

Limitations / TODOs

  • No persistence across restarts.
  • No authentication or private rooms.
  • No binary protocol or delta compression yet.
  • Mobile support is intentionally lightweight for v1; advanced gestures, room setup, and landscape-specific UI modes are still TODOs.
  • Horizontal scaling would require external state or pub/sub.

About

Trying vix.cpp

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors