neon-pong-lan
v1.5.2
Published
Neon-cyberpunk LAN Pong server with buffs, ultimates, talents and multi-room matchmaking. Run via `npx neon-pong-lan` and play in your browser.
Maintainers
Readme
Neon Pong LAN
Neon-cyberpunk пинг-понг на двоих для локальной сети. Хост запускает сервер одной командой — игроки заходят в браузере, без установки.
[host] $ npx neon-pong-lan
╔══════════════════════════════════════════════════╗
║ NEON PONG LAN — host started
║ Port: 3000
║ Tell your opponent to open:
║ http://192.168.1.42:3000/ (Ethernet)
║ Or locally: http://localhost:3000/
╚══════════════════════════════════════════════════╝Что внутри
- 2-игроковый сетевой Pong с host-authoritative симуляцией 60 Hz, snapshot 30 Hz, client-side prediction и entity interpolation
- 10 баффов / случайных предметов (SPEED BOOST, GIANT PADDLE, SHRINK, MULTI-BALL, SLOW MOTION, FAST BALL, REVERSE CONTROLS, MIRROR FIELD, MAGNET PADDLE, GHOST BALL) с весами и rubber-banding
- 4 ультимейта (OVERDRIVE, TELEPORT, TIME WARP, BALL CLONE) — выбираются перед матчем
- Дерево талантов на 15 узлов с XP/уровнями, прогресс хранится в localStorage с sha256-seal
- Мультикомнаты до 5 параллельных матчей — REST API
/api/roomsдля создания, 4-значные коды для приглашения друзей - Неон-визуал: parallax-сетка, trails, particles, screen-shake, bloom через canvas shadowBlur
- 19 SFX и 3 BGM-трека, всё синтезируется Web Audio API на лету (ноль ассетов)
- Zero-install для клиентов: только браузер (Chrome/Edge/Firefox)
Quick Start
Запустить через npx (одна команда)
npx neon-pong-lannpx сам скачает пакет, поднимет HTTP+WebSocket на порту 3000 (или ближайшем свободном) и напечатает LAN-адрес. Все игроки в локальной сети открывают этот адрес в браузере.
Установить глобально
npm install -g neon-pong-lan
neon-pong-lanУстановить как зависимость проекта
npm install neon-pong-lanimport http from 'node:http';
import { RoomManager } from 'neon-pong-lan/src/roomManager.js';
import { attachRoomManager } from 'neon-pong-lan/src/netServer.js';
const server = http.createServer(/* serve your own static files */);
const rooms = new RoomManager();
attachRoomManager(server, rooms);
server.listen(3000);CLI
USAGE:
npx neon-pong-lan [options]
OPTIONS:
-p, --port <num> Port to listen on (default: auto, 3000-3010)
-H, --host <addr> Bind address (default: 0.0.0.0; use 127.0.0.1 behind a proxy)
-r, --max-rooms <num> Max simultaneous rooms (default: 5)
-i, --idle-timeout <sec> Empty-room cleanup timeout (default: 60)
-o, --open Open browser to localhost on startup
-q, --quiet Suppress startup banner
-v, --version Print version
-h, --help Show helpПримеры
# Дефолт — поднимает на любом свободном порту 3000-3010
npx neon-pong-lan
# Конкретный порт
npx neon-pong-lan --port 8080
# За nginx-прокси: слушать только локально
npx neon-pong-lan -p 3000 -H 127.0.0.1
# Больше комнат и сразу открыть браузер
npx neon-pong-lan --max-rooms 10 --open
# Через ENV вместо флагов
PORT=8080 BIND_ADDRESS=127.0.0.1 NPL_MAX_ROOMS=10 npx neon-pong-lanREST API
Если хост запущен на http://host:3000:
GET /api/rooms # список открытых комнат
POST /api/rooms # создать новую (вернёт {code: "ABCD"})
DELETE /api/rooms # снести все пустые (cleanup)
GET /api/health # uptime + кол-во комнат
GET / # сам клиент
WS /ws?room=ABCD # игровой сокет (привязан к комнате)Геймплей
- Управление: мышь (по умолчанию) или W/S / ↑/↓. Переключение по первому input.
- Ультимейт: Space или ПКМ.
- TELEPORT — удержи Space, появится прицел; отпусти — ракетка телепортируется (300 ms stun).
- Остальные — мгновенная активация при готовом заряде.
- Пауза: Esc. Лимит 3×30 сек на игрока.
- Конец матча: Bo5 до 7 очков с отрывом 2 (по умолчанию). В лобби можно выбрать Bo3-11 или Bo1-5.
За nginx (продакшен)
В пакете уже есть готовые конфиги: deploy/nginx-neon-pong.conf и deploy/neon-pong.service для systemd. Подробная инструкция в deploy/README.md.
Минимум:
server {
listen 80;
server_name pong.example.com;
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
}С HTTPS (Let's Encrypt) клиент сам переключится на wss:// — в коде есть проверка location.protocol.
Архитектура
┌──────────┐ HTTP/REST + WS ┌──────────┐
│ Browser ├──────────────────────────►│ server.js │
│ (Player) │ │ │
│ Canvas │◄──────────────────────────┤ ws + http │
└──────────┘ JSON snapshots └─────┬─────┘
│
┌──────▼──────┐
│ RoomManager │
│ Map<code,Room>│
└──────┬──────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│Room │ │Room │ │Room │
│A4XW │ │BX4F │ ... │JTRC │
│60Hz │ │60Hz │ │60Hz │
└──────┘ └──────┘ └──────┘- Сервер (
src/): physics, RNG, buffs, ults, matchState, netServer, roomManager — чистый Node.js +ws. - Клиент (
public/): canvas-рендер, prediction, interpolation, particles, audio, HUD, talents, lobby — ванильный JS, ES-модули, без сборщиков.
Stack
- Node.js ≥ 20
ws(единственная runtime-зависимость)- Vanilla HTML5 / Canvas2D / Web Audio / WebSocket в клиенте
Тесты
npm test # юнит-тесты физики (12 кейсов)
node test/smoke.mjs # интеграция: lobby → match → goal
node test/match.mjs # полный матч + rematch
node test/multiroom.mjs # 3 комнаты параллельно + лимиты
node test/buffs.mjs # spawn / pickup эффектовЛицензия
MIT
