lp177

Mountain Fighters

Beat’em up satirique : sept nains contre Elon Musk pour sauver Blanche-Neige

Jeu webaoût 2026TypeScriptCanvas 2DWeb AudioWebRTC (PeerJS)Vite

Jouer en ligne Code source

Beat’em up satirique dans le navigateur : sept nains en blouson de cuir affrontent les sbires d’Elon Musk sur 70 cartes. Coopération jusqu’à quatre joueurs en local, jeu en ligne par simple lien, avec une simulation déterministe et des graphismes entièrement vectoriels générés par le code.

But du projet

Elon Musk a enlevé Blanche-Neige pour la disséquer et en construire un clone robot. Les sept nains posent leurs pioches et partent la délivrer. Le jeu revendique la profondeur de combat d’un Street Fighter (données de frames, annulations, jongles, parades, jauge) dans la structure d’un Final Fight : défilement horizontal, vagues d’ennemis, armes à ramasser, coopération.

Fonctionnalités

  • 70 cartes, avec un boss toutes les cinq cartes, jusqu’à Elon Musk lui-même.
  • 7 nains jouables, chacun avec ses coups, son arme et son ultime.
  • Ennemis variés : gardes, agents armés de taser, boucliers anti-émeute, robots de sécurité, aspirateurs autonomes, réfrigérateurs connectés, drones de livraison, stagiaires, lobbyistes.
  • Armes à ramasser et échanger (chaînes, battes, barres de fer, boucliers, portière de Cybertruck) et véhicules sur onze cartes (moto, Cybertruck, capsule Hyperloop, fusée).
  • Cinématique d’ouverture, passable, jouée une seule fois.
  • Multijoueur local jusqu’à quatre sur un clavier ou avec des manettes, et en ligne en envoyant un lien, depuis l’accueil ou le menu pause.
  • Commandes tactiles qui s’effacent dès qu’un clavier ou une manette est utilisé ; toutes les touches sont reconfigurables, y compris en pleine partie.

Fonctionnement

  • TypeScript et Vite, sans framework ; rendu Canvas 2D dans un espace virtuel de 640×360 adapté à la fenêtre. Seules dépendances à l’exécution : PeerJS et deux polices libres (Barlow, Barlow Condensed).
  • Aucune image ni fichier audio : personnages, décors et effets sont de la géométrie vectorielle animée par squelette, sons et musique sont synthétisés en WebAudio. Le jeu pèse environ 420 Ko compressés, polices comprises.
  • Simulation déterministe à 60 Hz : pas de Math.random ni d’horloge, un générateur à graine uniquement. Les cinq premières cartes sont écrites à la main, les suivantes générées à partir d’une graine fixe.
  • Netcode lockstep à délai d’entrée avec somme de contrôle : avant le combat, l’hôte mesure la latence et la gigue puis fixe un tampon d’entrées commun. Les entrées passent sur un canal non ordonné, l’état du salon sur un canal ordonné.
  • Mise en relation et relais : la signalisation passe par le serveur public de PeerJS, puis les pairs communiquent directement. Pour les réseaux qui bloquent la connexion directe, le jeu récupère des identifiants TURN temporaires sur https://lp177.fr/ice (modifiable avec VITE_ICE_ENDPOINT) ; sans relais joignable, il se rabat sur STUN et l’indique. Le salon affiche la route choisie (directe ou relayée, UDP ou TCP), la latence et le tampon retenu.
  • Le build vérifie les types et lance deux validations (contenu et netcode) avant de produire docs/ pour GitHub Pages.

Capture d’écran

Jouer

Le jeu se joue dans le navigateur : lp177.github.io/MountainFighters. Pour jouer en ligne, il suffit d’envoyer le lien du salon : l’ami clique, choisit un nain et rejoint le combat.

En local :

npm install
npm run dev      # http://localhost:5173
npm run build    # build dans docs/

Un relais TURN fixe peut aussi être déclaré dans un fichier .env (voir .env.example) ; ces valeurs sont intégrées au moment du build.

Contrôles

ActionJoueur 1Joueur 2Manette
Se déplacerZQSD (WASD en QWERTY)FlèchesStick gauche / croix
Attaque légèreFPavé num. 1A / ✕
Attaque lourdeGPavé num. 2B / ○
SauterEspacePavé num. 0X / □
SpécialHPavé num. 3Y / △
GardeMajPavé num. .RB / R1
SaisirRPavé num. 5LB / L1
Ramasser / utiliserEPavé num. 4LT / L2
SuperTPavé num. +RT / R2
PauseÉchapÉchapStart

Double appui sur une direction pour un sprint ; garde au moment de l’impact pour parer. Saut + attaque légère donne un coup de genou volant, saut + attaque lourde un coup de pied qui met l’adversaire au sol.