30

Stage 4, un petit bout de code devient grand (Partie 1)

On approche doucement du scope fixé pour en finir avec la beta. Tout de même, Super Tilt Bro v1.0, ça enverrait ! Il reste quelques petites choses à faire : améliorer quelques animations, rééquilibrer quelques mécaniques et faire une quatrième arène... Sans spoiler, cette dernière arène va s'avérer être un mini projet à part entière, les congés du mois de mai ne seront pas du luxe.

L'idée de départ est simple. Il existe une arène avec des plateformes mouvantes, mais cette arène est volontairement difficile, il s'agit de réussir à rester en équilibre au-dessus du vide. Du coup, les joueurs occasionnels l'évitent, se privant de plateformes mouvantes. Faisons une arène plus simple avec des plateformes mouvantes. Ce sera juste un nouvel arrangement de plateformes, réutilisant du code existant, tout se passera bien.

Quelques minutes passées sur Super Smash Bros sont suffisantes pour trouver un arrangement sympa à jouer. Il s'agit de l'arène Mute City de Super Smash Bros 4. Il dispose d'une plateforme principale plus petite que d'habitude et de deux plateformes mouvantes qui ajoutent de la largeur à l'arène. Il n'y a plus qu'à tenter de reproduire cette idée dans Super Tilt Bro. En plus, ça va aller vite, je dispose d'un merveilleux script qui prend du JSON en entrée et écrit l'assembleur tout seul.

MBvmSf6.png
De gauche à droite :
The Pit : l'arène qui fait peur !
Mute City : le pod en bas sert de plateforme stable, les plateformes mouvantes suivent les virages
Le script : à partir de la description des plateformes, il génère l'assembleur d'une arène

Le format JSON des arènes de Super Tilt Bro est simple, mais l'écrire à la main reste désagréable. (C'est là que tout commence à barrer en c*uilles.) C'est l'occasion idéale pour améliorer mes outils. Tiled étant la référence open source, aucune question à se poser, la première étape est de définir comment organiser les informations. Après quelques tâtonnements, l'organisation suivante est arrêtée:

Les emplacements spéciaux (comme les points de spawn) sont placés dans un calque d'objets nommé "spots". Les plateformes sont placées dans un calque d'objets nommé "platforms" et peuvent être de type "hard" (on ne peut pas passer au travers) ou "smooth" (on peut passer au travers). Les éléments esthétiques sont des images alignées sur la grille. Enfin, tout calque inconnu est ignoré, ce qui est pratique pour dessiner le résultat final même si le moteur n'en a pas besoin.

1FMfd9z.png
L'arène dans Tiled, les décors gris sont ignorés, les scripts les recalculeront.

Comme Tiled permet d'exporter ses cartes en JSON (et que j'adore le JSON), il y a juste à faire un nouveau script pour convertir les fichiers exportés par Tiled en fichier d'arène pour Super Tilt Bro. Le processus est donc: Dessiner la carte dans Tiled, lancer plein de scripts et pouf on obtient une ROM.

Hcw7BI5.png
Le résultat de tous ces scripts, une nouvelle arène \o/

C'est magique, c'est facile, ça va super vite... Et ça m'a pris la journée de coder tous ces outils.

Il n'y a plus qu'à ajouter les plateformes mouvantes, avec du code déjà prêt. Ça va être vite-fait... Non ?
avatar

31

Stage 4, un petit bout de code devient grand (Partie 2)

Changement d'idée ! Les plateformes mouvantes c'est du déjà-vu. Pour ce niveau il faut un bonus apparaissant régulièrement, flottant au-dessus des joueurs, celui qui arrive à le casser gagne des super-pouvoirs.

qptX2as.gif
The Hunt : quatre jours de code, et encore un niveau dont je suis fier !

Voyez comme les mouvements de l'orbe sont souples. On est loin de "un mouvement sinusoïdal ça semble vivant". Pour obtenir cet effet, on utilise une autre de mes techniques favorites : les steering behaviours. Aucune idée de comment ça se traduit, appelons les simplement steering behaviours.

Les steering behaviours nous viennent principalement des recherches sur l'IA. Ils permettent de déplacer des objets de façon naturelle tout en visant certains objectifs. Comme un orbe qui voudrait se positionner entre deux joueurs sans passer trop prêt de chacun d'eux.

Une fois par frame, on calcule le vecteur de déplacement idéal de l'objet pour chaque objectif, puis on additionne tous ces vecteurs à la vélocité de l'objet. Ça nous donne une nouvelle vélocité qui respecte au mieux chaque objectif en prenant en compte l'inertie de l'objet.

kYQn9H7.gif
Steering behaviours : le vecteur du succès !

Ce qui est génial avec ce système c'est qu'on obtient un mouvement fluide, et surtout qu'on peut penser chaque objectif séparément. On peut créer des comportements particulièrement complexes en implémentant trois ou quatre fonctions super simples. Enfin, comme chaque comportement est indépendant, il est facile d'en ajouter ou d'en supprimer pour essayer différentes combinaisons. L'exemple illustré est ce que j'avais en tête en commençant, puis j'ai remarqué que c'était plus sympa de ne pas fuir les joueurs, mais juste d'essayer de se placer au-dessus d'eux, un changement très simple.

Voilà, bilan la nouvelle arène est prête et m'aura coûté mes vacances. Si vous pouviez y jeter un œil et me remonter vos remarques/bugs avant la prochaine release, je vous en serais éternellement reconnaissant. Les points à avoir à l'œil sont : la fréquence d'apparition de l'orbe, la puissance du buff, le mouvement de l'orbe (est-ce amusant d'essayer de l'atteindre ?). Voici une ROM de test : http://blabla.wontfix.it/Super_Tilt_Bro_Playtest(E).nes
avatar

32

33

Merci pour les explications des steering behaviours !
Très intéressant et bien illustré.
Faut que je teste tout ça asap smile
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

34

Changement de plan, perspectives chamboulées

J'ai un plan. Avec Super Tilt Bro. qui commence à ressembler à quelque chose, il faut peaufiner quelques animations, ajouter des effets ici et là et on peut appeler ça une version 1.0. Ensuite, produire un batch d'une petite dizaine d'exemplaires pour se donner l'impression d'être un vrai producteur de homebrew sans se ruiner. Enfin, le chantier de la 2.0 et de son nouveau moteur révolutionnaire peut commencer.

C'est super sympa de chercher à produire ses cartouches en petit batch. On passe beaucoup de temps à fouiller l'internet pour trouver des solutions économiques. Un boitier de cartouche seul, ça coûte facilement dans les 5€ (il y a des jeux entiers moins chers que ça !) Donc beaucoup de lèche-vitrine en ligne et de discussions avec des petits producteurs de circuits imprimés pour reproductions.

JhI2zWh.jpg
Tout ce qu'il faut pour faire des cartouches ! Il ne manque plus que le logiciel sad

Tout se présente donc bien, sauf qu'entre temps Glutock a décidé de dévoiler au monde un truc génial. Un module wifi greffé dans la cartouche ! De l'or en barre, du porn pour geek ! Vous imaginez un peu ce que donnerait Super Tilt Bro. en réseau ? Pas moi. Il faut que j'essaye pour voir !

On s'attaque peut-être à un gros morceau. On veut porter un jeu local en réseau, ce qui est réputé très casse-gueule. Le jeu en question est un jeu temps réel qui supporte très mal la latence mais doit rester jouable avec ~50ms de ping. Enfin, on est sur la NES, il faut faire très attention au budget CPU et RAM. Tant pis, c'est trop beau comme idée, on fonce tête baissée !

La première étape est de penser au protocole de communication entre les NES. Une nuit blanche et c'est réglé. Le protocole est composé de quelques messages simples faits pour être envoyés en UDP. Chaque NES compte le nombre de frames depuis le début de la partie (appelé timestamp). Quand le joueur appui sur un bouton, elle envoie un message avec le timestamp et l'état de la manette, puis continue le jeu normalement. Le serveur connait l'état de la partie. Quand il reçoit ce message, il calcule son impact sur l'état de la partie puis renvoie un message aux deux NES contenant le nouvel état et le timestamp associé. Enfin, quand une NES reçoit un état de la partie, elle le copie dans sa mémoire puis rejoue les frames entre le timestamp de l'état reçu et le timestamp courant.

mDKnR3k.png
Une conversation banale entre une NES et le cloud.

Ce protocole permet aux NES de faire de la prédiction, en l'absence de message du serveur le jeu continue et donc le lag est moins visible. Les algorithmes gourmands sont déportés sur le serveur, la NES n'a besoin de ne maintenir qu'un seul état de la partie, sa consommation de RAM est préservée.

Avec ce protocole définit, il y reste trois choses à faire : patcher un émulateur pour envoyer des paquets UDP depuis la ROM, implémenter le protocole dans la ROM, implémenter le serveur.

Patcher un émulateur est rapide. J'ai choisi Mesen, parce que celui-là je ne l'avais encore jamais patché. Il est en C++ avec une classe par mapper. Le mapper NROM a été vampirisé pour l'occasion, permettant l'envoi de paquets UDP suivant une interface super simple pour la ROM. L'idée est de prouver que Super Tilt Bro. en réseau est possible, pas de s'arracher les cheveux sur de l'assembleur utilisant une interface crédible.

Dans la ROM, un hook pour le protocole réseau a été mis en place. Ainsi le code du réseau est séparé du reste, c'est à priori une bonne organisation définitive. Le code en lui-même va au plus simple, pas de configuration, si on sait ce qu'on fait ça marche, sinon ça explose.

Il ne manque plus que le serveur. Et là c'est un gros bout. On part sur du C++ qui gère notre protocole et, surtout, qui est capable de simuler l'état de la partie. Le code de Super Tilt Bro. est tout sauf portable, c'est de l'assembleur pour un vieux CPU, utilisant des souvent astuces de roublard et parfois dépendant des registres de la NES. Trois options : recoder une grosse partie de Super Tilt Bro. en C++, faire tourner un émulateur NES ou adapter un émulateur 6502 pour pouvoir appeler les fonctions de Super Tilt Bro. depuis le C++. J'ai choisi de réimplémenter le jeu en C++, à défaut d'être le plus rapide à implémenter c'est ce qui semble cacher le moins de surprises.

C'est super long ! Mine de rien, tenter de recoder deux ans de travail en quelques jours c'est sportif. J'ai réussi à avoir un serveur fonctionnel tant qu'on se contente de courir. Si on fait autre chose, ce n'est pas implémenté, donc le personnage ne fait rien. Comme le serveur fait autorité, le résultat sur la NES est comme si on ne pouvait rien faire d'autre que courir. Le protocole n'est pour l'instant supporté qu'en partie, notamment le serveur est incapable de rejouer une commande arrivée en retard. Ces limitations sont énormes, mais on a enfin un truc qui marche sur un réseau local. L'avenir s'annonce radieux.

Woh bourdel ! Ça valait le coup de ne pas dormir !

Bilan, le matos pour faire les premières cartouches est là. Sortir une version 1.0 dans les mois qui viennent serait super. Avant toute chose on va améliorer le prototype réseau, même si ça n'a rien à voir, c'est trop cool. En améliorant la prédiction on pourra aller sur internet. En finissant de réimplémenter Super Tilt Bro. en C++ on pourra réellement jouer.
avatar

35

Ah mais grave ouais !!!
J'eu pensé à un autre truc mais je ne sais point si c'est possible sur NES: utiliser le port manette 2 pour lire/écrire => câble link entre 2 consoles (mais bon, du coup tu restes physiquement dans la même pièce).
avatarMatmook -- http://blog.barreteau.org
Twitter : @matmookJagware

36

A priori, en croisant OUT0 ET D0, on devrait pouvoir écrire une valeur en écrivant dans $4016 et la lire depuis l'autre en lisant $4017. Et ça serait bidirectionel, un bit dans chaque direction a tout moment.

Ce qui va être drôle sera de synchroniser les deux NES et de gérer le fait que tu sois obligé d'écrire dans le cable pour lire l'état de la manette 1 (OUT0 est commun aux deux ports manette). Rien d'insurmontable, ça pourrait être marrant à faire smile

Documentation sur le sujet :
http://wiki.nesdev.com/w/index.php/Controller_port_pinout
http://wiki.nesdev.com/w/index.php/Input_devices
avatar

37

Tu es décidément trop fort boing

Merci pour ce post qui vient compléter brillamment la vidéo que tu avais tweeté !
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

38

Internet, une latence sans pitié

Après beaucoup de temps passé à réimplémenter Super Tilt Bro. en C++ et un peu passé à rendre le serveur plus "intelligent", on a pu tester le jeu sur le vrai internet. Deux améliorations ont été nécessaires côté serveur à cause de la latence de 50~80 ms de nos connexions. La première est de gérer intelligemment les messages arrivant dans le désordre. Disons que les deux joueurs pressent un bouton presque en même temps, le joueur 1 le fait à la frame 23, le joueur 2 à la frame 24, rien n'empêche le message du second joueur d'arriver en premier, le serveur ne doit pas se laisser perturber. La seconde optimisation nécessaire pour que ce soit jouable sur l'internet mondial est de compenser la latence côté serveur. Au lieu de simplement calculer l'état courant de la partie, le serveur prédit quelques frames dans le futur avant d'envoyer son état aux NES. Cette prédiction compense le temps de transport, ainsi la NES reçoit l'état présent de la partie.

On teste l'internet, feat. Bjorn

Le bilan de ce réseau est "pas mauvais, peut mieux faire." Avec ces améliorations côté serveur, on peut jouer gentiment, c'est fluide et agréable. Les problèmes surviennent quand on commence à jouer sérieusement. En effet, quand un joueur lance une attaque, le message est envoyé au serveur, puis le nouvel état de la partie est envoyé à l'autre NES. Tout ceci prend entre 100 et 160 ms, soit entre 2 et 3 frames. Pour rester synchronisée, la NES qui reçoit le message n'affiche pas le début de l'attaque. Super Tilt Bro. étant un jeu particulièrement rapide et nerveux, ces quelques frames sont souvent très importantes, on a donc beaucoup de mal à suivre l'action dès que le rythme s'accélère.

Il y a plusieurs solutions à ce problème, je n'en ai encore essayé aucune. Une idée serait de ralentir le rythme du jeu. Si les attaques prennent plus de 4 frames à sortir, le lag serait beaucoup moins visible. Cette solution est dégueulasse, on peut changer le gameplay du jeu, mais le faire pour des raisons techniques, ça craint. Un classique est de ne pas avoir de serveur, le peer-to-peer enlève une étape et réduit donc le lag de moitié. C'est une bonne idée, mais c'est vraiment plus facile à dire qu'à faire, d'abord les techniques pour le mettre en place ne sont pas toujours fiables (cherchez "hole punching"), ensuite ça forcerait la NES à être aussi intelligente que le serveur actuel ce qui fait exploser les budgets CPU et RAM. Enfin, un autre classique est d'induire un lag en entrée. Quand le joueur appuie sur un bouton, le jeu ne le prend en compte que deux frames plus tard, mais envoie le message au serveur immédiatement. Il faut à tout prix éviter d'induire trop de lag en entrée sinon l'expérience s'en ressent, même en réseau local.

Voilà qui clôt pour l'instant l'épisode du réseau. Très bientôt je posterai à propos de la version 1.0 (sans réseau) et de la production de cartouches... Qui devraient être prêtes pour la RGC 2018
avatar

39

Version 1.0 et production de cartouches

Toutes les mécaniques sont là. Les quatre arènes sont implémentées. Une foultitude de détails ont été ajoutés. Particules, physique, intelligence artificielle, compression,... Super Tilt Bro. à largement dépassé son ambition initiale, qui était simplement de finir un tutoriel. On va donc aller jusqu'au bout...

wAplses.jpg
Super Tilt Bro. en vrai


Une édition physique ! Voilà qui bouclera définitivement le tutoriel smile Et tout devrait être prêt pour la RGC 2018 \o/

La version 1.0 de la ROM est presque prête. Margarita a préparé une superbe notice en un temps record. Tout le matériel nécessaire à la production de cartouches est là. Il n'y a plus qu'à finaliser la v1.0, flasher les ROMs, souder les composants (67 soudures par cartouche), tester chaque cartouche, imprimer/coller les étiquettes, imprimer/relier les notices, préparer les boites et, enfin, mettre les cartouches en boite. Bref, il y a de quoi s'occuper d'ici à la RGC, surtout que la plupart de ces tâches sont nouvelles pour moi.

Préparez-vous à m'entendre brailler fièrement que ce jeu entièrement brassé à la maison est ma meilleure cuvée smile
avatar

40

top

41

42

Super tout ça grin
Merci pour ces précisions !
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

43

La production de cartouches, comment ça se passe ?

On en est là. Les neuf cartouches produites pour la RGC-2018 n'ont largement pas suffit. Le jour de l'évènement, il n'y en avait plus qu'une en vente et elle est partie avant même que le stand soit posé o_O Après un petit sondage d'intérêt, il s'est avéré nécessaire de lancer une seconde série de 50 cartouches. Mais pourquoi est-ce si cool de faire des cartouches ? Et comment fait-on ?

La ROM de Super Tilt Bro. a toujours été disponible gratuitement. Le côté dématérialisé est très pratique, mais un jeu NES c'est plus que ça. En tant que joueur on aime posséder l'objet, le toucher, le caresser, l'enfourner dans... Enfin surtout associer un objet tangible au jeu. Quand on parle de Super Tilt Bro. ce n'est plus seulement un petit jeu de versus, c'est une cartouche bleue avec des orcs sur l'étiquette. Ça existe vraiment dans notre monde et pas juste sur la SD de notre Everdrive. En tant que développeur, tenir une cartouche terminée ça procure une grosse sensation d'accomplissement. On ne s'en rend pas compte pendant le développement ni même durant la production, mais quand on tient sa première cartouche, c'est magique. Et puis c'est l'occasion d'être imaginatif, de planquer des easter-eggs autre part que derrière un konami code.

Voici donc comment les cartouches de la première série ont été faites. Pour une cartouche, il vous faudra:

Pour la cartouche:
1 NES NROM board de chez Muramasa
1 condensateur 22µF
1 AVRCIC
2 EPROM 27C256
1 Boitier
Les étiquetes imprimables
Du papier photo
Du scotch double face

Note: Pour réduire un peu le budget, l'AVRCIC peut-être produit par vos soins. Il s'agit d'un ATTINY13A sur lequel on a flashé le firmware de Krikzz

Pour la notice:
2 feuilles A4 de papier couché double face 130 grammes
1 bombe de fixatif acrylique
Le manuel imprimable
Du fil à coudre pour jean

Pour la boite:
1 protège poussière de SuperGameLand

Commencez par produire la cartouche:

Récupérez le code source du jeu. À l'aide de l'assembleur XA et des instructions dans le fichier tilt.asm, construisez les fichiers tilt_prg.bin et tilt_chr.bin. Enfin, gravez ces fichiers, chacun sur une EPROM différente. Pensez à étiqueter vos EPROM pour ne pas confondre PRG et CHR.

Avec un fer à souder, soudez les composants sur le PCB. Le condensateur en "C1". L'AVRCIC sur "AVRCIC". L'EPROM PRG à droite. l'EPROM CHR à gauche. Enfin, dans le petit cadre "H-V" en haut, faites une petite soudure reliant le V et le connecteur du milieu.

kehWSPs.png
Un PCB avec tous ses composants.

À ce niveau, vous pouvez déjà essayer le jeu. Placez le PCB dans son boitier, insérez le tout dans votre NES et voyez si ça marche. Il y a de fortes chances que la LED de votre NES se mette à clignoter, comme pour refuser un jeu avec le mauvais zonage. Dans ce cas, appuyez sur RESET jusqu'à ce que ça marche (une dizaine de fois). L'AVRCIC a besoin de se configurer pour votre zone. Si ça ne marche toujours pas, vérifiez les étapes précédentes. Si la LED continue de clignoter vous avez un problème avec votre AVRCIC, si vous voyez un écran gris vous avez un problème avec vos EPROM. Dans tous les cas, vérifiez vos soudures et que vous n'avez pas inversé PRG et CHR.

Placez le PCB dans son boitier. Fermez le boitier. Vissez. Vous obtiendrez un cartouche utilisable à laquelle il ne manque plus que les étiquettes.

Imprimez les étiquettes sur du papier photo. Collez du scotch double face à l'arrière de celles-ci. Découpez-les et collez-les sur la cartouche.

cj5YZWp.jpg
Et voilà une belle cartouche tout à fait présentable.

Préparez la notice:

Sur le papier couché, imprimez la notice au format 10.5x10.5 centimètres. Soit exactement la largeur d'une page A4 pour une double page de notice.

Étalez les pages imprimées sur un plan propre, dans une pièce bien aérée. Appliquez une couche d'acrylique sur le recto. Laissez sécher une à deux heures. Appliquez une couche d'acrylique sur le verso. Laissez sécher.

Note: il est très important de porter un masque pendant que vous passez l'acrylique et de bien aérer la pièce. L'acrylique est mauvais pour vos poumons. Il peut même être mortel. Dans le doute, vous pouvez sauter cette étape. La couche d'acrylique sert juste à retarder le jaunissement du papier et le rendre un peu plus résistant à l'eau. Ça ne vaut pas votre santé.

Une foi l'acrylique séché, découpez vos doubles-pages. Vous pourriez les assembler à l'aide d'agrafes, mais vous aller faire de petites coutures pour remplacer les agrafes. C'est plus long mais beaucoup plus classe.

Hjk8B2N.png
Passer l'acrylique, découper, relier.

Assemblez le tout:

Placez la cartouche dans le protège poussière. Placez la notice à l'arrière de la cartouche, de façon à ce que le logo soit visible. Refermez le protège poussière. Vous voilà en possession d'un exemplaire de Super Tilt Bro.

6YnMhE3.png
C'est beau, et fait maison !

Différences avec la seconde série:

Dans cette première série, il y a du très bon. Les notices, en beau papier, reliées à la main, sont définitivement à garder. Il y a aussi des choses à revoir. Les étiquettes en papier photo sont plus du bricolage qu'une vraie solution.

Donc, pour la seconde série de 50 cartouches, on part sur des étiquettes en vinyle. On garde le côté brillant du papier photo, tout en ayant des étiquettes plus souples et agréables au touché.

Aussi, les PCB de Muramasa ont vu apparaître un nouveau concurrent entre les deux séries. Antoine "Glutock" Gohin, ou monsieur Twin Dragons, nous propose des PCB avec les composants soudés en usine. Ça évite de se farcir toutes les soudures et le rendu est plus propre.

Enfin, l'imprimante utilisée pour la première série est une petite imprimante personnelle qui avait le mérite de rentrer dans mon budget d'étudiant dans les années 2000. Grâce au bon papier, le résultat est loin d'être mauvais. Pour la seconde série on utilise une imprimante plus haut de gamme. Le rendu est encore meilleur.

Bilan:

Il est tout à fait possible d'obtenir de bons résultats avec de petits moyens et de l'huile de coude. En plus, ça a le mérite de porter fièrement la mention "brassé à la maison" puisque, en effet, tout est fait dans mon appartement smile

Bien que la seconde série ne soit toujours pas terminée, les cartouches officielles sont déjà presque toutes réservées. S'il y a des désistements, le surplus sera remis en vente. Mais bon, maintenant vous savez tout ce qu'il faut pour vous faire votre propre exemplaire !
avatar

44

C'est très clair et passionnant à lire ! Merci pour les explications ! smile

45

Trop bien ton poste Do It Yourself !
Merci smile
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

46

Mise en route de la v2, refonte des coordonnées

Maintenant que les cartouches de Super Tilt Bro. sont toutes livrées, il est temps de commencer à préparer la version 2. On commencera par s'attaquer aux gros chantiers d'architecture. Il faut faire disparaître les limitations de la v1 avant de faire un meilleur jeu. Commençons par le système de coordonnées.

La NES affiche des images d'une résolution de 256x240. Pratique! On peut décrire n'importe quelle position de l'écran en deux octets : un entier 8 bits non-signé pour la composante horizontale et un autre pour la composante verticale. Dans Super Tilt Bro. sortir de l'écran c'est mourir, la v1 est donc basée sur ce système simple d'un octet non-signé par composante.

Pour certains objets qui ont besoin de plus de souplesse, comme les personnages, on peut utiliser un deuxième octet que l'on nommera sous-pixel. On forme ainsi un nombre à virgule fixe, permettant de placer l'objet plus précisément et donc de lui donner une vitesse plus précise. On peut, par exemple aisément déplacer un personnage d'1.5 pixels par frame.

yiC6

Ce système fonctionne bien, mais a posé deux problèmes.

Le premier, technique et contournable, est le mélange ingrat d'entiers signés et non-signés. En effet, si on a deux points sur l'écran, soustraire les composantes de leurs positions permet d'obtenir un vecteur... Du moins d'après mes cours de math, car avec ce système on soustrait deux nombres non-signés. Ça se passe bien tant que le résultat est positif, mais un résultat négatif produit un overflow. On s'en sort toujours, mais c'est parfois galère.

Le deuxième problème, lui n'a pas pu être contourné et la v1 a dû sortir avec : si on est autorisé à sortir légèrement de l'écran avant de mourir, le jeu est plus agréable manette en main. Avec ce système de positionnement bien ancré partout dans le jeu (personnages, hitboxes, plateformes, particules,...), on ne peut pas simplement ajouter "vite fait" la notion de "hors de l'écran" pour mettre en place cette fonctionnalité. Super Tilt Bro. v1 ne comprend pas du tout la notion de "en dehors de l'écran". Quand on lui en parle, il est largué. D'ailleurs, pour lui on ne meurt pas "en sortant de l'écran" (ça ne veut rien dire), mais "si en se déplaçant vers la gauche, on finit à droite de notre position d'origine".

Pour résoudre ces deux problèmes, on change le système de coordonnées. Au lieu d'utiliser un octet non-signé par composante, on utilise cette foi un entier signé sur deux octets. On appelle l'octet de poids fort l'octet d'écran et l'octet de poids faible l'octet de pixel. Bien sûr pour les objets qui ont besoin de la précision supplémentaire on peut toujours ajouter un octet de sous-pixel

T5mE

Ce système permet donc de régler le mélange d'entiers signés/non-signés et de faire sortir les personnages de l'écran. C'est une belle victoire. En prime, on dispose de vraiment beaucoup de place. Un octet pour l'écran, ça fait 256 écrans. Si un jour on voulait implémenter un mode aventure, basé sur du scrolling, ça serait envisageable.

Forcément, ce changement à un coût. Stocker des positions demande plus de mémoire et les manipuler est plus gourmand en CPU. Heureusement pour le CPU, lors du refactoring des animations une grosse optimisation est passée, bien plus impactante que quelques additions sur 16 bits.

Ce changement a été fait dans le cadre d'un mini marathon pendant les ponts du mois de mai. Vous trouverez la ROM résultante ici : http://supertiltbro.wontfix.it/files/preview/Super_Tilt_Bro_marathon(E).nes

N'hésitez pas à me faire des retours à propos de l'impact sur la jouabilité, ou des rapports de bug.

Aussi, durant ce marathon, j'ai reporté mes progrès quotidiennement sur Twitter. Dites moi si le format vous plait. J'en referait certainement d'autres car j'y ai pris un pied incroyable.
avatar

47

C'est trop bien merci !
Le format "forum" est top avec un bel article et des explications imagées. Aussi, on peut le lire plus posé et l'info ne disparait pas dans d’innombrables tweets si on veut le reconsulter !
Le format "thread Twitter" est top car ça permet de retweeter et faire découvrir le projet et ses avancements à ses abonnés. C'est cool !

Les 2 formats sont bien !
Après sur Twitter c'est le must niveau visibilité je pense smile
Si en plus tu fais les 2 c'est vraiment génial ^^

Bon, par contre faut vraiment que je me remette à jouer...
Même Micro Mages je n'y ai pas retouché depuis ma partie de 30 minutes avec mon frère l'autre soir sad
Snif.
En tout cas je testerai cette nouvelle version à la prochaine occasion smile
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

48

Hey, merci pour les retours détaillés !

En effet les formats sont complémentaires. Coté développeur, écrire au fur et à mesure sur Twitter fait partie intégrante du marathon. Ça rend la chose plus vivante. Par contre il est impossible d'y caser le moindre détail, la limite de caractères est impitoyable. Sur le forum, c'est autre chose. Le moindre détail peut être développé jusqu'à faire un poste fleuve pour expliquer qu'on a ajouté un octet quelque part smile

C'est pas la première foi que tu exprimes des inquiétudes sur la visibilité offerte par le forum. Ne t'en fais pas. D'abord, mais c'est personnel, j'ai lancé ce topic moins pour la visibilité que pour avoir un endroit ou poster ce que j'avais à dire. On y écrit en français, vous êtes chaleureux et vous vous occupez de l'hébergement, le rêve ! Mais aussi, la visibilité est très bonne. Les meilleurs me lisent ici, je sais que vous êtes les meilleurs car je vous rencontre aux RGCs. Et puis, après avoir écrit un article pour ce forum, l'article peut être traduit en anglais et bombardé partout (ce que je devrais faire plus souvent). Bref, merci pour ce petit coin d'internet, je ne sais pas s'il plait à tout le monde, mais je m'y sens super bien !

Et oui Micro Mages, il faut y jouer ! Et avec son 4 joueurs, ça va être juste excellent sur les prochains événements
avatar

49

top

RogerBidon (./48) :
Et oui Micro Mages, il faut y jouer ! Et avec son 4 joueurs, ça va être juste excellent sur les prochains événements

Comme Super Tilt Bro wink
J'espère que tu reproposeras un tournoi !
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

50

Plusieurs personnages jouables dans Super Tilt Bro.

Voilà, le moteur de Super Tilt Bro. est capable de supporter plusieurs personnages. C'est une bonne tranche de boulot abattu, mais je crains qu'il n'y ait rien à montrer. Pas de ROM contenant des centaines de personnages et autant d'heures de jeu. C'est pour l'instant "juste" une possibilité offerte par le moteur. Et c'est bien de ça dont on va parler : quelles sont les difficultés d'implémentation et comment Super Tilt Bro. s'en sort.

aJjgOPc.gif
Bon, d'accord il y a bien un second personnage "jouable", Squareman le perso qui ne fait rien.

Mais pourquoi permettre plusieurs personnages ?

Réponse courte : parce que c'est trop coooool !

À vrai dire, permettre au joueur de choisir entre plusieurs personnages a été envisagé dés le début de Super Tilt Bro. Cependant, c'était un rêve inaccessible. Outre la masse de travail considérable, il faut tenir compte de la taille limitée de la ROM. Sinbad occupe 6 Kilo-octets, avec le reste du jeu, Super Tilt Bro. v1 ne dispose plus d'assez d'espace libre pour un second comme lui. Autre problème, la mémoire vidéo. La mémoire vidéo est aussi une ROM, qui contient 256 tiles, Sinbad en utilise 94. On ne pourrait pas y faire tenir les graphismes pour plus de deux personnages sans une grosse passe d'optimisation.

Mais les temps changent ! Super Tilt Bro. v2 est sur une plus grosse cartouche. 512 Kilo-octets au lieu de 32, ça donne des ailes. Quant à la mémoire vidéo, elle on ne peut pas l'agrandir de façon magique. Ce qu'on peut faire c'est mettre de la RAM à la place de la ROM vidéo. Grâce à ça, on peut n'y mettre que les tiles des personnages réellement utilisés. Et puis enfin, si Super Tilt Bro. v1 était l'occasion de voir ce qui pouvait être fait avec une NES, la v2 est l'occasion de repousser les limites !

Et puis bon... Plein de persos, c'est trop cool !

Et donc, comment fait-on fonctionner un jeu qui propose plein de persos ?

Le premier point à poser problème est le stockage des personnages. En effet, le CPU de la NES accède à une ROM de 32 Kilo-octets. Si on veut une ROM plus grosse, il faut tricher. L'astuce est d'embarquer une ROM plus grosse dans la cartouche. Le CPU ne pourra voir qu'une partie de cette ROM. À tout moment, on peut changer la partie visible de la ROM, ainsi on a accès à tout l'espace de stockage.

C'est l'idée du bank-switching. Concrètement, on sépare l'espace de la cartouche en blocs de 16 Kilo-octets (les banques). On peut donc faire tenir deux banques dans les 32 Kilo-octets visibles par le CPU. Une des banques est toujours visible par le CPU, on l'appelle la banque fixe. L'autre banque visible par le CPU peut être changée à tout moment.

K4DWo1K.png
La cartouche de Super Tilt Bro v2 est énorme !

La stratégie de Super Tilt Bro. pour le stockage des personnages dans différentes banques est simple. Toutes les données propres à un personnage doivent se trouver dans la même banque. Dans la banque fixe on stocke une table indiquant dans quelle banque se trouve chaque personnage. Ainsi quand on a besoin des données d'un personnage, on saura toujours les retrouver.

1Xo4S6s.gif
L'index stocké dans la banque fixe permet de savoir dans quelle banque sont les infos sur un personnage.

Le problème de la mémoire vidéo est traité différemment. Non seulement on ne pourrait pas y faire tenir assez de sprites pour tous les personnages, mais le système de banques poserait d'autres problèmes. Tous les personnages présents à l'écran doivent être visible en même temps dans la mémoire vidéo, le PPU en a besoin pour les afficher, or un système de banque ne permet pas un contrôle assez fin pour choisir deux personnages à afficher. La solution sera d'utiliser de la RAM vidéo. Au lancement de la partie on écrit les tiles des deux personnages sélectionnés au début de la RAM vidéo, et voilà !

Et ce n'est pas fini !

Bon, on a un moteur capable de gérer plein de personnages. La prochaine étape logique est de créer plein de personnages super stylés ? Eh bien non. Actuellement, créer un personnage signifie écrire beaucoup d'assembleur (pour coder ses attaques) et de binaire (pour ses graphismes et animations). C'est long, fastidieux et empêche de se concentrer sur le personnage lui-même. Il va donc falloir rendre ce processus plus simple.

La prochaine étape sera donc de créer des outils. D'abord un format de données pour stocker toutes les infos sur un personnage dans un fichier, qui sera automatiquement "compilé" en assembleur. Ensuite, ce qui serait super sympa serait un éditeur de personnage dans lequel on peut simplement dessiner les attaques du personnage qu'on veut créer pour générer une ROM jouable.

Enfin, une fois bien outillé, faire un second personnage sera envisageable. Non seulement ça sera plus simple qu'en assembleur/binaire, mais ça servira aussi d'épreuve du feu pour l'éditeur.

Bref, le but est de présenter un nouveau personnage pour la RGC-2019. Le timing semble bon, reste à voir si ça sera plus rapide ou plus lent que prévu fatigue
avatar

51

Trop bien tout ça.
Ça ira au niveau de l'équilibrage du jeu ? Tu prévois quelque chose ou tu penses mettre les mêmes attaques / hitboxs pour que tout le monde soit à égalité ?

Bon courage pour la suite smile
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

52

Merci, merci happy

Les personnages n'auront pas les mêmes attaques ni les mêmes hitboxes, ça serait dommage autant de code pour ne pas changer le gameplay.

Pour l'équilibrage, j'avoue manquer de culture. Je me souvient avoir googler des trucs du genre "équilibrage jeux de combat" et ce qui semblait ressortir c'est que ça demande beaucoup d'essai/erreur. Donc le plan va être de faire des persos, puis de les équilibrer en continu.

À vrai dire, avec un perso ça marche déjà comme ça, on remarquera que dans la v1.0 le bouclier de Sinbad a une petite animation de dissipation du bouclier, animation absente de la beta. Durant cette animation le joueur ne peut rien faire mais peut se prendre des coups. L'ajout de cette animation est un équilibrage, le bouclier était trop puissant. Sans elle, quelqu'un qui met le bouclier pour rien peut simplement l'enlever et se remettre à courir. Avec elle, quelqu'un qui met le bouclier pour rien se retrouvera forcément vulnérable un court instant.

Si quelqu'un a de la lecture sur l'équilibrage de jeux asymétriques, et de versus fighting en particulier, je suis preneur. Ça sera mieux que de tout faire au pifomètre.
avatar

53

Je vais regarder ça, mais oui il me semble que c'est une partie un peu compliquée...
De toute façon il y a toujours des "low tier", "top tier" etc mais faut un minimum d'équilibrage quand même. Que l'écart ne soit pas trop grand entre les persos.

Ça va demander pas mal de parties tests à 2 joueurs. Faudra pas hésiter à nous solliciter smile
Je connais quelques joueurs de Smash aussi. Ils seront à la RGC, je les aiguillerai vers ton stand pour que tu es des premiers retours déjà !
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

54

Merci pour l'aide. En effet, quelques sessions de playtest intensifs seront à prévoir, ça va considérablement augmenter mon budget bière smile
avatar

55

Haha wink
C'est ça les jeux brassés !
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

56

Encore un gros merci pour l'effort à alimenter ce sujet ! smile

57

Un jeu moddable, carrément !

Pour finir le dernier article, nous disions que pour implémenter facilement des personnages, il fallait un format adapté. En effet, quand on fait un personnage pour un jeu, on veut le designer, le dessiner et parfois aussi implémenter quelques trucs spécifiques. On ne veut pas se soucier de choses propres au moteur de jeu, comme cette histoire de banques.

La solution est simple : rendre le jeu moddable

Plus précisément, on oublie le code. On définit tout ce qui fait qu'un personnage est unique : ses animations, ses hitboxes, l'effet de ses coups spéciaux,... On crée un format de données facile à éditer qui contient tout ça, ça sera la base de notre mod. Au moment de compiler le jeu, un script pourra lire ces données et faire le nécessaire pour intégrer les personnages au code du jeu.

lgEycQH.png
Structure d'un mod pour Super Tilt Bro.

Dans le cas de Super Tilt Bro. le format choisi se repose sur deux pierres angulaires : JSON et GIF. JSON permet de décrire les informations hiérarchiques, comme "c'est un mod qui contient un personnage qui contient une animation d'attaque dont la hitbox est très puissante". Pour GIF, je ne vous ferai pas l'affront d'expliquer que c'est un format d'image, mais j'appuierai sur une qualité souvent oubliée : c'est un format d'image basé sur des palettes de couleurs. Les graphismes de la NES étant également palettisés, les GIFs sont idéaux pour être convertis en sprites.

F0sMLO3.png
Compiler un mod revient à le convertir en assembleur et l'intégrer au code du jeu

Avoir ce format de mod c'est une bonne étape, on n'a plus à se soucier des besoins du moteur de jeu. Mais bon, écrire du JSON à la main c'est particulièrement désagréable. Pour pallier à ça il va nous falloir des outils.

Outillons-nous

L'outil idéal serait un éditeur de mod graphique, en HTML5, facile d'utilisation, couvrant l'ensemble des fonctionnalités du jeu et avec... OK, on arrête là. Peut-être que quelqu'un aura un jour le temps de faire un truc aussi génial. En attendant, réutiliser des choses existantes c'est cool.

Je travaille énormément avec The Gimp, l'idée a donc été de l'utiliser comme interface graphique. En suivant une hiérarchie de calques bien définie (toutes les animations sont dans le groupe "anims", les hitboxes dans des calques nommé "hitbox",...) on peut faire un script qui lit le fichier et le convertit en JSON+GIF. Ainsi on dessine dans un éditeur d'image et non dans un affreux mélange de JSON et d'images.

Parlons d'Open Raster. The Gimp enregistre ses fichiers en XCF, Krita utilise le format KRA, Photoshop PSD. Tous ces formats ont en commun de se concentrer sur le support de toutes les fonctionnalités de leur éditeur, même au détriment de la simplicité. Quand on veut échanger des images avec des calques, on utilise généralement PSD car, même si c'est le pire d'entre tous, c'est le seul universellement reconnu. Open Raster, est né des engueulades entre les communautés de The Gimp et Krita sur la question "qui doit supporter le format de l'autre ?" Du coup, il prend le problème autrement, c'est avant tout un format d'échange, il est simple et supporte la base commune : une image constituée de calques. Quand on dit simple, c'est simple. Il a été trivial lire la spec et écrire un parseur pour les besoins de Super Tilt Bro. Donc techniquement le script supporte les fichiers Open Raster et n'est aucunement dépendent de The Gimp. Pour résumer : Open Raster c'est le feu !

Petite note, on a simplifié le problème étape par étape. Bilan, avant on avait de l'assembleur et on en faisait une ROM. Maintenant ça ressemble plutôt à ça : on bosse dans The Gimp, on convertit l'image en Open Raster, que l'on convertit en JSON, qui deviendra de l'assembleur pour enfin faire une ROM. Au final, c'est simple à utiliser puisqu'on dessine un personnage et des scripts font le reste. Pour limiter les problèmes incompréhensibles, les scripts en question font plein de vérifications. Ça permet de détecter les erreurs au plus tôt dans la chaîne. On n'a absolument pas envie d'avoir un message d'erreur de l'assembleur quand on a mal nommé un calque, ou pire, une ROM valide mais qui crash de temps en temps.

2a4KsQ9.png
Notre chaîne de construction s'est étoffée

Maintenant et plus tard

Super Tilt Bro. est moddable ! Victoire ! Si vous êtes du genre à ne pas avoir peur de recompiler un truc, vous pouvez très simplement ajouter une moustache aux personnages présents dans le mod officiel

Pour l'instant seuls les personnages sont moddables, mais les arènes sont dans le viseur smile
avatar

58

Petite addition: on m'a demandé de montrer quelque chose de plus concret... Alors voilà :

avatar

59

Trop trop trop bien.
Merci aussi pour la vidéo.

J'ai déjà trop de projets..... ce n'est pas très sympa ce que tu fais là T_T

(Franchement c'est excellent !!)
avatar@originalfei
In pixels we trust.
ORE WO DARE DA TO OMOTTE YAGARU !

60

Et c'est reparti !

La base de code commence à se stabiliser et mine de rien, le jeu est mieux qu'avant. Ça serait con de n'en faire profiter que les geeks qui le recompile depuis le dépôt github. Donc voilà, petit message pour annoncer qu'on relance le cycle ALPHA -> BETA -> release. Avec cette première ALPHA, toujours disponible gratuitement ici : https://sgadrat.itch.io/super-tilt-bro.

Ce que j'entends par ALPHA, c'est que le jeu est toujours en gros chantier. Il est jouable, mais il y a plein de choses qui devrait arriver au fur et à mesure des ALPHAs : le support du réseau, plus de musiques, de meilleurs bruitages,... En fait, à peu près tout ce qui me semblera cool, qui vivra verra smile



Changements notables par rapport à la version 1.1 (celle sur les cartouches):

* Un nouveau perso jouable
* Nouveaux graphismes par Martin Le Borgne, qui a bossé sur Twin Dragons (ce mec est super cool !)
* On peut descendre des plateformes en appuyant brièvement sur bas
* On peut sortir de l'écran sans mourir, les limites sont juste un peu plus loin
* L'IA est un peu moins conne (elle arrive enfin à nous frapper si on ne bouge pas)
avatar