Deuxième étape, une inspection systématique des listes d'animations maintenues par l'Engine lui-même histoire de s'assurer qu'il ne reste aucune référence à un objet libéré (c'est désormais facile, puisque chaque objet libéré se voit écrasé par des 0xfefefefe et que sa mémoire n'est pas ré-attribuée lors du test). Me voici armé pour tester les enchaînement de niveaux, mais jusqu'à un certain point seulement: au bout de quelques itérations, la mémoire disponible pour le test aura été complètement utilisée. Allez, je devrais pouvoir passer aux chargements-suite-à-une-fin-de-niveaux dans le courant de la semaine, et étudier les "script reset" expérimentaux supposés accélérer les chargements de niveaux.
Monday, January 25, 2016
Leakage: 0%
Deuxième étape, une inspection systématique des listes d'animations maintenues par l'Engine lui-même histoire de s'assurer qu'il ne reste aucune référence à un objet libéré (c'est désormais facile, puisque chaque objet libéré se voit écrasé par des 0xfefefefe et que sa mémoire n'est pas ré-attribuée lors du test). Me voici armé pour tester les enchaînement de niveaux, mais jusqu'à un certain point seulement: au bout de quelques itérations, la mémoire disponible pour le test aura été complètement utilisée. Allez, je devrais pouvoir passer aux chargements-suite-à-une-fin-de-niveaux dans le courant de la semaine, et étudier les "script reset" expérimentaux supposés accélérer les chargements de niveaux.
Tags: guru meditation, level2, unit test
Sunday, January 17, 2016
When the player sees the challenge
because some rings can't be obtained in one play through, the encouraging function of the rings becomes diminished. [...] Instead of saying "you can do it, keep trying," they say, "too bad you missed. better luck next time."I ultimately got the true meaning of that thought while watching "Super Mario Fixer, episode 2" and see how KirbyKid played it, how he pushed effort into getting all the coins doing only one jump per platform, without going backwards. An exercise that may sound futile at first but that he describes as "recognize the challenge for themselves and let the player go for them".
Vous vous souvenez de Kirby Kid et de ses précieux commentaires sur le gameplay de ce qui devait devenir School Rush ? Un que je n'ai toujours pas pris en compte -- parce que je n'en comprenais pas la pleine mesure -- c'est la nature "généreuse et dense" des bonus sur les niveaux de School Rush. Forcément, il y en a assez bien, entre autres parce que c'est un enfant de 4 ans qui a choisi où les placer.
Où est le problème donc ? Eh bien, voyez-vous, si les bonus sont bien positionnés, ils peuvent proposer des façons alternatives de parcourir le niveau, par exemple "d'une traite, sans faire demi-tour ni s'arrêter mais en prenant tout de même tous les bonus". Ça représente une sorte de challenge supplémentaire que le joueur aguerri peut se fixer lui-même une fois que "finir le niveau" n'est plus un challenge intéressant pour lui. Mais pour se faire, il faudra veiller à ce que chaque pièce soit placée avec précision, pour qu'il n'y ait pas besoin de plusieurs passages pour être sûr de les ramasser toutes.
I want to have two ways of playing School Rush. One is power-play, rushing through. The other is exploring and experimenting. I can use some bonuses to tease the explorer and reward her. I can use some other bonuses to tease the rusher and reward him. Because I don't have a single coin, but multiple bonuses. I can have e.g. the "A" letters show the path for rush-and-be-amazing, and other letters for exploring places that require to do multiple pass over the level.
Tags: designclass, guest star, level design, mario
Sunday, January 10, 2016
100 bytes for a level
Il m'aura fallu me promener dans le code désassemblé de Super Mario Bros 1 pour finir par y croire. Oui, sur cette cartouche de 40KB, les niveaux sont extrêmement compacts. Oui, la technique pour en faire le rendu est à la base de ce que j'avais observé avec l'éditeur pour NSMB: bien que le hardware travaille avec des "tiles", le niveau est décrit par une série de commandes (un byte de coordonnées, un byte indiquant le type de commande et éventuellement une taille). On aura ainsi des "un tuyau de 3 blocs de haut" puis "une rangée de 5 briques" et "un escalier de hauteur 3". Voire même "un trou dans le sol de largeur 4". Pas de "patterns extensibles" derrière ces codes, mais directement du code assembleur!
Les buissons, nuages, le sol sont eux décrits sur une autre couche qui est utilisée en premier lieu pour remplir la zone mémoire sur laquelle le niveau sera ensuite dessiné.
L'équipe RD4 aura profité au maximum du fait que le jeu ne fait pas marche arrière: le niveau est encodé écran par écran, et les coordonnées des objets sont données à l'intérieur de l'écran en cours. Un marqueur est ajouté aux objets qui se trouvent sur un nouvel écran par rapport à leur prédécesseur. (I AM ERROR) Il faudra attendre que SMB3 embarque une RAM additionnelle dans sa cartouche pour que le jeu puisse se souvenir des blocs déjà cassés et des pièces collectées, rendant ainsi possible une navigation plus libre dans le niveau (/I AM ERROR).
Un monde de différence, donc, avec le stockage brutal d'un tableau de MxN éléments que j'utilise dans LEDS (avec des niveaux de 32 ou 64KB. Plus gros que l'entièreté du jeu SMB1, donc), mais qui me permet en contre-partie une souplesse totale pour que les livres ne soient pas tous exactement les même. Allez, apparemment, une simple compression .zip pourrait réduire les niveaux à une taille d'environ 8KB.
Tags: asm, level data, mario, NES, tiled
Tuesday, January 05, 2016
10 ans de DS
Voilà. Il y a 10 ans, je déballais ma première DS. Juste un an après, je démarrais le projet "dsgametools" sur sourceforge. Bonne année 2016 à tous. J'espère parvenir à finaliser "School Rush" cette année ^_^ Le prochain projet de Bilou "Infinite Pyramid" a déjà commencé à me faire cogiter.

one year from gameplay sketch to game release one year from engine test to gameplay sketch we have most of the GFX done within the first year.
Wednesday, December 30, 2015
Je peux améliorer mon C++
Grande différence entre mon "nouveau" boulot (depuis Mars 2014) et mon ancien poste universitaire: ici, il y a des revues de code. Et mes collègues "Hergé et Jigé" ont un sacrément haut niveau en C++ comparé au mien. Alors autant profiter de mes deux semaines de "Super Papa Bros" pour essayer de remanier le code de mon moteur de jeu, le rendre plus fiable, plus lisible, et peut-être plus efficace.
J'avais introduit un mécanisme de gestion de mémoire inspiré du cours "compilateurs" : le "tank", avec un seul bloc de mémoire qui est découpé progressivement en sous-blocs qui auront tous la même durée de vie. L'ennui principal, c'est que ce "tank" n'a aucun moyen de retenir quels objets ont été créés ni d'appeler les destructeurs en fin de cycle. Du coup, tout objet "standard" présent dans les morceaux du tank sont une fuite de mémoire potentielle.
Parmi les "nouveaux trucs" appris cette année qui pourront m'être utiles, il y a la fonction "foreach", les fonctions template (et en particulier leur utilisation pour faire de la programmation assertive), les namespaces anonymes, et les structures-internes-pour-masquer-l'implémentation.
Let me collate a few C++ tricks I practiced this year and hope to use in my hobby tools/game engine to improve them.
If it make sense to have a function applied on all members of a collection, foreach can help:
- for (vector<Tire>::iterator it = wheels.begin(), e = wheels.end(); it != e; it++) {
- checkPressure(*it);
- }
+ for_each(wheels.begin(), wheels.end(), checkPressure);
template<typename T>
void assert(T a, T b, const std::string msg) {
if (a != b) throw AssertException(msg);
}
+ assert(myCar, TimeTravellingDelorean, "timed' out");
-assert<Car>(myCar, TimeTravelling ...);;
getLibraryPath<sizeof(int)>():
template<int> path getLibraryPath();
template<> inline path getLibraryPath<4>() {
return "/usr/lib32";
}
template<> path getLibraryPath<8>() {
return "/usr/lib/x86_64-linux-gnu";
}
template<> must be out of the class block and have additional MyClass:: token.
You don't need to declare your functions
static to avoid interference with other translation units of the program. Simply put them in an anonymous namespace.You don't need to explicitly track the "object setup sequence" with an init_level if you can do it with contents of the regular members of the objects,
Car::~Car() {
- switch(init_level) {
- case TIRES_MOUNTED: RecycleTires();
- case ENGINE_INSTALLED: RecycleEngine();- // FIXME: what do you do for default: ?- }
+ if (tires!=UNDEF) RecycleTires();
+ if (engine!=UNDEF) RecycleEngine();
You can have compact structure initialization with (optionally-)named fields but it must be *trivial*, e.g.
- you may not swap the order of components;
- you may not omit a field if there are other field after it
- but you *can* omit items at the tail of the description
- copy constructor :
Car(const Car &that) : engine(that.engine), tires(that.tires) {} - comparison operator :
bool operator==(const Car &that) { return that.tires==tires && that.engine==engine; } - ostream-compatibility: this requires a additional
std::ostream& operator<<(std::ostream& os, const Car& that) { os << "powered by " << engine << " on " << tires; return os; }function. Note that it is *not* a member of the Car struct/class and that it will need to be declared friend of the Class in case of a class.
throw new std::runtime_error(..) is caught by catch (...) { releaseResources(); throw; }, but not by catch(const exception& e). That latest one only catch stack-allocated exceptions, e.g. throw std::runtime_error(...);. Reading more on this I should.
namespace ds = PPPTeam::LibGEDS is the way to say import PPPTeam.LibGEDS as ds. And that ostream & operator << (ostream &out, const Complex &c) is the way to tell how the class 'Complex' should be printed.
Oh, and I shouldn't use std::unique_ptr on stack-allocated object. ever. unique_ptr will eventually call free on the pointer it holds.
Tags: allocation, coding, cxx
Tuesday, December 22, 2015
Usage: 15% ; Leakage: 12%
Bon, bin les premiers résultats de l'analyseur mémoire intégré à mon système de test-de-code-DS-sur-x86 sont précis, mais aussi assez effrayant: 12% de la mémoire allouée lors de l'initialisation de l'écran-titre ne sont pas rendus à la fin du niveau. Dans un cas pareil, la mémoire de la DS (4Mo) finit systématiquement par être saturée après un certain temps d'utilisation du jeu, ce qui ce traduira fort probablement par un crash.
Allez, joyeuses fêtes à vous aussi. (Et, euh, non, n'espérez pas trop une version "spéciale Noël" de School Rush avec de la neige sur les bancs et des bonnets à ponpon sur les gommes sauteuses, du coup)

Tags: allocation, coding, unit test
Monday, December 21, 2015
Rayman Designer
Quelque-part en 1997, Ubisoft sort "Rayman Gold", avec un éditeur de niveau. Curieusement, je passe mon tour. Pas trop envie d'acheter une 2eme fois le jeu que j'ai toujours pour pouvoir avoir l'éditeur de niveau ? Pas trop envie de me contenter de faire des maps dans un univers qui n'est pas le mien et d'en être réduit aux seuls ennemis déjà existant dans le jeu ? J'avoue que je ne saurais plus trop dire.
First, the core gameplay is different, and the player is asked to collect every ting (read "golden coin" if it was a Mario game) to reveal the exit of the level. Okay, I love it when you have something more to do than reaching the exit, but being forced to grab every whatever to complete the level always felt annoying. I already found it lame near 2001 when I played Rayman II and discovered that without collecting all the tings of the games I couldn't access the last levels. But here you have to collect them all *level per level*. Oh, okay, you can select levels freely, but still. And the "colored tings that open gates" felt artificial, even more abstract than typical "keys and locks" and much less integrated than Commander Keen's coloured keys.
Mais j'étais curieux l'autre jour de voir un peu à quoi pouvait ressembler les niveaux intégrés dans l'édition "Rayman Forever" -- niveaux de fans repris sur galette. Sont-ils du même tonneau que les missions impossibles de Mario Maker ?Pas exactement. Pas ceux que j'ai vu, en tout cas. Par contre, il y a usage abusif de la "potion magique qui te donne des aileuus", présente presque systématiquement, et contrairement aux designers de Ubisoft, qui prenaient soin de guider le joueur vers la suite du niveau une fois qu'on a ramassé le "ting-qui-fait-apparaître-un-pont-quelque-part", on risque ici de devoir ré-explorer tout le niveau chaque fois qu'on entend la petite fanfare qui annonce que quelque-chose a changé. Bof pour moi, donc.
Tags: designclass, game design, game maker, rayman




Vote for your favourite post
