L'ARPG multijoueur en navigateur
Un monde bâti, une base qui se souvient, un serveur qui répond, un websocket qui pousse — et tes deux joueurs dans le même navigateur.
42 secondes · sous-titres Français inclus · 8.6 Mo
Les 7 trucs que tu vas savoir faire
Leçon 12 : L'ARPG multijoueur en navigateur
Regarde la leçon (42 s) : un monde bâti, une base qui se souvient, un serveur qui répond, un websocket qui pousse — quatre étapes, et ton ARPG tourne dans un onglet.
Bâtir le monde, case par case
Écris `cellule(x, y, sol)` : une case du monde — un Hash avec `"x"`, `"y"` et `"sol"` (ex: `"herbe"`). Le monde 8-bit commence par UNE case.
La base qui se souvient
Écris `charge(rows, id)` : lire la base — `rows` est un tableau de lignes Hash (avec `"id"`), renvoie LA ligne dont l'id vaut `id`, sinon `nil`. Sans ce lire, la partie recommence à zéro.
Le serveur répond aux routes
Écris `route(chemin)` : le petit routeur — `"/joueurs"` → `:joueurs` · `"/monde"` → `:monde` · `"/parties"` → `:parties` · tout autre chemin → `nil`. Le serveur ne fait QUE ça : un chemin, un symbole.
Le websocket diffuse les coups
Écris `evenement(msg)` : le serveur reçoit `msg` (un Hash avec `"type"`) — `"tire"` → `:inflige` · `"parle"` → `:diffuse` · tout autre type → `:ignore`. Le websocket ne fait que ça : type → action.
Livrer à BON acteur
Écris `remets?(element, acteur)` : un élément venu de la base porte `"pour"` (un id) et `"role"` (`"pnj"` ou `"joueur"`) ; l'acteur porte `"id"` et `"role"`. true SEULEMENT si l'id correspond ET le rôle correspond — au bon joueur, au bon PNJ.
Leçon 12 : OK
Sans aide : `transfert(rows, id, acteur)` — 1) cherche la ligne `id` dans la base `rows` (absente → `false`) · 2) livre seulement si `"pour"` == `"id"` de l'acteur ET `"role"` == `"role"` de l'acteur. Le reste, c'est `false`.
📄 La feuille de chute
imprime-la, colle-la à ton écran, fais semblant que c'est ton idée📄 Cheat sheet — L'ARPG multijoueur en navigateur (monde · base · flux · websocket)
Un ARPG 8-bit qui tourne dans un onglet, c'est 4 étapes : bâtir le monde, le retenir dans une base, répondre aux appels, pousser les coups — puis livrer chaque élément au BON acteur.
Les 4 étapes du trajet
case → base → route → websocket (puis : livraison au bon acteur)
cellule() charge() route() evenement()
1. Le monde : des cases, pas un moteur
def cellule(x, y, sol)
{ "x" => x, "y" => y, "sol" => sol }
end
cellule(2, 5, "herbe") # => {"x"=>2, "y"=>5, "sol"=>"herbe"}
Le monde entier = un tableau de ces hashes (leçon 6 + leçon 8, revues). Le tileset vient après — d'abord les données.
2. La mémoire : la base qui se souvient
def charge(rows, id)
rows.find { |r| r["id"] == id } # la ligne… ou nil
end
Entre deux parties, la base est la seule chose qui survive à l'onglet. Tu charges, tu joues, tu sauves : trois appels, et le monde a une mémoire.
3. Le flux : un chemin, un symbole
case chemin
when "/joueurs" then :joueurs
when "/monde" then :monde
when "/parties" then :parties
else nil # inconnu : le serveur dit non
end
Une requête n'est rien d'autre : le client crie un chemin, le serveur répond par un symbole
(ou par nil — un 404 honnête).
4. Le websocket : type → action, poussé
case msg["type"]
when "tire" then :inflige # le serveur applique…
when "parle" then :diffuse # …et RETRANSMET aux autres
else :ignore # pas du jeu : on jette
end
La différence avec la route : c'est le serveur qui parle en premier. Le socket reste ouvert, les coups partent à tout le monde en direct.
5. La livraison : au bon acteur, jamais « presque »
def remets?(element, acteur)
element["pour"] == acteur["id"] && element["role"] == acteur["role"]
end
Un élément venu de la base porte sa destination (pour) et son public (role : "pnj" ou
"joueur"). Les deux conditions — l'id seul livre au mauvais PNJ, le rôle seul livre au
premier venu. C'est le && du tri multijoueur.
Le tour complet (ce que fait ton serveur par message)
def transfert(rows, id, acteur)
el = rows.find { |r| r["id"] == id } # 1. la base
return false unless el # 2. rien trouvé → rien ne part
el["pour"] == acteur["id"] && el["role"] == acteur["role"] # 3. bon destinataire
end
Base → recherche → double condition → livré. Cinq lignes de Ruby pour tout un back-end de MMO. (Le vrai, en plus : persistance, ids secrets, latence — mais la forme est celle-là.)
À ne plus jamais dire
"il faut un moteur de jeu pour faire un multijoueur"→ une base, une route, un socket"le serveur décide de tout"→ il décide de CE QUI EST VRAI : la base dit qui a quoi"websocket = magie temps réel"→ uncase/whensur les messages, poussé en boucle
SlopCourse — du slop au code propre.