An ice puzzle generator inspired by the Ice Path (and other similar locations) from the Pokémon Gold and Silver games.

The goal is to move the small slime from its starting point to the hole to fall down to the next level. However, once you start moving in a direction you cannot stop until hitting a wall or landing on a snow patch.

Controls

Arrow keys, swiping a direction (on mobile) - move the slime around

Clicking the snow patch button (on the left) - reset the level

Clicking the hole button (on the right) - solves the level automatically

Level generation

Here is the procedure used to generate levels:

  • On an empty 12 by 12 grid, rocks are placed at random until at most 40% of all tiles are covered
  • A starting point is chosen at random
  • All tiles reachable from this starting point are listed, and the furthest one gets changed into a snow patch
    • This step is repeated until the path to the furthest tile no longer increases in size
  • The furthest tile from the starting point gets changed into a hole, to mark it as the goal of the level
  • The whole map is then scanned tile by tile 5 times, applying a cleanup and a clutter procedure at each step
    • The cleanup procedure changes a rock or a snow patch to an ice tile if doing so does not decrease the length of the shortest solution; useless tiles are left in with a 40% random chance for aesthetic purposes and to confuse the player
    • The clutter procedure changes a tile into a rock if doing so increases the length of the shortest solution
  • If the shortest solution takes lower than 7 moves, the whole generation process is restarted from the first step up to 5 times, at which point the algorithm gives up

Notes on the generation procedure

  • Most if not all of the values mentioned in the generation procedure could be altered to try and influence the length of the solution
  • While the generation succeeds most of the time, it is not guaranteed to do so (and I did manage to make it fail at least one)
  • There is currently no safeguard against locking the player in an unwinnable state
  • Focusing on the longest path tends to produce levels "on a railroad", where the next step feels fairly obvious if not forced entirely. 
    • Intentionally not targeting the "longest-shortest solution" as the level goal could help with mitigating this issue
    • Having multiple "hidden goals" as additional constraints during the generation might help to keep the level more "explorable"
    • Adding multiple starting and end points could be done to help integrate the generated level into a bigger cave or dungeon for a fully-featured game
StatusReleased
PlatformsHTML5
Rating
Rated 5.0 out of 5 stars
(3 total ratings)
AuthorDelca
GenrePuzzle
TagsProcedural Generation, PROCJAM

Comments

Log in with itch.io to leave a comment.

I like to press the "solve this level automatically" button and watch the little blob zip around.

This was a lot of fun to play! I was surprised by how challenging the puzzles generated by this algorithm can be. I had plenty of moments where I had to really think about how to solve the puzzle, and those "a-ha!" moments felt very satisfying!

These puzzles are suprisingly tricky, great results for such a simple algorithm.

Bon sang j'ai eu des flashbacks de Pokémon cristal, bien joué :)

Du coup c'est généré procéduralement ? Tu utiliserai pas du raycasting des fois ?

Content que ça ait plu :-) Je ne suis pas assez bon en pixel art pour sortir des designs de ma tête, donc j'ai effectivement gardé la map de la route de glace de Crystal ouverte pour me servir d'inspiration.

Oui, tous les niveaux sont générés durant le fondu au noir qui les précède. Je viens de rajouter une explication du fonctionnement dans la description ; mais en quelques mots l'algorithme place des rochers au hasard, calcule le chemin le plus long et essaye d'ajouter ou de retirer des obstacles tant que ça rallonge la solution la plus courte.

(donc pas de raycasting, mais beaucoup de pathfinding pour essayer de s'assurer un niveau jouable et intéressant)

(1 edit)

Ok, je vois, c'est hyper intéressant ce que tu as rajouté en description. J'aurai jamais pensé c'etait aussi complexe sous le "capot".

Perso je pensai que tu utilisais du raycasting car tu aurais pu :

-choisir une case de départ 

-lancer un rayon a partir de celle ci

-placer un bloc "virtuel" sur la trajectoire du rayon qui le ferait dévié de 90°

-faire apparaitre un "vrai" bloc juste a côté du bloc virtuel en conséquence

-recommencer X fois jusqu'a placer la sortie

-le tout saupoudré de magie noir procédurale pour déterminer l'angle du rayon et l'endroit ou il doit dévier 

Je sais pas si jme fait bien comprendre...  

Voila ! Un dessin vaut milles mots :) Je dit pas que c'est la solution idéale, mais j'ai immédiatement cru que tu avais procédé ainsi. Un problème, de multiples solutions...

edit: j'ai mal placé l'un des rochers sur le dessin... je suis pas encore reveillé

(1 edit)

Je comprends bien ce que tu me décris, c’était la première approche que j'ai tentée :-) J'avais deux problèmes majeurs avec les résultats qu'elle me donnait :

  • ça ressemble de très près à une technique de marche aleatoire, et comme les images de Wikipédia l'illustre bien le chemin qui en résulte a tendance à s'amasser en certains endroits tout en laissant d'autre pans de la carte complètement vides
  • je ne pouvais pas garantir que le chemin fabrique était le plus court, et finir en deux-trois mouvements un niveau qui aurait du en prendre une vingtaine ça me signifiait que je n'avais pas bien le contrôle de la difficulté des niveaux générés

Le deuxième point était le plus important pour moi, et sans faire de raisonnements et preuves mathématiques sur mon processus de construction je ne me voyais pas pouvoir créer cette garantie de manière constructive. Je suis donc passé par la solution de secours du bidouillage algorithmique qui consiste à faire un parcours en largeur de la carte à chaque modification pour s'assurer de ne pas avoir réduit la longueur de la solution sans le vouloir.

Vu que ça me donnait facilement accès à tous les chemins existant depuis un point de la carte, j'ai aussi pu me débarrasser de la marche aléatoire et me contenter de placer des rochers au hasard de manière uniforme, ce qui a fortement augmenter la probabilité d'utiliser toute la map ou presque. Une bonne façon de s'en assurer pourrait être de considérer un chemin en plusieurs étapes plutôt qu'une solution en un seul segment, mais le coût en calcul et complexité de code dépasse surement le temps que j'avais à consacrer à ce problème pendant la Procjam...


(et pas de raycasting non plus dans ma première approche parce que si c'est un outil utile quand on vit dans un monde continu, moi je travaillais sur une grille discrète qui est facile à explorer de manière exhaustive)

Waw tu m'apprend des tonnes de trucs la. Hmm, je crois qu'il serait possible de réduire le chaos qu'implique la méthode raycasting en lui imposant un certains nombre de contraintes, pour obtenir une répartition la plus homogène possibles des blocs de glaces. Tu me donne presque envie d'essayer de coder un proto...

En tout cas ta méthode de génération actuelle marche du tonnerre de dieu, et c'est plaisant a jouer, ça ne fait aucuns doutes. Même si elle semble un peu trop issue de l'esprit tordu d'un diplômé de polytechnique : )