Wednesday, January 31, 2018

School Touch?


My brother comes back again with the idea of School Rush on Android platform. Porting issues set aside, I guess he means "on the bare device", and not assuming one bluetooth dpad and buttons attached, Nintendo-switch-like. That implies converting touch and taps and gestures into valid SNES inputs.

Mon frangin n'en démord pas: la plate-forme qu'il faudrait attaquer pour un portage de School Rush, c'est les smartphones & tablettes. Androïd, donc. Au-delà de l'aspect purement "portage", ce qui va manquer le plus sur Androïd, ce sont bien sûr les boutons et le D-PAD. Je doute qu'il avait en tête qu'on se bricole quelque-chose avec des contrôleurs bluetooth en plus du téléphone lui-même. Bon, la bonne nouvelle c'est que la DS elle-même a un écran tactile. On pourrait donc imaginer faire une version "School Touch" pour essayer le potentiel du jeu avec cette interface-là avant de se lancer dans des longues soirée de méditation sur les interfaces Androïd.

Good news: the DS also has a touchscreen. So as a preliminary test, I could just try to use the touchscreen to see how the game feels. Imho, a specific area to emulate the d-pad on having to hold a finger on the screen as we do for the (A) button would be terrible. No one could complete the game in those conditions. I've tried that with e.g. Sonic 2 back then and it was really degrading the gameplay.

Ce qui est déjà clair, c'est que je ne ferai pas une espèce de pad virtuel à travers l'écran tactile. C'est généralement une catastrophe. Il faudra plutôt que j'aille vers une sorte de mélange entre "platform panic" de Nitrome (glisser à gauche ou à droite pour changer le sens de la course avec Bilou qui continue à courir tout seul) et Phantom Hourglass (tapper un monstre pour utiliser les mains de Bilou)

Ideally, we should be constantly running when playing School Rush. That means in the School Touch game, Bilou should start running forward as soon as we trigger RUN, keep running until we give a contradictory input. Similarly, just tapping Jump should do a max-height jump. modulating dump height on distance would be additional inputs rather than timing on the initial input.

No idea when I would do that,... though.


Là où je sèche plus, c'est pour le saut. Dommage, pour un jeu de plate-forme, j'en conviens. Dans School Rush, on dose son saut par la durée de la pression sur le bouton. Faire pareil sur un écran, c'est risquer d'avoir toujours les doigts dans le chemin quand on veut regarder la suite du niveau. Je partirais plutôt vers un système où on fait de base le saut maximum, que l'on "interrompt" si Bilou arrive plus haut que l'endroit où on a tappé  / l'endroit où est le doigt. Enfin, il faudra trouver quelque-chose pour pouvoir atterrir avec assez de précision sur des plate-formes parfois assez étroites.

I liked the idea of "tap another GOB to trigger the "punch" button: it works for picking up bladors, throwing them on baddies, grabbing spons and punching things.

Saturday, January 27, 2018

J'adore le mauve

 Parce que dans Fez, le mauve est synonyme de mystère et d'intrigue. Généralement une petite pièce qui semble en-dehors du monde "normal", une atmosphère de trans-dimensionnalité... du fez quoi.

I love than purple shade of mystery Phil introduced in his Fez game. He mostly used it in small, indoors location that feel a bit disconnected from the "overworld". It usually looks bigger inside than it should be given the exteriors' dimensions. We first encounter it in the strange place where the cube gives us power, and it was absent completely from the village, to find it again just when we cross the door to "the world beyond" the village.

L'introduction du personnage à son nouveau pouvoir se fait dans le mauve, couleur presque absente de son village. On la retrouve pourtant derrière la porte qui mêne "au monde au-delà du village.

Et quel monde! les cascades tombent de nulle part, les blocs flottent dans les airs, il y a des portes partout et pourtant elles n'ont nulle part où mener (enfin, ça devrait chaque fois être une autre porte vers la même salle qui fait au mieux deux fois la chambre de gomez, mais en fait non. Ici, l'intérieur, c'est l'extérieur).

That first hub is the goal of our game: we want cubes to open those doors. The mystery color is used again, which makes the room feel unique, with floating blocks and Cascadas flowing from nowhere. There seems to be which echoes the duality of the gameplay: the normal, outerworld is for exploring, and the purple, inner world is for riddles.  Indeed, past that first hub, purple rooms will mostly be locations where we took for anti-cubes.

Il y a donc deux couches de réalité dans Fez: le monde extérieur, propice à l'exploration, et le monde intérieur, mauve, propice à ...

Eh bien propice aux énigmes. On va essentiellement le retrouver dans des salles "cachées" où il va falloir faire quelque-chose pour faire apparaître un anti-cube. C'est d'ailleurs probablement dans ces salles que vous avez le plus de chance d'y trouver votre premier si vous n'avez pas encore jeté un oeil sur la liste des "achievements" du jeu.

Un des aspects du jeu qui m'avait vraiment plu dès ma première "vraie" partie, faisant un peu écho aux puzzle qu'on pourrait trouver dans un Zelda.

Mais le mieux, c'est que le jeu nous met la puce à l'oreille. une salle-mauve en-dedans a sa porte d'accès sur un mur mauve au-dehors. De quoi provoquer l'anticipation du mystère mais aussi pouvoir la repérer plus facilement parmi les autres portes d'un noeud (on ne peut pas parler de monde ni de niveau pour fez) et simplifier un peu le back-tracking.

One clever design idea about those riddle-rooms is that their purple status tends to contaminate the outerworld. The door to the room itself will be purple as well, and sometimes, even some of the bricks around are purple, too.  This helps quickly identifying the right door when we backtrack to riddles we had not yet solved.
 

Some level of backtracking is impossible to avoid with Fez, but to be honest, the more you can focus on the things immediately reachable, the best. I wished I could close doors towards rooms I couldn't understand, To reduce the amount of trials when I'll have to go there again.  understanding how the map system works was a Key factor in bearing he game, and I eventually. picked up a sketchpad to take notes of my progress, and scribble anything that could be useful later, like the location of owls, obelisks and interesting paintings. without it, I think I would still be running that maze for final cubes. Likely, I should have depicted the secret doors as well.

Bien que, je vous l'avoue, j'avais déjà fait l'expérience assez désagréable de constater que Fez est beaucoup moins pratique quand on doit retourner quelque part que quand on y fait son premier passage. En fait, il aurait été pratique de pouvoir refermer une porte quand on se rend compte qu'elle mène vers une énigme qu'on ne sait pas encore résoudre, de sorte qu'elle apparaisse comme "à faire" au prochain passage.

Si bien que l'on doit assez vite apprendre à se servir de ce qui tient lieu de "carte" pour ce monde. garder un oeil sur ce qu'il y a à l'arrière-plan quand on tourne le monde dans telle ou telle direction, vérifier si la salle marquée d'un '?' est bien sur la "face" visible, s'il y a plusieurs portes sur cette face, etc. (et tenir compte du fait que la carte s'autorise à changer la position d'une porte si elle est sur la face par laquelle on arrive dans le noeud). Sans ça, c'est l'effet labyrinthe garanti.

Et oui, j'ai finalement pris un carnet à spirale pour y prendre note des choses sortant un peu de l'ordinaire (en particulier dans les salles mauves) y compris par où on y parvenait pour pouvoir y retourner facilement.
J'aurais probablement dû faire pareil avec les "portes dérobées" (marquées d'un double-carré) qui ne marchent que dans un sens la première fois mais qui offrent des raccourcis en cas de re-parcours.

AnimationModel

Donc, j'ai fini Fez (enfin, j'ai 64 cubes) mais ça, je vous en parlerai plus tard. J'ai aussi fini de réorganiser le code de mon éditeur d'animation de sorte que les manipulations effectuées sur la liste d'images puisse être extraites du code de l'interface graphique correspondante. Je ne vais pas qualifier ça de Model/View/Controller, mais c'est un pas dans la bonne direction, à mon avis.

At last, am done with one big chunk of nefactoring on the DS Animation Editor. Frames list can now be manipulared from any piece of code. It no longer requires emulation of the whole widgets/windows engine. 

It is probably not scleanly separated as MVC code, but it is definitely one step in the right direction. Now I can get rid of the ugly coupling between thumbs display and thumbs-bitmap filling when saving the file. I can get rid of global objects. I can introduce my new Resources class.

Tout ça parce qu'il était impossible dans l'état actuel de débarasser AnimEDS de ses objets globaux vu le couplage tordu et foireux entre la fenêtre qui fait le rendu des miniatures et le système de sauvegarde. Pensez un peu: pour sauver les miniatures (utilisées par l'éditeur de niveau), on allait devoir faire croire à cette "fenêtre" que l'utilisateur passe d'une page à l'autre pour la forcer à re-générer des prévisualisations en mémoire vidéo que l'on capture pour les placer dans le fichier.

Prévisualisations qui - au passage -- demandaient qu'on fasse croire à la fenêtre d'édition des animations qu'il y a une nouvelle animation à éditer pour qu'elle la décode, construise la liste de frames correspondante et qu'on puisse demander un rendu de la première frame à chaque coup.

C'est presque un miracle qu'on ait pu continuer à éditer des animations après une sauvegarde, à ce tarif-là.

Tout ça parce que si AnimEDS garde ses objets globaux, il est impossible de réorganiser la gestion des resources dans le Game/GuiEngine.


Thursday, January 11, 2018

Engine Refactory

The Big Refactory has started (I could pretend it is a new-year resolution). And it even went pretty far, like abstracting away the animated objects list so that only the code for animated objects need to know details of the animation scheduler.

I was about to try changing the VRAM allocation system so that only classes deriving from using Resources could request items, and I got stuck in the animation editor.

Unlike SEDs and -to some extent- LEDs, AniMEDs still use a lot of global variables. Things like the sprite set or the animation being editted are used almost directly in many places, instead of being captured as "structural singletons". And at some places, it also means that we were calling Ressource Manager directly at top-level code, and that contradicts what a common base class can do.

There is one other peculiar thing about the animation editor: the set of pixels used in the game isn't uploaded to the video memory. Instead, we keep it in main memory, and only some bits of it go tothe VRAM through a Sprite sheet that map some sprite memory.  These sprite sheets are linked to a specific widget, such as the timeline or the frame preview. I must not try to make them part of a "model": they truly belong to the implementation of the widgets.

And yeah, although I have a digital sketchpad and an e-boox, I still enjoy some good paper and fine (erasable) pens for such things.

Thursday, January 04, 2018

Presenting monsters


This is something I really loved in DKC closing cutscene and which I'll now seriously start working on for School Rush: seeing the nicknames of all the baddies in the game with the baddies themselves. Later on, when I wanted to bring Badman II to an end, I tried to do something similar: which apparently worked quite well it was acclaimed by Aderack in his wiki and essays.

And as if I'd need one more proof, my brother just convinced Lazycow that such a show was all he needed to make the. end-of-game cut scene of Power Glove feel satisfying for the players reaching that point.


J'étais complètement fan de la séquence de fin de Donkey Kong Country, avec sa présentation des ennemis un peu humoriste qui dévoile leurs noms et permet de se souvenir de tout ce qu'on a traversé. J'avais fait quelque-chose d'un peu similaire pour la fin de Badman II, ce qui a plu, visiblement (au moins à Aderack ;)

Et comme s'il en fallait plus pour m'encourager à remettre le couvert dans School Rush, voilà que mon frère me raconte que LazyCowse demandait que faire pour le final de son PowerGlove et mon frère de lui dire que "bin si, les joueurs aiment bien qu'on leur remontre la galerie des monstres/boss avec les noms de tout le monde (surtout quand les noms sont un peu rigolos). Et sisi, y'a pas forcément besoin de beaucoup plus.

Donc ne vous inquiétez pas, je vais quand-même garder un petit quelque-chose d'original : le croquis ci-dessus est une ancienne idée. Mais j'ai encore quelques petits détails à régler pour que ce soit réussi. 

Of course, these are just some preliminary sketches, and there has been some evolutions. But I know you'll allow me to keep those details a secret, and not spoiling your future satisfaction myself.

Wednesday, January 03, 2018

A dos de blador.

Mes taille-crayons, une fois en mouvement, font d'assez mauvaises plates-formes, en vérité. Celà vient de leur animation. D'abord (comme la plupart des animations de marche), elle va retarder certains mouvements pour consommer d'un coup 2 pixels de déplacement après être restée immobile pendant 4 images si la vitesse de consigne est d'1/2 pixel-par-60eme de seconde. Ensuite, parce que contrairement à Bilou, le déplacement de dumblador s'interrompt pour une courte pause avant de reprendre: non seulement ce taille est trop "dumb" pour mettre un pied devant l'autre, mais en plus, il lui faut un moment pour se souvenir de ce qu'il convient de faire pour finir le mouvement qu'il a entammé. Autant dire qu'il vaudrait sans doute mieux pour une "pile de dumbladors" de tomber d'un étage quand un des tailles-crayon se remet en mouvement plutôt que de jouer à rajouter des "selles invisibles" pour offrir quelque-chose de plus souple.

Non. Je préfère tenter maintenant de faire tenir Bilou sur un taille-crayon à l'arrêt. Et là aussi, j'ai du travail: il faudra veiller à

  • forcer une mise à l'arrêt complet au contact, puisque le contrôleur "stopper" sera court-circuité,
  • "détacher" Bilou de son support lorsqu'il saute,
  • compléter le contrôleur "onpath" pour qu'il provoque le détachement lorsque Bilou n'est plus par-dessus le chemin.
This has been a "known issue" since April 2014, and it still wouldn't be easy to fix it today: you can walk on a Dumblador (after stunning it) as if it was a platform, but as it wakes up, weird things occur that make Bilou slightly slip forward and eventually fall of the blador. Initially, it was also affecting stacked dumbladors, so I added a rule to "break" the stack as a blador wakes up.

The core of the problem comes from the fact that a carried GOB will adapt to the "moving platform"'s speed in order to give the illusion of friction, but when it comes to dumbladors, the speed and the effective motion quite disagree. First because - as with any WALKing GOB - the horizontal speed isn't constant, and second because I introduced a small pause between two steps for the blador, to reinforce the feeling of "dumbness". As a reminder, the GPath abstraction is as follow:

  • GameObjects have an 'onpath' pointer, which complements the 'attach' pointer (to a gob).
  • GobArea now implements the (horizontal) GPath API, returning always the same y coordinate, and checking that you're in the desired xrange.
  • 'Ap' in a gobexpression will attach the object to a "path" rather than to an object, the area that triggered the collision will be used to define the new path.
I gave path-capable engine a try back in february 2013, but that was nothing I could test. The idea was to support both NSMB-like angled mushrooms and (softly) swinging ropes. The current code with dynamic GPath comes from June 2013 and has still to be complemented with a controller that uses it.

It's all described and motivated in http://sylvainhb.blogspot.be/2013/06/walking-on-platforms.html