J’ai étudié EnTT et Flecs, puis construit un ECS autour de trois exigences : accès en lecture/écriture déclarés, changements structurels différés et déterministes, et snapshots du monde. Une Entity contient un index et une génération sur huit octets ; la génération détecte les références périmées. La persistance utilise un UUID, StableEntityId, et non un handle du runtime.
Les entités partageant les mêmes composants vivent dans des archetypes, avec des colonnes SoA contiguës dans des chunks de 64 KiB. Pour deux millions d’entités, 64 KiB nécessitait 1 482 pages contre 5 955 à 16 KiB, avec la même bande passante. Les sparse sets stockent les composants rares sans multiplier les archetypes. Les tables de composants partagés gardent une valeur par configuration distincte, référencée par le chunk.
Chaque SystemDescriptor déclare ses lectures et écritures. L’ordonnanceur en déduit un DAG de dépendances et exécute ensemble les systèmes sans conflit. Avec 32 systèmes, son coût mesuré était de 0,68 µs par frame sur 10 000 entités et de 0,86 µs sur 1 000 000 : il suit les systèmes, pas le nombre d’entités.
Des phases fixes définissent input, simulation, physique, événements, application structurelle, transforms et extraction pour le rendu. Créations, destructions et changements de composants passent par CommandBuffer, appliqué en un point déterministe. Un auditeur d’accès détecte les écritures non déclarées en développement et disparaît à la compilation Shipping. Événements typés, observers et stockage dédié de hiérarchie complètent le modèle ; la propagation par versions évite de recalculer les nœuds immobiles.
Le replay depuis un snapshot a reproduit 120 enregistrements d’audit identiques sur 120 frames, sur la même machine et le même build. C’est la portée vérifiée du déterminisme et la base du Play/Stop de l’éditeur ; le déterminisme entre plateformes n’est pas promis.