Showing posts with label depth. Show all posts
Showing posts with label depth. Show all posts

Friday, August 18, 2017

Habillage ...

Il est temps de passer du 'test fonctionnel' à quelque chose de plus "habillé" pour le dernier niveau vertical. Jusqu'ici, je m'étais contenté d'un minimum de graphisme (les blocs-sol) pour vérifier si les sauts étaient possibles. Il est temps de dessiner le reste des objets.

Ouais, sauf que pour avoir des dessus-de-fardes-sur-lesquels-on-marche un peu partout dans le niveau, c'est pas forcément simple. J'avais pensé à des "couches" suggérées par différentes couleurs (il y a déjà une convention dans l'ensemble du jeu du genre farde verte = mur, farde brune/mauve/vert-foncée = plate-forme semi-solide), et faire des structures un peu imbriquées comme avec mes bons-vieux-buissons.

Since April, I've been extending the "vertical, last level" of School Rush with some more platforming challenges. I intentionally kept the look of the level ultra-minimalist for monthes, as it is much easier to tweak the location of the platforms and adjust difficulty that way. I haven't touched the layout of the level in weeks, so I guess it is ready to receive more complete look.

I had plans to fake depth between level elements such as books or binders to justify the presence of so many platforms without having significantly more "ground", although there is some from time to time. And I was also planning to reuse the color conventions present in earlier levels of School Rush, such as "green book = wall, purple book = jump-through platform".

But that was missing the annoying fact that I can change the colors only on the background layer of tiles, while I typically need both background and foreground together to combine small objects into larger structures as I did with the green zone's bushes.


Sauf que pour faire facilement ce genre de choses avec un tileset réduit, je jouais sur les deux plans de tiles, toujours le même pour ce qui est par-devant, l'autre pour tout le reste. Mais mon moteur de jeu ne permet pour l'instant de changer la palette de couleurs que pour les tiles d'arrière plan: les tiles d'avant-plan sont systématiquement "verouillés" sur la palette #0 et les bits correspondants sont utilisés pour encoder le type de bloc.

This is thus one more motivation to change things in the game engine and take the "tiles properties" array out of foreground palette information, but hopefully, I have enough room (~20% left) in my blocks tileset to accommodate for some "combined" tiles, be it at the cost of manual palette retro-fitting.

But I know this cannot be labeled as "the solution" for this problem: It killed the Badman III effort by making the art impossible to manage. Later on, I'll have to address the issue for real.

Bref, pour cette fois-ci, je vais me débrouiller en créant "à la main" des tiles supplémentaires qui "combinent" les deux couches, avec des imports de palette, mais ce ne sera pas beau à regarder dans l'éditeur (parce que le joueur ne devrait pas voir la différence, lui). Décidément, tout cet été pousse vers un déplacement des propriétés du niveau hors des couches de "rendu".

Saturday, July 28, 2012

OAM priority issues

I'm about to introduce significant complexity in the game engine for the purpose of displaying some compound animations properly. I've took the time to think about it (while drilling staircase for a kid-safety-barrier, if you ask :P) and figured out how to sort all the needed details. I just missed one point: this is absolutely not the only place where I need OAM depth-sorting.

Remember of Apple Assault's frenzy, and how you could end up not seeing that appleman that runs towards you because it's actually sneaking behind a row of stunned applemen ? That's never been fixed to date because I had no way to instruct the game engine that "those stunned applemen should be moved to the background".

Then I remembered of that "talk" by Rafael Baptista about resource management on the GBA. Before he entered the core meat of his talk, he suggested that copying OAM entries (you can think of them as sprite descriptors) could be the right time to follow a Z-order linked list and keep the "hardware" OAM entries and their "shadow" counterpart. Nice move, although I still wonder how he manages the scaling/rotation matrices along the way...

I used to have a large, one-chunk DMA transfer of all the sprites & rotation information. I would have to split that in 3-u16 slices. That sounds like I'll have to pay sverx's report on memory copies performance benchmark a second - and more careful - read... and possibly opt for an intermediate - sorted, but in-cache - version out of the vblank period and then DMA that into VRAM when the vblank is hit.

A final consideration: there is little chance that I need a fine-grained Z-sorting. low/normal/high priority should be enough in 99% of the cases, and the remaining case could likely be "sorted" out at GOB instanciation by internally sorting the OAMs the GOB received.

edit: I asked myself the right question: 'is that move out of DMA sync'ing gonna cost me framerate or not ?'. From that point on, I hacked a modified version of my game engine, that uses CPU-driven copy with merging of OAM and rotations into one single table (as the DS hardware expects) and started Apple Assault with aggressivity setting turned at max (so many apples that you'll experience "ghost" berry bats and shots). Good news: it still works flawlessly (that is, I can't observe any slowdown). Next: the depth-re-ordering...


edit++: just applied silly reverse-priority and order-enforcement-at-sync() in an AppleAssault check: it proves the concept: now Bilou can sneak behind stunned applemen. Useless, but you can't deny it's no longer the default z-order that is applied.

edit+++: checked that a (Simple)Gob set on zlist[0] appears in front of (Compound)Gobs set on zlist[1]... now I've got to figure out how to use that best to implement the pullmask for my "roll jump" animation ...

Tuesday, August 24, 2010

They do clump a lot

I've been an attentive reader of KirbyKid's writings on level design for a couple of years, now, so I sent him a copy of Apple Assault v1.1, asking for advices on a few points where my "regular consultants" and I tend to disagree. I was happy and honoured to find his in-depth reply in my mailbox this morning. I'll sure have things to think about and experiments to run in the next weeks.

A force que la plupart de mes "consultants réguliers" (comprenez, CJ, Cyril et Gédéon) me contredisent sur certains choix de design pendant les préparatifs d'AppleAssault, et vu les commentaires peu instructifs récoltés sur dev-fr, j'ai fini par profiter que j'avais un binaire prêt-à-l'emploi pour demander l'avis d'un quasi-pro du level design, j'ai nommé Krazy Kirby Kid. Après quelques échanges de commentaires et d'e-mails, j'ai reçu ce matin sa réponse détaillée dans ma boîte aux lettre, que j'ai ouverte avec une excitation assez proche d'une réponse-du-Père-Noël. Il faut dire que je suis le blog de KirbyKid depuis près de 2 ans et que ses essais sur les "blind-boxes", les "core mechanics" et autre DKART. Un des aspects qui me turlupinait, c'est cette tendance qu'ont les applemen à "s'agglutiner" pour former des chenilles

I had issues with the "wiggler/lemmings" aspect of applemen behaviour, and my initial idea was to make "fall of cliff" somehow probabilistic. KirbyKid pointed out that

I like working with simple predictable enemies. They [Applemen] do clump up a lot though. The issue I have with this is that they can clutter the game (...) [and it] makes it easier for an appleman to sneak behind a stunned appleman and hit you.


La bonne nouvelle, c'est que l'avis extérieur de KirbyKid me motive à faire des expérimentations alors que j'ai plutôt tendance à justifier ma position vis-à-vis de mes "voisins de VTJ". Ou alors il a juste réussi à trouver les arguments vraiment convaincants. Bref, voyons ce qu'on peut faire pour éviter les "grappes" d'applemen, en particulier compte tenu du fait qu'un tel attroupement rend plus difficile l'identification des applemen encore "en course".

Let's experiment another strategy, then ... something more bio-inspired, such as generators that "sense" how many applemen exists in their surrounding and self-inhibit the generation of applemen if a certain density is reached.
state1->state2 on done
state2->state1 on found0
state2->state1 on done [c#applemen# 0 >] (x#throw_appleman# d#applemen#)


Petite idée "bio-inspirée" pour éviter ça: rendre le générateur d'applemen plus sensible à son environnement ... par exemple l'empêcher de générer un nouvel appleman s'il en a vu un récemment. J'ai déjà des zones-de-détections (cf la boîte bleue sur le schéma) que l'appleman utilise pour "voir" Bilou et l'attaquer, c'est le même principe. Sauf qu'ici, celà provoquera le retour anticipé de l'état "sonder l'environnement" (state2) vers l'état "attendre" (state1) alors que la génération d'un nouvel appleman se fait normalement à la fin de l'animation de state2 (à condition qu'il y ait encore des applemen à générer, bien-sûr).

It is actually surprisingly easy to tweak: an additional state (state2) is added to the FSM ruling the generator, which has an "active test area" (depicted in blue) and it will remain in this state only for a few frame, while state1 covers the majority of the inter-applemen delay. We can leave state2 either because an appleman has entered the "sensitive area" of the generator (in which case nothing happens) or because the delay for state2 has expired, and only then we throw a new appleman and decrement the number of applemen still to be generated.

Pour peaufiner, je peux faire en sorte que l'appleman soit à son tour "sensible" à l'annulation d'une génération et du coup "quitte le nid". Ca marche assez bien sur le niveau 1, en tout cas.

An additional tweak allowed the applemen to "sense back" such detection and, when this happens when they're on a cliff, make them jump off. In this way, applemen no longer "stick in their trunk hideout forever" on map #1: after a short time, they will leave the safety of the hollow trees and explore the surroundings. That should make them clump much less, although it's not yet a full-proof solution.

edit: I only gave these new game rules a few tries, but it looks like it doesn't make difficulty increasing with levels. At least, it doesn't make me feel that the game is getting harder, just that the levels are longer and longer to play, and I've been tempted to stop playing when I reached the map #1 with >60 applemen to attract out of there trees. I may need to find something else so that running applemen cannot ambush behind stunned applemen. The fact that the priority of two applemen solely depend on the OAM registers they use doesn't help 0_o


Au final, l'approche n'est pas vraiment concluante. Le niveau 1 est rasoir (sauter pour attirer 60 applemen ou les voir approcher au compte-goutte ... bof. Le niveau 2 déséquilibré (certains "trous" n'auront généré que 2 applemen, et un bug fait que certains restent "cachés" dans leur arbre. Les niveaux 3 et 4 ont leurs générateurs trop loin des applemen et ne sont donc de toutes façons pas affectés. Bref un "compteur global du nombre d'applemen présent à l'écran" aurait été tout aussi (sinon plus) efficace. Je devrais avoir moyen d'arranger les niveaux 1 et 2 avec un "nombre de saut autorisés" défini pour chaque générateur, par contre.

Tuesday, October 20, 2009

Sprites à Priorité Dynamique

Voilà typiquement le genre d'environnement qui était pénible à construire avec l'ancienne version de LEDS et qui devient simplissime avec le curseur de copie et autres nouveautés.
Mais c'est aussi le genre d'environnement qui pose problème au moteur de jeu dans sa version ".999" parce que j'utilise les deux plans de tiles comme arrière-plan alors qu'à d'autres endroits dans le jeu (p.ex. quand Bilou est dans un arbre), il se situe en fait _entre_ les deux plans.

Bushes like these were typically the kind of background that was a real nightmare to build with the previous release of LEDS. And with the "copy cursor" and "pull to foreground" modes of the new prototype level editor, it's really easy and funny. On the other hand, it was also the kind of background that challenged the game engine. It is acutally built by "flattening" the two layers in such a way that i never need more than two tiles at a place, and yet simulate much more planes. Unfortunately, as i wish some elements to hide Bilou (such as walls and trees in secret places), Bilou actually stands "between" the two layers i'm using here, while in this specific case, he should be on top.

Le résultat, c'est que souvent, les pieds de Bilou étaient masqués, comme sur l'image ci-contre, soit parce que j'avais oublié de repasser l'herbe en arrière plan, soit parce qu'il y avait déjà un autre élément de décor par-derrière l'herbe.
Quand j'avais lu les spécifications techniques de la console Genesis, j'avais été plutôt étonné de voir qu'il n'y avait que deux plans de tiles. Or, Sonic est parfois devant le décor et parfois derrière (sans compter l'image de fond, bien sûr, qui occupe le 2eme plan). Le truc, c'est que contrairement aux console de Nintendo, la Genesis permettait de définir pour chaque tile si les sprites avait priorité ou pas pour l'affichage.

As a result, it is common to see Bilou's feet hidden by the grass in the latest demo, either because i forgot to move the grass to the bottom layer, or because it has to be on the front layer due to some other object (e.g. vines or bushes) in the background. I'm trying to address this by reproducing in software the technique used in the SEGA Genesis, as illustrated in Sonic II.

Je vais donc tenter de reproduire cette approche en software: puisque je dois tester les "flags" de chaque tile lors du déplacement de Bilou, je peux assez aisément en ajouter un qui force Bilou (et les autres sprites) à "passer par-devant le décor" quand ils sont au moins partiellement en contact avec ce tile-là. Ca risque bien de compliquer un rien l'édition de niveaux, mais ça devrait valoir la peine...


Despite the Genesis had only two "scroll layers" (against 4 for the DS), it dynamically evaluated tile-to-sprite priority: while all the tiles involved in the "tunnel" on the picture above were on scroll layer A, Sonic can be hidden by the "front pillars" and still seen in front of the dark checker tiles. I'm unsure whether this implies that rings in Sonic were sprites, though. I cannot change the DS hardware, but i can mimmic this technique by having some of the tile attributes (F_RAISER) that forces any sprite that hits it to appear above all the "scroll layers" rather than between "F scroll" and "B scroll" for this specific frame. It's still to be tested.