Contre-Frappe
un shooter façon Counter-Strike, écrit de zéro en Rust
Client, serveur dédié autoritaire, bots, GOTV, éditeur de maps et launcher, une seule base de code moteur, toujours en cours.
- Tout, moteur, netcode, bots, outillage, ops
- Rust · Bevy · lightyear · Tauri · Fastify · Kubernetes
- En cours, jouable en solo contre les bots
Le problème
Je voulais comprendre de quoi est réellement fait un shooter compétitif, pas en lisant mais en le construisant : un déplacement qui ressemble à Counter-Strike, un serveur qui a le dernier mot, des adversaires contre lesquels ça vaut la peine de jouer, et toute la machinerie autour du jeu (mises à jour, comptes, résultats de match, spectateurs) sans laquelle un vrai jeu ne sort pas.
Commencé fin 2024 comme une petite expérience Bevy, redémarré deux fois, c'est devenu ceci : un workspace Cargo de 29 crates, environ cent mille lignes de Rust, près d'un millier de tests, et une règle : chaque pull request vient avec une entrée dans le journal du projet.
Ce que j'ai construit
Un workspace en couches où chaque crate ne dépend que des couches inférieures : types partagés et formats de maps tout en bas ; physique, armes, rounds et squelettes au-dessus ; joueur, combat, économie et cœur réseau ; puis IA des bots, effets, son spatial, spectateur, démos et voix ; et au sommet les binaires : le client, un serveur dédié headless d'environ deux cents lignes, un éditeur, et un petit serveur MCP qui permet à un assistant d'éditer les maps.
Le réseau est un pont entre événements Bevy et messages, si bien que le HUD, le son et les effets ignorent s'ils sont en ligne. Le client prédit son propre joueur et interpole les autres à 64 ticks par seconde ; la compensation de lag garde ~300 ms d'historique de positions par joueur et rejoue les tests de tir à ce que le tireur a réellement vu. Autour du jeu : un launcher Tauri avec connexion Steam et mises à jour par canal, un backend Fastify qui enregistre les serveurs, consigne les rounds et lance des serveurs de match à la demande, et un relais GOTV qui rejoue les ticks avec 90 secondes de délai aux spectateurs et à un viewer web.
Les bots ont reçu le plus de rigueur : d'abord un harnais de mesure (parties bots seuls, métriques, résumé écrit), puis quatre phases publiées chacune avec ses chiffres avant/après : blocages par manche de 28 à 5, précision de 3 à 20 %, désamorçages de zéro à 44 %, avec des profils de difficulté qui ordonnent réellement les résultats.
Ce que j'ai appris
Que « une logique de jeu, trois modes réseau » vaut toutes les contraintes que ça impose : le solo n'ajoute aucun plugin réseau, et les systèmes prédits du client appellent exactement les fonctions de physique que le serveur exécute. Que les petits pièges d'un moteur (une caméra HDR jamais effacée, un auditeur audio sur la mauvaise caméra, des hitboxes à l'échelle 0,01 de Mixamo) coûtent plus de soirées que le netcode. Et que mesurer avant de changer (un harnais avant une refonte, des chiffres avant une affirmation) est la seule raison pour laquelle les bots sont devenus meilleurs plutôt que différents.
“La même fonction de physique tourne sur le client et sur le serveur ; c'est ce qui fait converger la prédiction.”Homelab GitOps