Resume
Trois bugs IA aliens fixes ce soir :
-
Splash de mort : port de la fin de
ai_JustDied(ai.s:194-266) et de
Anim_ExplodeIntoBits(newanims.s:605). Quand un alien meurt avec
AlienT_SplatType_w < NUM_BULLET_DEFS(= 20, cas commun des Red Alien,
Insectalien, Triclaw, Guards, etc.), il spawn maintenant 7 « bits » de
gore qui partent dans toutes les directions et retombent par gravite,
exactement comme dans le jeu original. -
Duree cadavre :
DEATH_FADE_FRAMESpasse de 25 a 50 ticks Amiga
(= 1 sec a 50Hz). L’ASM original utiliseai_FinishedAnim_b(fin reelle
de l’anim) plutot qu’un timer fixe ; on garde le timer pour la simplicite
mais en le calibrant plus large pour couvrir les animations de mort des
boss (8-12 frames = 40-60 ticks). -
Step-walls traversables : aliens bloques par les marches / passages
entre zones de hauteurs differentes. L’ASM autorise la traversee si
|delta_Y| <= StepUpVal = 20pour walking (cf.objectmove.s::MoveObject).
Cote port, leAlienWallCollidertraitait tous les murs comme bloquants,
meme les step-walls visuels (= edges entre 2 zones connectees ayant des
hauteurs differentes). Fix : separer les step-walls dans des Geometry
nommeesstepwalls_NNdans leLevelSceneBuilder, et laisser le
AlienWallCollidercontinuer a ne scanner quewalls_*(donc ignorer
lesstepwalls_*).
Le cas splatType >= 20 (boss : Snake/Mantis/Crab/Wasp qui doivent spawner
2 aliens plus petits) reste un TODO pour la suite (phase 2.G).
Fichiers modifies
-
core/ai/AiWorld.java: nouvelle methodespawnSplatBits(splatType,avec
worldX, worldY, worldZ, impactX, impactZ, inUpperZone, zoneId)
doc complete pointant versAnim_ExplodeIntoBits. Default no-op pour
ne pas casser les tests unitaires qui n’implementent pas l’interface
complete. -
core/ai/AlienAI.java:
–DEATH_FADE_FRAMES: 25 -> 50 (justification dans le javadoc).
–justDied(): appelleworld.spawnSplatBits(def.splatType(), ...)
quandsplatType < 20. Le TODO existant (« splatter, son, message
displayText ») devient du code reel. Le commentaire ASM-ref complet
est inclus pour facilite de relecture. -
world/AiWorldAdapter.java: implementation runtime du splash.
ReutiliseAlienShotPool(= meme pool que les tirs aliens, c’est
l’equivalent direct deAI_AlienShotDataPtr_lASM). 7 bits par mort
(= clamp ASMcmp.w #7,d2), angle aleatoire 0..4095, magnitude 2^(1..4),
velY positif vers le haut (256..1279), gravite forte (12) pour retomber
rapidement. Les bits suivent le meme code path que les bullets aliens
dansAlienBulletUpdateSystem: ils heritent du raycast murs, du
timeout, et de la kill-on-impact – donc ils s’arretent visuellement
au sol au lieu de continuer indefiniment. -
world/AlienWallCollider.java: ajout d’un mode diagnostic
(toggle via-Dab3d2.dumpAlienCollider=1) qui logue pour chaque
Geometry de mur scannee : nom, zoneId/joinZoneId userData (si presents),
et nombre de segments extraits. Permet de verifier en jeu que les
stepwalls_*ne sont pas pris en compte par le collider alien. -
tools/convert/LevelSceneBuilder.java: fix step-walls.
– Nouveau bucketswq(step-wall quads) en parallele dewq(wall
quads). Meme indexation par texture (bk), meme format de payload
(14 floats).
– Detection step-wall apres tous les checks portes/lifts : un wall
avecoz > 0et!doorZoneDefs.containsKey(oz)est classifie
step-wall (= edge entre 2 zones connectees non-speciales).
– Dans la bouclefor (int rep = 0; rep < numRepeats; rep++), choix
conditionnel du bucket :(isStepWall ? swq : wq).get(bk).add(...).
– Apres l’emission deswalls_NN, emission desstepwalls_NNvia le
memebuildWallGeo()(meme shading, meme texture, meme animation).
– StatsstepWalls:Najoutees a la ligne resume du build.
Comment tester in-game
Prerequis : rebuild necessaire pour que les .j3o contiennent les
nouvelles Geometry stepwalls_*. Lancer :
./gradlew buildScenes
Les logs montreront stepWalls:N pour chaque niveau. Sur les niveaux
standard, on attend N > 0 (typiquement 50-200 selon la topologie).
Ensuite :
1. Lancer le jeu, ouvrir un niveau avec des Red Aliens (niveau A).
2. Tirer sur un Red Alien jusqu’a le tuer.
3. Verifier visuellement le splash :
– L’animation de mort joue en entier (~1 sec)
– 7 sprites rouges (placeholder couleur des bullet alien) partent du
centre de l’alien dans toutes les directions
– Ils retombent par gravite et meurent au sol/mur
4. Verifier le mouvement : approcher d’un alien qui est dans une zone
adjacente legerement plus haute / plus basse (presence d’une marche
visible). Faire en sorte qu’il ait LOS sur le joueur, il doit pouvoir
se rapprocher en franchissant la marche, alors qu’avant il restait
bloque.
5. Verifier que les murs vrais bloquent toujours les aliens (= ils ne
passent pas a travers les murs porteurs des zones).
Toggle diagnostic
Si un alien semble passer a travers un mur qu’il ne devrait pas, ou
l’inverse :
./gradlew run -Dab3d2.dumpAlienCollider=1
Les logs au demarrage du niveau montreront chaque Geometry de mur scannee
par AlienWallCollider avec le nombre de segments extraits. On peut
ainsi confirmer qu’un mur particulier est ou n’est pas dans la liste des
bloquants.
Limitations connues / TODO 2.G suite
- Sprite des bits : ils utilisent le rendu sphere coloree placeholder
deAlienBulletUpdateSystem.createBulletGeometryau lieu du vrai sprite
Splutch1-4 du WAD. Sera resolu quandBulletSpriteRenderersera branche
sur le pool alien (actuellement seul le pool joueur l’utilise). - Boss spawning :
splatType >= 20ne spawn pas encore les 2 aliens
plus petits. Le TODO est marque dansAlienAI.justDied(). - Son final scream :
world.playPositionalSoundest encore no-op. - Step-walls : test runtime StepUp/StepDown manquant. La separation
step-walls/walls dans leLevelSceneBuilderrend TOUS les step-walls
traversables par les aliens, peu importe la difference de hauteur.
L’ASM est plus fin : il bloque si|delta_Y| > StepUpVal(20 walking,
30 walking-down, 1000 flying). En pratique, les marches du jeu sont
toujours < 20 unites, donc le port simplifie devrait suffire. Si on
observe des aliens qui sautent des falaises, il faudra implementer le
vrai test : etendreAlienWallCollider.Segmentavecint joinZoneId,
passer lefloorHdes zones via {@code AiWorld}, et tester au runtime
dansmove(). - Cadavres persistants : l’ASM (et notre port) supprime le sprite a la
fin de l’anim de mort. Pour ajouter de vrais cadavres qui restent au
sol, il faudrait separer la logique : sprite final fige sur la derniere
frame de l’anim DIE, plus de tick IA. C’est un ajout par rapport a
l’ASM, a discuter.