Ether Relay est un jeu d action spatial one‑page jouable dans le navigateur. Tu pilotes un drone de ravitaillement dans une tempete de debris pour recharger des relais, maintenir un flux d energie eleve et survivre aux fronts successifs. Le front est un unique index.html (HTML/CSS/JS), tandis que le backend Python (stdlib) fournit la presence live et le leaderboard.
- Boucle nerveuse : collecte → livraison → surge, avec un multiplicateur de flux a proteger.
- Boost tactique : un burst court qui permet d eviter un pic de danger ou de franchir la tempete.
- Anomalies de flux : zones temporaires qui recompensent la prise de risque (points + recharge d onde).
- Fronts climatiques : vagues distinctes qui modifient la vitesse, la taille et la densite des debris.
- HUD clair : objectif contextuel, etats d onde/boost, integrite et relais cible.
- Deplacement : ZQSD ou fleches.
- Onde de choc : Espace.
- Boost : Shift ou B.
- Pause : P ou Entrer.
- Briefing : T.
- Mobile : pad directionnel + boutons Onde et Boost.
- Ramasse des noyaux pour remplir le cargo.
- Livrer un cargo charge un relais et augmente le flux (multiplicateur).
- Un relais sature declenche un surge (nettoyage local + gros bonus).
- Utilise le boost quand la densite de debris devient critique.
- Reste dans une anomalie de flux pour engranger des points et recharger l onde.
index.html: interface, rendu, moteur de jeu et logique gameplay.server.py: serveur HTTP + API JSON (presence live + leaderboard).scripts/: utilitaires de maintenance (ex: lint des scores).tests/: tests unitaires backend.
cd /workspace/neon
python3 server.py
# http://localhost:8000Si le front est ouvert en
file://, il utilisehttp://localhost:8000par defaut.
PORT(defaut8000)IDLE_TIMEOUT(defaut15)ADMIN_TOKEN: activePOST /api/reset(aliasRESET_TOKENaccepte)DRY_RUN(1/true) : analyse sans ecriture disqueTRUST_PROXY(1/true) : utiliseX-Forwarded-For/X-Real-IPMAX_SESSIONS_PER_IP(defaut6)RATE_LIMIT_RPS(defaut20)RATE_LIMIT_BURST(defaut40, calcule si absent)CACHE_MAX_AGE(defaut300)MAX_SCORE_PER_SECOND(defaut900)SCORE_GRACE_POINTS(defaut1500)MAX_SCORE_CAP(defaut5000000)MAX_SCORE_TIME(defaut28800, 8h)
Base: http://<host>:<port>/api. Le client peut forcer l API via ?api=https://....
Si le front est heberge sous /ether-relay, ce prefixe est ajoute automatiquement (compatibilite /space-cleaner conservee).
POST /api/state- body:
sessionId(obligatoire),clientId,instanceId,x,y,color,name,score,time,best,bestTime,since - reply:
{ ok, players, board, boardDaily, serverTime }
- body:
POST /api/score- body:
name,score,time,color,clientId,sessionId(optionnel) - reply:
{ ok, board, boardDaily, serverTime }
- body:
POST /api/leave- body:
sessionIdouclientId(+instanceIdoptionnel) - reply:
{ ok, removed, removedIds, serverTime }
- body:
POST /api/reset- body:
token(ou headerX-Admin-Token), requiertADMIN_TOKEN - reply:
{ ok, cleared, serverTime }
- body:
GET /api/stateouGET /api/board- reply:
{ ok, board, boardDaily, serverTime }
- reply:
scores.jsonest cree et mis a jour par le serveur (non versionne).- Le leaderboard expose le top 10 (
MAX_BOARD) et conserve jusqu a 100 scores (MAX_STORE). - Le serveur garde une seule meilleure entree par joueur (
clientIdprioritaire, sinon nom normalise). - Deux vues sont renvoyees: classement global (30 jours) et classement 24h.
- Tri:
scoredesc, puistimedesc, puiscreated. - Purge automatique des scores vieux de 30 jours (
BOARD_TTL).
python3 scripts/lint_scores_json.py
python3 -m unittest tests/test_server.py- Un reverse proxy (nginx/caddy) peut servir les assets statiques et proxyfier
/api. - Propager
X-Forwarded-Foret activerTRUST_PROXY=1si besoin.