Post subject: Kingdom Hearts: Chain of Memories (GBA)
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour, Je sais que j'emploie déjà un post dans la partie principale du forum, mais comme certains ont du mal avec l'anglais (que je suis loin de maîtriser, étant toujours en train de l'apprendre) je préfère créer un post ici pour toucher le plus de monde possible afin d'avoir plus d'avis. Donc, comme premier TAS j'ai choisi Kingdom Hearts: Chain of Memories sur GBA et je voudrais savoir si vous connaissez quelques bugs ou astuces pour aller plus vite. Vous pouvez télécharger le fichier de la première version de la Ville de Traverse et de la Ville d'Halloween ici. Mais cette version n'est plus à jour vu que Samsara m'a expliqué comment finir plus vite le premier tutoriel. Malheureusement (ou heureusement ?), l'aléatoire influe sur tout le jeu (les salles, les cartes, l'IA...) et donc, je suis en train de refaire les deux mondes (avec déjà un gain d'environ 1500 frames à la fin de la Ville de Traverse). Edit: Voici la version mise à jour avec une amélioration d'environ 3500 frames sur l'ancienne, soit environ 59 secondes. Par contre, j'ai toujours du mal avec le système d'aléatoire (même pour le comprendre ^^'). Le fichier pour l'émulateur est ici ici et voici la vidéo : Link to video S'il-vous-plaît, donnez-moi vos avis... Et suis-je le seul Belge sur le site ? :p
New PCSX2-rr
Joined: 1/26/2009
Posts: 558
Location: Canada - Québec
J'ai pas réussis à synchroniser avec vbarr-svn480(desync juste après la cutscene du début). Mais d'après ce que je peux voir sur la vidéo, ça semble très bien. Beaucoup d'attaque combo et même un petit glitch graphique à la fin du premier boss! Question: comment fonctionne la chance pour obtenir les bonnes cartes/rares? Est-ce avant que le combat commence ou pure manipulation durant le combat?
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
J'utilise la version 24, si ça peut t'aider. Oui, le bug graphique avec l'Armure Gardienne est chouette (et découverte complètement au hasard :p). Pour la chance, je n'ai pas encore tout compris mais la frame à laquelle le dernier ennemi meurt définit la carte... Mais sauter peut aussi changer l'aléatoire, mais je suppose qu'il y a encore d'autres choses qui se cachent derrière tout ça. Donc, pour obtenir la bonne carte, je donne le dernier coup un frame plus tard (et il faut parfois recommencer le combat et changer l'ordre des ennemis).
New PCSX2-rr
Joined: 1/26/2009
Posts: 558
Location: Canada - Québec
Ok, en effet ça sync correctement avec la v24. Petit truc mineur, à 8:20 et 14:50, il est possible de sauter sur l'échelle. Côté ram watch, as-tu trouvé quelques adresses intéressantes? Vite fait, j'ai trouvé ces adresses(unsigned-2bytes) pour l'hp des ennemis, mais j'ai l'impression que le jeu recycle l'utilisation de la mémoire à mesure... 0x02032C88 mob1 0x020329C8 mob2 0x0203271E mob3 0x02032C48 mob4? ... Ah et sinon, j'en ai déjà une petite idée, mais pourquoi avoir choisi "Halloween Town" en premier? :) edit: typo
Post subject: Re: Kingdom Hearts: Chain of Memories (GBA)
Player (103)
Joined: 1/4/2013
Posts: 117
Location: Belgium
Tounet01 wrote:
Et suis-je le seul Belge sur le site ? :p
Nop :) Sinon j'ai regardé la run, c'est assez chouette :). Ceci dit, je ne connais absolument pas le jeu donc j'ai du mal à percevoir les subtilités. Donc moi je dis: Continue sur ta lancée :D
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Désolé pour le retard : j'étais en vacances sans mon ordi et sans connexion internet. BadPotato, en effet il est possible de sauter sur l'échelle mais cela modifie l'aléatoire par la suite... Pour les adresses, je les avais trouvées mais comme tu le dis, le jeu n'emploie pas les mêmes adresses pour la même chose. Pour le reste, j'ai juste les vitesses de Sora (haut, bas, gauche, droite), ce qui me permet de démarrer le plus rapidement possible après une séquence. Le choix de la Ville d'Halloween est dû au fait qu'Oogie Boogie n'est pas touchable en permanence et donc, il faut mieux qu'il ait la petite barre de vie possible :D. Youpi, un autre Belge :p ! Merci, et je te conseille le jeu si tu aimes bien ce genre de RPG (malgré le fait que je n'ai jamais su finir la partie de Riku... Fichues cartes :p)
New PCSX2-rr
Player (103)
Joined: 1/4/2013
Posts: 117
Location: Belgium
Si le jeu réutilise les adresses, il doit y avoir un pointeur quelque part qui indique où elles se trouvent. Ensuite, un peu de lua et hop, on a ce qu'il nous faut en permanence. Bon après, c'est qu'une théorie... Un jour si j'ai le temps, je testerai :p (même si je suis pas un grand fan des RPG)
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Hum... C'est une théorie à laquelle je n'avais pas pensé. Merci beaucoup ! :D
New PCSX2-rr
Player (103)
Joined: 1/4/2013
Posts: 117
Location: Belgium
^^ Ca fonctionne comme ça pour Mario 64DS -j'y ai jeté un oeil par curiosité-, du coup j'avais un script qui lisait le pointeur et de là, j'allais lire les adresses (en convertissait les nombres en un truc lisible au passage).
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Est-ce que tu pourrais juste me dire comment trouver les pointeurs (je n'ai pas trouvé sur le site ^^'), stp ?
New PCSX2-rr
Player (103)
Joined: 1/4/2013
Posts: 117
Location: Belgium
Très franchement, je n'ai pas cherché :D. J'ai juste lu cette page. Et le script :
Language: lua

local CharacterPointer = 0x02097490 local pointer local Vars = {} Vars["Character"] = 0 --byte Vars["X"] = 0 --DWord Vars["Y"] = 0 --Dword Vars["Z"] = 0 --Dword Vars["modelAngle"] = 0 --Word Vars["motionAngle"] = 0 --Word Vars["speed"] = 0 --DWord Vars["xVelocity"] = 0 --DWord // x and z derived from speed + direction Vars["yVelocity"] = 0 --DWord // Always -32k on the ground Vars["zVelocity"] = 0 --DWord Vars["status"] = 0 --12Byte // Swimming, walking,.... Vars["BowserRevolutionSpeed"] = 0 --Word Vars["BasementWaterLevel"] = 0 --DWord Vars["RNG"] = 0 --DWord Vars["cameraX"] = 0 --DWord Vars["cameraX"] = 0 --DWord Vars["cameraX"] = 0 --DWord Vars["upDownAngle"] = 0 --Word local VarsAddr = {} VarsAddr["Character"] = 0x8 VarsAddr["X"] = 0x5C VarsAddr["Y"] = 0x60 VarsAddr["Z"] = 0x64 VarsAddr["modelAngle"] = 0x8E VarsAddr["motionAngle"] = 0x94 VarsAddr["speed"] = 0x98 VarsAddr["xVelocity"] = 0xA4 VarsAddr["yVelocity"] = 0xA8 VarsAddr["zVelocity"] = 0xAC VarsAddr["status"] = 0x370 VarsAddr["BowserRevolutionSpeed"] = 0x0217B1D4 VarsAddr["BasementWaterLevel"] = 0x02176464 VarsAddr["RNG"] = 0x0209CDF0 VarsAddr["cameraX"] = 0x12C VarsAddr["cameraX"] = 0x128 VarsAddr["cameraX"] = 0x124 VarsAddr["upDownAngle"] = 0x3A dofile "../../../_Tools/Lua Libs/HexConversion.lua" --[[ UI ]] function Coord() Vars["X"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["X"])), 20) Vars["Y"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["Y"])), 20) Vars["Z"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["Z"])), 20) Vars["modelAngle"] = memory.readword(pointer + VarsAddr["modelAngle"]) Vars["modelAngle"] = (Vars["modelAngle"] / 65535) * 360 Vars["motionAngle"] = memory.readword(pointer + VarsAddr["motionAngle"]) Vars["motionAngle"] = (Vars["motionAngle"] / 65535) * 360 Vars["speed"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["speed"])), 20) Vars["xVelocity"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["xVelocity"])), 20) Vars["yVelocity"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["yVelocity"])), 20) Vars["zVelocity"] = LibHex.ToFixedPoint(string.format("%X", memory.readdwordsigned(pointer + VarsAddr["zVelocity"])), 20) gui.text(5, 25, string.format("X: %.2f Y: %.2f Z: %.2f", Vars["X"], Vars["Y"], Vars["Z"])) gui.text(5, 35, string.format("Xv: %.2f Yv: %.2f Zv: %.2f", Vars["xVelocity"], Vars["yVelocity"], Vars["zVelocity"])) gui.text(5, 55, string.format("Angle: %.2f mdlAngle: %.2f", Vars["motionAngle"], Vars["modelAngle"])) gui.text(5, 75, string.format("Speed: %.2f", Vars["speed"])) end function RNG() Vars["RNG"] = memory.readdword(VarsAddr["RNG"]) gui.text(100, 5, string.format("RNG: %d", Vars["RNG"])) end function UI() pointer = memory.readdword(CharacterPointer) Coord() RNG() end gui.register(UI)
Donc en gros, tout ce qui est LibHex.untruc c'est dans un fichier que je lis grâce à la fonction dofile. Ce sont des fonctions de conversions. Dans la fonction UI, j'affecte la variable pointeur (stockée dans une adresse connue); ensuite dans Coord() je vais lire la valeur "speed" -par exemple- qui est toujours à pointeur + une valeur (dans point de vue programmation, j'ai envie de dire que le pointeur contient l'adresse de l'objet perso et que donc, il est logique toute les infos nécessaires soient côte à côte dans la mémoire). Comment trouver ce pointeur? Hummm... Si je reprends cet exemple: On est dans une zone X où on a notre vitesse. On change de zone et tout a changé en RAM mais... On sait que si on appuie sur avant pendant 5 frames, notre vitesse sera de 8 (par exemple) il suffira de chercher cette valeur précise pour trouver la nouvelle adresse de la vitesse. On va dire que pour la zone X, l'adresse de la vitesse est 0x100 et pour la zone Y 0x150. Si il y a pointeur, il existe en RAM une adresse qui contient la valeur 0x100 (256 en décimal) quand on est dans la zone X et 0x150 (336 en décimal) quand on est dans la zone Y. MAIS La valeur speed n'est qu'une valeur; pas un objet. L'objet (parfois nommé head ou header) avoisine ces valeur (vers le bas) c'est peut-être 0x99 (dans la zone X) et donc il faudra chercher une adresse qui contient 0x99. Etc... C'est comme ça que j'approcherais le problème pour ma part (en espérant que le jeu fonctionne ainsi). PS: Pour ceux qui se demande pourquoi j'ai passé mon temps à créer un tableau avec mes variables, c'est parce que si je crée mes variables dans la fonction, mon PC pédale à mort dans la choucroute à cause des milliers de créations à la seconde (et bonjour le memory leak) je limite la casse en faisant comme ça. C'est beaucoup moins problématique quand on utilise:
Language: lua

while true do UI() emu.frameadvance() end
car la fonction n'est appelée QUE si on avance d'une frame.
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Hum... Merci beaucoup ! Le plus dur va être de trouver les pointeurs ^^'. Mais au moins, je sais comment je vais devoir chercher.
New PCSX2-rr
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour ! Désolé, j'avais un peu oublié ce post-ci ^^'. Donc, je vous mets les mondes faits (ou re-faits pour certains) avec les explications : Ville de Traverse : Link to video Juste des combats pour récupérer une partie des cartes nécessaires. Les cartes bleues ne peuvent pas être obtenues ici. Pour l'Armure Gardienne : comme je n'avais que les Cartes Malus des Rhapsodies Bleues et des Nocturnes Rouges et que les sorts de Glace font des dégâts de zone (ce qui est utile ici :p), il était préférable de lui geler le corps (et de le finir avec des attaques physiques). Pour les tutoriels : - Celui avec l'Inconnu (bon, c'est Marluxia) : comme il faut employer toutes les cartes, les 2 premiers coups d'un combo sont à privilégier (l'animation du coup final est trop long). - Celui avec Léon : il est fait "normalement". Le Colisée de l'Olympe : Link to video Quelques combats pour obtenir des cartes bleues (et d'autres :p). On ramasse aussi Estoc Glacier (Blizzard Raid), qui est très pratique sur les ennemis de Feu (ex: Axel, Hadès) Hadès : - J'ai attendu que l'Ombre apparaisse car il fallait changer la RNG (voir plus bas) pour qu'Hadès soit correct (il est vaincu avec Estoc Glacier). - Sa carte Malus : Furie : Double les dégâts faits (mais il faut avoir 39% des HP : 19 HP sur les 80 de base)... C'est complètement pété pour un TAS :D Wonderland : Link to video Il fallait récupérer la Carte Malus du Crescendo, ce qui a demandé une manipulation de la chance assez horrible. Elle permet d'augmenter les dégâts des Invocations (ex: Cloud) mais annule l'utilisation des magies : Omnislash fait 50 points de dégâts par coup sans, 64 avec Maître des Tours : - Fait avec Furie - évidemment, j'ai évité les cardbreaks (c'est une perte de temps sèche ^^') Agrabah: Link to video Un nouveau deck ! Mais il faut aller voir les Mogs (voir la section RNG) : il fallait 10 As de Coeur, 5 Lampe Magique, 5 Brasier et 5 Cloud Description du deck : Toutes les cartes attaque au front, puis la magie (Cloud et Glacier), puis les objets de Récupération (Potion(+)), puis les Malus Jafar : - Manipulation pour obtenir des plate-formes correctes - Iago est intouchable pendant quelques frames après le changement des plate-formes (je sais pas pourquoi :p). Monstro : Link to video Parasitocage : - Passer en Furie aurait été trop compliqué : les ennemis du Monde sont trop mous (tout comme le boss) et casse-pieds à vaincre. - De plus, il y a une petite technique grâce au sol acide : il fait des dégâts tous les x temps, ce qui permet d'interrompre l'action en cours. Comme les As de Coeur font plus de dégâts en début de combo qu'à la fin (je peux vous mettre le tableau, si vous voulez ;) ), c'est très pratique pour faire plus de dégâts. Lutte Intestine de Monstro : Un "mini-jeu" obligatoire : les Sans-Coeurs n'apparaissent qu'une fois un certain nombre déjà tué (généralement, le groupe qui vient de poper). Ville d'Halloween : Link to video Oogie Boogie : - La carte Aide (celle avec la tête de Mickey) n'apparaît qu'après une certaine frame. Elle permet de baisser les grilles d'un coup (sinon, il faut cardbreak Oogie). - On le tue en un cycle en employant les 2 premières attaques de l'As de Coeur (et en finissant les combo avec Lampe Magique, quand nécessaire). Retour vers la Ville de Traverse (Farm) : Link to video 6 minutes de farm... Passionnant à regarder, n'est-ce pas ? :p J'ai fait un deck spécial : 3xGlaciers et 1x Chaîne Royale (car il faut au moins une carte Attaque dans un deck). Au début, 52 cartes ; à la fin, 79. Toutes les cartes ont été ramassées, donc il ne faudra plus faire aucun combat (à part les boss, bien sûr). Forteresse Oubliée : Link to video J'ai ramassé 6 "Rose éternelle" (il m'en fallait 5 mais j'ai préféré en prendre une de plus pour éviter la valeur 1). Maléfique : - Au début, il fallait qu'elle attaque rapidement (pour Furie), puis, le moins possible (pour éviter les cardbreaks). - Les Attaques physiques lui font suffisamment de dégâts. - Carte Malus : Sacrifie du temps de rechargement contre plus de puissance physique Néo Riku : - Un deck spécial : 6xCloud et 3x Roses éternelles - Normalement, il peut être tué avec 3 Omnislash sous le Boost d'Invocation (la Carte du Crescendo) mais ce boost disparaît quand on recharge. Donc, il faut le finir avec un combo de Keyblade. - Cela pourrait être plus rapide avec Furie, mais Riku est trop lent pour attaquer. Général : - RNG : La partie la plus complexe du jeu (et qui a dû rebuter plusieurs joueurs, je pense :p). Elle change selon les règles suivantes :
    En sautant En détruisant/tapant un objet sur l'écran d'exploration (ex: les caisses) ou en sautant dessus L'apparition des Sans-Coeurs Les déplacements des Sans-Coeurs (attention : sur l'écran d'exploration, il se peut que le Sans-Coeur fonce à toute vitesse sur Sora; ceci ne change pas du tout la RNG)
Elle régit les points suivants :
    La création des salles (qui dépend aussi de la frame) Le comportement des ennemis (en combat ou en exploration) Les objets obtenus (que ce soit les cartes Rouges/Bleues/Vertes ou les attaques/Magies/Invocations) Les magasins mogs
- Salle du Conquérant (la dernière salle du Monde) : La position de Sora dépend de la frame à laquelle entre dans la pièce (et donc, il faut apparaître à côté de la porte de sortie, ce qui évite de devoir monter l'échelle). - Petite anecdote : on appliquant un cheat sur les HP de Oogie Boogie, le jeu plant quand Sora prend la carte. Si vous avez des questions, n'hésitez pas à les poser ;). Oh, et est-ce quelqu'un peut me dire à qui je dois m'adresser pour changer de pseudo ? :D
New PCSX2-rr
Joined: 10/23/2009
Posts: 545
Location: Where?
Ça m'a l'air bien fait. Vous êtes sur le bon chemin je crois. :) Pour le pseudo, je crois que FractalFusion est un bon candidat ou encore les administrateurs.
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Merci :D. Je dois tout d'abord remercier Ghostwheel, le speedrunner du jeu, qui donne vraiment de bons conseils ;). Merci pour l'info.
New PCSX2-rr
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour ! Voici le Huitième monde : Atlantica ! Link to video - Manipulation de la chance grâce aux points mogs (chaque rebond de chaque bulle fait "tourner" la RNG) - J'ai ramassé 6 "Trésor des Mers" : cette Keyblade inflige 15 dégâts pour le 1er et 2e coup mais 35 dégâts pour le dernier coup d'un combo, ce qui la rend la plus puissante en fin de combo (après Ultima, bien sûr, et je n'ai pas cherché les stats de 3 Keyblades car elles prendraient trop de temps pour être ramassées). Il ne m'en faut que 5 mais j'évite la valeur 1 (ah, la RNG de ce jeu) - Le nouveau "deck" :
    5x (Rose éternelle + As de Coeur + Trésor des Mers) 3x Glaciers 6x Feu 3x Glaciers 1x Potion+ 1x Ether Malus : 1x Nocturne Rouge, 2x Rhapsodie Bleue, 1x Maléfique, 1x Hadès
- Pour Ursula : Je ne peux pas employer Furie (la carte d'Hadès) car 3 coups me tueraient mais 2 sont insuffisants (et toutes ses attaques retirent le même nombre de HP). Donc, le choix s'est porté sur Maléfique (+50% en Attaque mais la recharge est plus lente). - Pour Neo Riku : Il m'a fallu plus de 10 essais complets pour trouver la bonne RNG et le bon comportement de l'ennemi (cette version est 10 secondes plus rapide que le premier essai).
New PCSX2-rr
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour ! J'enchaîne rapidement avec le Capitaine Crochet Link to video Pas grand chose à dire, cette fois : - Manipulation de la chance pour les créations des salles mais c'est facile et rapide à faire (chaque frame crée une salle différente). - Pour le Capitaine, 2 Estoc Feu et 1 Brasier suffisent à le tuer (après qu'il ait sauté directement dans le Feu :p). Il était ennuyant à optimiser car il a tendance à sauter un peu partout.
New PCSX2-rr
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour (c'était rapide à faire) ! Voici le Dixième Monde : La Forêt des Rêves Bleus. Link to video On ne se soucie pas de Winnie dans cette route... Donc, il doit encore être en train de chercher ses amis... Tout seul... Vexen : Je l'ai contrôlé pour éviter qu'il ne bouge dans le terrain (il fait des zigzags quand il bouge). Ses attaques le stoppent, donc le provoquer marche bien. Il a 1120 HP, Estoc Feu (avec le Boost de Feu de la carte Nocturne Rouge) fait 375 HP, donc 3 Tours suffisent. "Heureusement", il n'a pas lancé Auréole (il n'a même pas essayé).
New PCSX2-rr
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour ! Voici la Cité du Crépuscule Link to video - On court jusqu'à la prochaine porte (en prenant les meilleures salles possibles). - Petit correctif par rapport à la Forêt des Rêves Bleus : Vexen I ne peut pas employer Auréole... Mais Vexen II peut (et cette fois il n'a vraiment pas essayé :D). Le combat est plus ou moins identique au précédent (manipulation du comportement) - Riku III : De plus en plus agressif (surtout avec ses "Brasier X Obscur") mais quelques roulades, 3 Omnislashes et 1 combo suffisent (1 seul coup était assez mais je ne pouvais pas lancer Omnislashe sans qu'il me card-break).
New PCSX2-rr
Joined: 7/17/2012
Posts: 528
Location: Switzerland
Ah ben content de voir que ça avance bien :)
My Citra 3DS rerecording movie files test repositery: https://cutt.ly/vdM0jzl Youtube playlist "Citra Tests": https://cutt.ly/AdM0wg9 http://www.youtube.com/user/phoenix1291
Active player (251)
Joined: 8/12/2013
Posts: 185
Location: Belgium
Bonjour ! Hum... Encore une fois, j'ai oublié de mettre à jour ce poste. Donc, je mets le lien vers la playlist (les bonnes vidéos sont vers le bas). Îles du Destin :
    Pour les salles, idem que pour la Cité du Crépuscule Darkside ne peut pas être manipulé comme les autres boss (sauf si on se prend des coups ou qu'on ne le tape pas). Furie est la méthode la plus rapide (avec un complément d'Overdrive pour maximiser les dégâts quand on n'est pas encore en HP critique). Néo Riku IV : Pour une fois, Furie est plus rapide que Omnislash contre Riku. Ce combat est dur à optimiser (beaucoup d'esquives et de cardbreaks). J'ai rajouté des cartes 0 au paquet (et retirer les cartes Brasier) et même si je ne m'en sers pas pour ce combat, il reste plus rapide que sans les ajouter (Riku est moins agressif). Larxene II : Pour ne pas changer : Furie... Les cartes 0 permettent de la cardbreaker plus rapidement. Le problème étant que ces cartes 0, qui sont des Keyblades moins puissantes, infligent moins de dégâts que les cartes que j'emploie d'habitude (sauf Trésor des Mers, si employé en fin de combo).
Manoir Oblivion:
    Le dernier monde ! Les salles suivent toujours le même principe que les mondes déjà faits... Donc, rien à dire, à part qu'il y a beaucoup de portes à ouvrir. Axel : Il a 1680 HP et Estoc Glacier fait 375 de dégâts. Donc, en 5 Tours, il est mort. Les cartes 0 servent ici aussi à le manipuler (et à abréger ses animations).
New PCSX2-rr