Un automate cellulaire à éléments
Falling Sand n'est pas un jeu à gagner mais un bac à sable au sens propre : chaque case de la grille contient un élément — du vide, du sable, de l'eau ou du mur — et n'obéit qu'à une poignée de règles locales. Aucune forme n'est dessinée ni stockée : les tas, les pentes et les flaques que vous voyez apparaître ne sont écrits nulle part, ils émergent du comportement individuel de milliers de cellules. C'est exactement l'esprit des automates cellulaires, appliqué à de la matière.
Trois règles, trois matières crédibles
Le sable tente de tomber tout droit ; si la case sous lui est occupée, il essaie une diagonale — c'est ce simple report en biais qui, répété, l'empile en talus aux pentes régulières plutôt qu'en colonne. L'eau suit la même chute, mais ajoute une règle : quand elle ne peut plus descendre, elle s'étale à l'horizontale, ce qui la met naturellement à niveau et forme une flaque plate. Le mur, lui, ne bouge jamais et sert de décor ou de récipient. Je gère aussi une notion de densité : un grain de sable, plus lourd, peut chasser l'eau sous lui.
L'ordre de balayage n'est pas un détail
La grille est mise à jour en place, sans double tampon, ce qui impose une discipline stricte. Je balaie les rangées de bas en haut : un grain qui tombe atterrit ainsi dans une ligne déjà traitée et ne redescend pas plusieurs cases dans le même passage. Un drapeau « déjà déplacé » empêche la même cellule d'être rejouée après avoir glissé. Et je alterne le sens gauche / droite à chaque image : sans cette alternance, le sable dériverait systématiquement du même côté et les tas pencheraient. Ces choix d'ordre, ce sont eux qui font la différence entre une simulation crédible et un tas de bugs visuels.
Un rendu pensé pour la performance
La grille compte des dizaines de milliers de cellules, mises à jour soixante fois
par seconde. Plutôt que de dessiner chaque case au Canvas — coûteux — j'écris un
pixel par cellule dans un ImageData à la résolution de la grille, que
j'étire ensuite d'un seul drawImage à la taille réelle de l'écran,
lissage désactivé pour garder des grains nets. Toute la logique tient dans des
tableaux typés (Uint8Array) : pas d'objets, pas d'allocations dans la
boucle, un balayage linéaire de la mémoire. Zéro dépendance.
Ce que ça dit d'un projet sérieux
Un « petit sable qui tombe » condense ce que je recherche dans tout système : des règles simples et lisibles, mais un comportement d'ensemble riche et une attention réelle à l'ordre des opérations et au coût de chaque image. Sur vos projets, c'est la même exigence que j'applique — une logique qu'on peut raisonner et tester, des performances mesurées plutôt que subies, et un code dont vous restez pleinement propriétaire.