A real-time capture point system for airsoft, paintball, and nerf games
Turn any device into a capture point with GPS tracking, live maps, and instant score updates. Perfect for outdoor battles with multiple objectives.
Creates a King of the Hill style game:
- Admin Control Station: Start/stop games, view live tactical map, manage teams
- Capture Point Devices: Tablets placed around the field - players tap to capture
- Live GPS Tracking: See all capture points on a satellite map in real-time
- Instant Scoring: Points update immediately when captured or held
Typical Setup: 1 admin laptop + 4-8 tablets as capture points
npm install
npm run devThen open:
- Admin: http://localhost:3000/admin
- Capture Point: http://localhost:3000/capture-point (open multiple tabs)
Try it: Click "Start Mission" on admin, then capture points in multiple browser tabs.
- Admin: Computer with Node.js
- Capture Points: Tablets/phones with web browsers only (no Node.js needed!)
- Network: All devices on the same WiFi
-
Build & start admin server:
npm run build node .output/server/index.mjs
-
Find admin IP:
# Linux ip addr # Windows ipconfig
Note the IP (e.g.,
192.168.1.10) -
Open on tablets:
- Open browser on each tablet
- Navigate to:
http://192.168.1.10:3000/capture-point - Each tablet automatically gets a unique NATO name
-
Play:
- Open admin:
http://192.168.1.10:3000/admin - Click "Start Game"
- Place tablets around field
- Players tap buttons to capture!
- Open admin:
Create a .env file (copy from env.example):
# Teams
DEFAULT_TEAMS='[{"id":1,"name":"Red Team","color":"#ef4444"},{"id":2,"name":"Blue Team","color":"#3b82f6"}]'
# Scoring
POINTS_PER_CAPTURE=10
POINTS_PER_SECOND=1
# Timing
GPS_UPDATE_FREQUENCY=1000
CAPTURE_COOLDOWN=1000LOAD_PREVIOUS_STATE=true # Load previous game state
STATE_FILE_PATH=.battlemesh-state.jsonNote: Environment variables have sensible defaults - only set what you want to change.
- Capture Bonus: +10 points when you capture a point
- Hold Points: +1 point per second for each point your team controls
Example: Red Team holds 3 points for 60 seconds = 3 ร 10 + (3 ร 1 ร 60) = 210 points
- Check devices are on the same WiFi network
- Verify admin IP address is correct
- Check server is running
- Allow location permissions in browser
- System automatically falls back to browser location if GPS hardware unavailable
- URL parameter:
http://192.168.1.10:3000/capture-point?reset=1 - Reset button: Click "Reset Identity" in capture point interface
- Console:
localStorage.removeItem('battlemesh-nato-names')
Server:
.battlemesh-state.json- Game state (scores, captures, teams)
Browser (capture points):
sessionStorage['battlemesh-tab-id']- Tab identifierlocalStorage['battlemesh-nato-names']- NATO name mapping
- Big tap buttons for quick captures
- Real-time score display
- Tactical map view
- Connection & GPS status
- Full game control (start/stop/reset)
- Live tactical map with satellite imagery
- Real-time scoreboard
- Activity feed (all captures)
- Node monitoring
- NATO callsigns (Alpha, Bravo, Charlie...)
- GPS tracking (hardware or browser location)
- State persistence (survives restarts)
- Keyboard shortcuts (
Sstart/stop,Rreset,Ccenter map)
npm test # Run unit tests
npm run lint # Check code style
npm run test:coverage # Test coveragenpm run test:e2e # Run all e2e tests (10-12 seconds, CI optimized)
npm run test:e2e:ui # Run e2e tests with UI mode
npm run test:e2e:headed # Run e2e tests in headed mode- All tests:
npm run test:e2e- Complete test suite across all browsers (10-12 seconds) - Run specific browser:
npx playwright test --project=chromium - Run specific test file:
npx playwright test tests/e2e/core.spec.ts - Run in debug mode:
npx playwright test --debug - Generate test report:
npx playwright show-report
- Core Functionality: Landing page, admin page, capture point page, multi-page integration
- Core Gameplay: Game start/stop, capture operations, team management, score tracking, state synchronization
- Responsive Design: Mobile and tablet viewport compatibility
- Cross-Browser Compatibility: All pages load correctly across browsers
- Performance: Pages load within reasonable time limits
- Browsers: Chrome, Firefox, Mobile Chrome, iPad Pro
- Nuxt 4 - Vue.js framework
- Pinia - State management
- Tailwind CSS - Styling
- Leaflet.js - Maps
- Server-Sent Events (SSE) - Real-time communication
- Fork the repo
- Create a branch:
git checkout -b my-feature - Make your changes
- Run tests:
npm test - Submit a pull request
MIT License
- Pre-cache map tiles by zooming around your field area
- Do a practice run before game day
- Ensure all devices are fully charged
- Use static IPs for stable connections
- Test GPS functionality before placing devices
