Jump to content

Pokemon Mystery Dungeon 2 - Psy_commando's Tools and research notes


Recommended Posts

Alright, these last few days I've been writing some conversion scripts to check things out.

Firstly, I wanted some more confirmation on the reverse-drawing method, so I assembled every FrameGroup that had overlaps, and drew them all out in reverse order: https://www.dropbox.com/s/pkgvs9g7u5bod1r/MONSTER_overlap.zip?dl=0 Just having them all on preview in that one folder seems to confirm it as a consistent rule- at least enough to convince me. The images that start with an underscore denote that they have -1 frames and aren't completely reliable, which led to another question...

One thing didn't sit right with me: given that -1 frames used existing memory, it would mean that they would be drawn after the original sprite piece. However, there's many places where -1 frames are at the END of a FrameGroup list, and never at the beginning. If frame pieces were truly drawn in reverse order, that would mean that the -1 frames are paradoxically pulling memory from a future state. Perhaps the draw order isn't in reverse, and the game just constantly draws behind (however strange that may be)? I was going to try and edit the position of Giratina's -1 Frame to overlap with the frame it copied, in an experiment of which frame would draw first, but I got sidetracked by a more general issue...

I wanted a better understanding of -1 Frames, and trawled through all the FrameGroups with -1 frames in hopes of finding some pattern. I initially tried checking if all -1 frames referred to another frame that was a constant X frames earlier. It didn't work that way, nor did it give me any insight on possible patterns. So then what I tried next was using the Resolution variable of the -1 Frames. The fact that, out of runtime, the game seems to know what the dimensions are of the piece it is copying makes me highly suspect that the copied frame could be deduced from existing data. I then attempted to run a script that would draw out all FrameGroups with -1 Frames, and then attempt to find any preceding frames that matched the dimensions of the -1 frame. All possibilities would then be tried, and laid out in such a way that it would be easy for a human to manually identify the correct assembly:

https://www.dropbox.com/s/i1ipz5pslp7lr09/MONSTER_minus_one_monster.zip?dl=0

A large number of sprites, when pushed through this algorithm, had only one possible solution, which meant that they were solved (the folder is preceded with the underscore). For the purposes of using the sprites for my standalone project, I considered applying this approach to all sprites out there to shrink the workload, and simply manually identify the correct assemblage from the remainder. Save for that Dugtrio (which has a lot of particle bits), it seemed like a straight shot...

However, when I ran this algorithm on the m_ground sprites, python nastily ran out of memory. I did a sweep check on just how many combinations the sprites had in there, and confirmed that some sprites had too much possibility depth to feasibly deduce even when the human eye and script automation were put together:

http://pastebin.com/9CGLahLK

(each number getting multiplied is a -1 frame, and its value is how many frames match up with its dimensions)

...It's all those darn story-releated animations, due to m_ground being the story-related sprites directory.

I guess my last hunch that may be worth pursuing is to count the amount of graphics (maybe by the number of 8x8 textures?) that get listed in a framegroup to see if there's any correlation between that, and the -1 Frame's copy target. I dunno. If worst comes to worst and I can't squeeze anything else out of this frame data, I'll probably just ignore those complex story-related frames and settle for the m_monster and m_attack frames. All of the frames in those subdirectories have much tamer probability spaces, and I didn't really need that animation of Dusknoir charging a giant shadow ball, after all... That said, I hope some portion of the info that came out of this hunt can help your searches, now or in the future.

Link to comment
Share on other sites

Nice work!

It definitely seems that the frames are assembled in reverse order!

One thing didn't sit right with me: given that -1 frames used existing memory, it would mean that they would be drawn after the original sprite piece. However, there's many places where -1 frames are at the END of a FrameGroup list, and never at the beginning. If frame pieces were truly drawn in reverse order, that would mean that the -1 frames are paradoxically pulling memory from a future state. Perhaps the draw order isn't in reverse, and the game just constantly draws behind (however strange that may be)? I was going to try and edit the position of Giratina's -1 Frame to overlap with the frame it copied, in an experiment of which frame would draw first, but I got sidetracked by a more general issue...

I doubt its that paradoxical. It could still be drawn from top layer to bottom when assembling the sprite, and it would mean the whole thing would still make some sense. At least, from what I know of the way the NDS works with sprites it could work. While running the game in No$Gba debug or demume you can look at the OAM and video memory, and that helped me with some of my findings. I think it could probably help seeing better what's going on, if you want to try.

I ran some experiments in the past, and some people helped me out testing it, and it truly seems like the value of unk15 decides what's going to be displayed by a -1 frame. The value seems to be split into 2 nybbles possibly, so that means there should be 15 possible variations to the way -1 frames are displayed. So maybe looking at the bits of that value themselves would yield better results?

I think testing it by changing the values to test hypothesis is probably a better way to go though. That's how I figured out 90% of the sprite format, and pretty much most of the other complex formats.

The data in the xml files is slightly formatted to be practical to a end-user though. Because some things just can't be represented in XML without introducing logical issues.

There's some extra redundancy in the wan files. And its worth noting that there's possibly things tied to the structure of the file that could impact what's displayed on a -1 frame.

Also, m_ground is the sprites loaded when the game is in "Ground mode" as they call it. Its the overworld, or anywhere outside a randomly generated dungeon. m_attack and monster are loaded in dungeons, and they're leaner because there's a lot of pokemon sprite loaded and its filling up the VRAM pretty fast and they just load stuff on the fly as needed. One interesting thing to note too is that in-dungeon sprites have a different layout than out of dungeon sprites when in the VRAM.

I'll try looking at it on my end too, but right now I was more focused on getting my script exporter/importer to work, so I can eventually make a script compiler out of it!

In other news:

I've been running tests with my script tools and its not perfect yet, but its interesting to note how messed up the game is when a few things aren't right :P

Most things seems normal, except the intro glitches out when the lapras scene pops in.

And then there's this. :

[video=youtube;h-SllEox9tI]

Everything looks fine until the last 43 seconds xD

And when beginning a game from scratch, this happens (Video limit is limiting me to one embedded video per post :/):

Still lots of fixing to do! I found out that some of the offsets are incorrect in the resulting files, so that might explain at lot ^^;

Link to comment
Share on other sites

I tested the monster and m_attack animations after porting them directly into my standalone application. I suspect there may be a few bugs, but just testing out charmander, charmeleon, and charizard revealed a few things.

monster

0- walk

5- sleep

6- hurt

7- idle

m_attack

1- regular attack

2- kick? (charmander kicks, charmeleon and charizard scratch)

3- shooting (flamethrower)

4- attack with arm/shooting? (charmander scratches, charmeleon/charizard shoots)

8- spin around attack (fling, feint attack)

9- double team/agility

10- jump a little, while in shooting animation (maybe digging?)

11- also a charging animation?

12- single twirl (item throwing, orb usage, etc)

-the order of the animations starts from downwards-oriented animation, and then goes counterclockwise.

-some pokemon have the same animation to do multiple things; e.g. the animations for charmander's "shoot" and "charge" are visually identical, but the animations for charizard have them different. You can see this in action by giving them both pokemon the moves Flamethrower(shoot) and Blast Burn(charge), and seeing how they execute them.

-animation 4 puzzles me. I'll have to check how it looks for more pokemon, because it appears ambiguous.

-when a pokemon (such as charmander) does its normal attack in PMD, it lunges forward and then springs back to its original position. However, the animation playback from the xml consists of its lunging forward, a long pause (514 units of pause!), an odd twitch (offset of movement), another long pause (258 units) and then the spring back.

EDIT: These long pauses only appear in attack-related animations, and seem to signify a critical point in the animation, such as then the attack is supposed to land, or hit. Now I just need to find a way to upload screencapped animations...

EDIT2: Perhaps the duration of a frame consists of one byte, and the other byte is for some special flag value?

Edited by Tabun_ne
Link to comment
Share on other sites

That makes sense. Those match the holes in the xml files I had too.

And yeah, all character animations follow that rule for orientation.

Yeah, there's a possibility something is off with the durations. I'm not really sure what it is exactly. It would need more in-game testing.

Also, I forgot to post this here, but script editing is on its way :D

[video=youtube;sbL3pTXxSd8]

Notice that extra last line of dialog? :P

Link to comment
Share on other sites

Amazing job! I have to say that I'm very impressed with how far you've managed to get with changing the script.

I'm interested in knowing, would it be possible to maybe add on to the original game's script? For example, creating entirely new cutscenes for when you complete a certain dungeon, or maybe even triggering boss battles?

On the subject of additions, I noticed a lot of DUMMY placeholders in the files I've ripped from the game using your tools, specifically KaoUtil and GfxCrunch. I know that it's possible to add new portraits on preexisting pokemon, but with these dummy placeholders, could it be possible to go as far as to add new pokemon into the game? Say, if we wanted to add in Arceus or perhaps a Primal Palkia? And if that was possible, what about adding new moves, or adding in completely new music tracks without replacing the old ones? And though this might be a VERY long shot, maybe it could be possible to push it even further and add new special episodes?

I don't know much about the actual ways we can modify Explorers of Sky so far, so it's entirely possible that none of these things are even slightly possible. But I'd definitely love to know if it could become a reality, even if only in the distant future.

Link to comment
Share on other sites

Thanks! ^^

Nerketur did it before though.

All of that is possible.

The script engine seems pretty flexible, and I've found the data in the binaries the game uses to refer to levels and etc.

You can trigger dungeons and etc from what I can see in the scripts. Cutscenes should be doable too.

Adding pokemons might be limited to the 1200 slots already available. 2 slot per gendered pokemon are needed. So replacing the dummies is definitely possible.

Menus are apparently hard-coded this far. But, I'm pretty sure it would be possible to hack the menus and add another episode to the list I guess.

We'd have to try it first to know for sure.

Also, here's a preview of what the script editor is outputting right now :

http://pastebin.com/949Skj8V

The structure will change a bit, but I'm heading towards making something very simple to use and edit.

I still need to figure what lots of things do though.

Link to comment
Share on other sites

I've been watching this thread for a few months now, and checking on updates every so often; just decided to make an account here since I wanted to try helping a bit, and well honestly I've been looking into hacking and messing around with this game for a very long time.

Furthermore, It's very great to see that people here have come forward with putting consistent effort into providing a lot of research development for this game, helping along with that, and cracking down on it (not that others haven't, but just from what I've personally seen on other forums similar). Quite frankly, the PMD community in general seems to really be amongst the latter in terms of hacking Pokemon games (so I'm very happy I found this place).

Anyways, I have been tinkering with your tools that you've provided, and I have been testing them out. I haven't encountered anything major (yet), and the tools do get the job done for their intended purposes.

However, I did want to share a few tidbits of information, and some stuff I did happen to figure out with the use of your tools.

In the monster.md, I founded out that the 0x1A (BitFlag1) is used for controlling the evolution parameter for a given Pokemon. I found that setting it to 0xb0 will not permit the Pokemon to evolve or be apart of an evolution line whatsoever (so it's pretty much used for majority of the legendary Pokemon). Setting it to 0x70 will permit the Pokemon to have an evolution into another Pokemon. Setting it to 0x30 will permit the Pokemon to have a previous evolution (so a Pokemon can evolve into it), but it will be impossible for the Pokemon to evolve into another Pokemon (so it would be used for a final stage evolution of course).

I did happen to notice a value of 0x60 on Kakuna, Silcoon, and Cascoon. I figure that 0x60 completes that same purpose as 0x70 does, but since the 3 of those Pokemon are in the same Category (Species) of Pokemon, I think explains why they have that value. However, Metapod undergoes the same species of them as well, but Metapod has a value of 0x70 instead of 0x60.

A logical explanation as to why Metapod has a value of 0x70 instead of 0x60, is because it's the first species of its kind, and it comes before Kakuna, Silcoon, and Cascoon going off of Pokedex numbers and placement of them in the game files. Since Kakuna, Silcoon, and Cascoon share the same exact evolution requirements as Metapod and are all of the same specie, must explain the special 0x60 value for them (to prevent conflict), and the difference in values at the 2nd evolution parameter @ 0x0E.

So, I think if you want to accomplish multiple Pokemon having further evolution's doing the exact same thing whilst having them all under the same Category (be the same species of one another), you would have to use the value 0x60 for those Pokemon instead of 0x70 (without there being issues I guess).

Don't 100% quote me on this though; I haven't tested this myself, but it's just what I think is the case by just my observations.

To add on, it is possible to evolve a Pokemon back into its pre-evolution state as shown in this video:

[OGV]http://puu.sh/q5x0V/d70950803a.ogv[/OGV]

It's pretty easy to accomplish, you just put a value of 0x30 @ 0x1A in the monster.md for the Pokemon you want to do this for, just make them evolve into one another. This could be useful to some people, and may even be quite neat or fun for others. However, you must keep in mind the +10 max HP and the +5 Atk/S.Atk/Def/S.Def each time you undertake an evolution.

I got the random idea of doing this in the first place, because of how Shaymin doesn't stay in it's Sky Form after you use a Gracidea on it (after you leave the dungeon). If you want a permanent Sky Form Shaymin, this method will work only if you make Shaymin evolve to something other than 535 (Sky Form Shaymin's regular Index number). That's because of how Sky Form Shaymin and or the Gracidea is programmed I'm pretty positive.

So what I did is just took one of Arceus's dummy slots and replaced all of its data with Shaymin's Sky Form, then changed @ 0x06 (Unk#1) to a value of 0x02 (for the passive sped up status Sky Shaymin has). Then, I made Shaymin evolve into my custom slot I made for a new Sky Shaymin, vice versa. Also yes, you can keep Index #535 untouched completely if you want to (as long as nothing conflicts with each other negatively).

Obviously this method isn't really neat, but if you are someone like me who gets tired of constantly going to go get a Gracidea every time before having to go into a dungeon, and then using it, then you could maybe work with this until a lot cleaner way is introduced with scripting, and or just modifying the game engine or whatever (no I'm not super knowledgeable with this stuff xD).

Dunno if this helps at all, but this was fun nonetheless c:

Link to comment
Share on other sites

I've been watching this thread for a few months now, and checking on updates every so often; just decided to make an account here since I wanted to try helping a bit, and well honestly I've been looking into hacking and messing around with this game for a very long time.

Furthermore, It's very great to see that people here have come forward with putting consistent effort into providing a lot of research development for this game, helping along with that, and cracking down on it (not that others haven't, but just from what I've personally seen on other forums similar). Quite frankly, the PMD community in general seems to really be amongst the latter in terms of hacking Pokemon games (so I'm very happy I found this place).

Anyways, I have been tinkering with your tools that you've provided, and I have been testing them out. I haven't encountered anything major (yet), and the tools do get the job done for their intended purposes.

However, I did want to share a few tidbits of information, and some stuff I did happen to figure out with the use of your tools.

[...]

Great find!

I've been wondering what that was for, and how special evolutions worked for a while, but I never had that much time to tinker with that. xD

Do you know a bit about binary btw? (pun not intended ^^; )

And sorry for not replying sooner. I've been somewhat busy, and I had connections issues on my main computer.. ^^;

And yeah, its annoying how little romhacking support the games have gotten from the community. That's pretty much why I began working on this. xD I knew basically nothing about reverse-engineering when I began too. So I guess when there's a will there's a way xD

If you ever find anything else interesting be sure to tell us! Its really helpful when others share their finding, since there's only a few of us, and it can take ages to do anything on our own!

And you said you didn't encounter anything major, but did you stumble across any small quirks or bugs?

I wonder if Luminous Spring's 10 character name bug could be looked into from there and possibly fixed as well.

What bug is that?

I'm not familiar with it.

Progress on the next version of statsutil:

So, I implemented all the scripting syntax feature I wanted to have for the first version. Now I'm mostly hunting bugs and fixing quirks, and testing.

The new recompiler is nearly ready to handle the new syntax features I've added.

I still have to fix and test the new commandline parameters for statsutil though.

I'm also wondering if I should focus on releasing the new statsutil with only script support added, or wait until I reversed the script/level data format as well? Since there's no way to add actors and props to a scene without editing the script data file.. I'm just looking for input on that.

Because if I'd release statsutil with only script support added, it would allow people to mess around and figure out things and bugs while I'm working on script data support, and random dungeon data support, and etc..

EDIT:

So, I put Gracidea's finding into bits, and I can see some patterns :

Lower byte's bits:                   Hex:                       Purpose:
-----------------------------------------------------------------------------------------------------
1011 0000                            0xB0                       Disable evolution, and pre-evolution?

0111 0000                            0x70                       Allow evolution as normal?
0110 0000                            0x60                       Apparently used for sillicoon and cascoon's evolution?

0011 0000                            0x30                       Pokemon has pre-evo, but won't evolve any further?

I'm pretty sure those individual bits do things separately on their own. Possibly testing with the values :

[font=Fixedsys]
0x10   0001 0000
0x20   0010 0000
0x40   0100 0000
0x80   1000 0000
[/font]

could give some more accurate answers? If you want to give it a try?

And I wonder if the low nybble does anything at all?

Link to comment
Share on other sites

What bug is that?

I'm not familiar with it.

There's apparently a bug in NA Sky with Luminous Spring; if you try to evolve a pokmemon that has its normal name or a nickname of exactly 10 characters the game will freeze (unless it was the last one recruited). It's fixed in all other versions, just NA has this issue.

Video:

[video=youtube;lpgvbDEFaRU]

Link to comment
Share on other sites

I'm also wondering if I should focus on releasing the new statsutil with only script support added, or wait until I reversed the script/level data format as well?

Please do! It might not be the full package yet, but I do like the idea of messing around and figuring out what can and can't be done just yet.

EDIT: I've also recently remembered a few more questions I've had about editing Explorers of Sky. I'm not sure how much of it would pertain to the script editing aspect, but it would still be neat to know!

1) Would it be possible to change attributes of a certain pokemon instead of its whole species? For example, say I want to give the zubat in the first dungeon's boss battle Pressure as an ability without affecting the rest of the species. Could that be done on its own, or would I need to create an entirely new zubat out of one of the dummy slots?

2) Can pokemon be assigned certain statuses before loading into an area? For example, force the player and partner to be at half health at the start of a boss battle, or maybe inflict confusion on the player pokemon?

3) Can it be made so that certain events you perform would influence others? At the least, I mean something like adding a new dungeon after clearing a special episode. At most, I would be talking about a boss battle being entirely different if you faint a specific amount of times in the dungeon before fighting them.

4) Can triggers be added in the overworld to begin certain events? To put it simply, I want to make it so that I can make a prompt appear that asks if you want to begin a special episode, but by examining an object that would normally have no purpose in the original game, such as a window or the back of a shop.

5) Could adding songs entirely instead of replacing them be a thing in the future?

And finally, 6) Would it be possible to force the game to skip certain prompts and/or restrictions entirely? Specifically, I'm referring to how story events are usually separated by days where you just do jobs. Is there any sort of way to remove at least some of these days, so that the story events are gotten to quicker? On top of this, after each day there is a prompt that asks if you want to save the game and/or return to the title screen. Can this prompt be replaced with an automatic save instead?

Again, I'm very impressed with the work you've done so far. I can't wait to see the possibilities!

Edited by Mariohuge
Link to comment
Share on other sites

Please do! It might not be the full package yet, but I do like the idea of messing around and figuring out what can and can't be done just yet.

It took me a while to make things works and fix all obvious bugs, but here you go:

https://app.box.com/s/ufet70cr9lxruusr4cl4uaib5rbi11ra

Its a crippled version of statsutil, since I still haven't fully fixed the commandline argument parsing. Its definitely not what I'd call ready for release, but its probably enough to mess with the scripts! It also supports ONLY the north american version of Explorers of Sky right now. I didn't test the european and japanese versions yet. And EoT and EoD need a lot more work before I can support them!

But you can drag and drop a ssb file on it, and it'll write an xml file. You then need to open a console in the same directory and type the name of the xml file plus the "-scripts" switch after to get it to compile your xml file. You have to make sure the pmd2data.xml file is in the same directory as both the file you're drag and dropping and the executable though.

Here are the command lines that'll work right now for handling scritps:

ppmd_statsutil.exe "script.ssb"

Decompile a single script file to xml.

ppmd_statsutil.exe "script.xml"  -scripts

Compiles a single script xml file.

ppmd_statsutil.exe -e -romroot "EoSRomRoot" "EoSStats" -scripts

The one above exports all scripts from the game into the "EoSStats" directory. If you omit the "-scripts" at the end, it'll just export everything supported right now, the scripts, game text, pkmn stats, moves, etc..

The "EoSRomRoot" directory contains arm9.bin and a directory named "data" which contains the rom's file. That's the typical layout when you export a rom using DSBuff or most other tools.

ppmd_statsutil.exe -i -romroot "EoSRomRoot" "EoSStats" -scripts

The one above compiles all the script's XML data presents in the "EoSStats/scripts" directory into the SCRIPT directory of the target "EoSRomRoot" rom root directory.

If scripts are missing or added it should keep going. It has to load COMMON.xml though! Its a quirk I have to fix, but I forgot to change it.

The XML for the script should be fairly straight forward. Most of what parameters and instructions do is unknown, but I managed to figure out a bunch of them, and convert them to user friendly names. Here's what a typical file may look like :

https://gist.github.com/PsyCommando/a2bc5c609f69a84fd56d35d9febd2445

The number appended to parameters (for example "_1") is just a dummy btw, it doesn't determine the order the parameter is parsed. Its simply to make it standard XML, so most parsers won't complain about duplicate attributes.

Here are some of the values ripped from the binaries that can be used (Not the event list stuff):

https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/ScriptEngine/arm9.txt

Here are all the instruction names, and the nb of parameters they take :

https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/ScriptEngine/opcodelist_eos.txt

It would probably be easier to look at what the dev did and mess around with the values to learn how it works.

Also, some command take a string as parameter, and because the european version of the game has several version of a string in several languages, I made strings a sub-node, instead of an attribute like most parameters.

EDIT: I've also recently remembered a few more questions I've had about editing Explorers of Sky. I'm not sure how much of it would pertain to the script editing aspect, but it would still be neat to know!

1) Would it be possible to change attributes of a certain pokemon instead of its whole species? For example, say I want to give the zubat in the first dungeon's boss battle Pressure as an ability without affecting the rest of the species. Could that be done on its own, or would I need to create an entirely new zubat out of one of the dummy slots?

You need to create a separate entity. Unless the entity itself is already a special entity. Some of the important pokemons have a unique entity that's not the base pokemon of their specie.

2) Can pokemon be assigned certain statuses before loading into an area? For example, force the player and partner to be at half health at the start of a boss battle, or maybe inflict confusion on the player pokemon?

The script engine is unloaded during dungeon play. So, I'm assuming that would need to be done via editing the ASM code of the game. You can set some dungeon parameters and flags before entering one though. Idk if its supported however.

3) Can it be made so that certain events you perform would influence others? At the least, I mean something like adding a new dungeon after clearing a special episode. At most, I would be talking about a boss battle being entirely different if you faint a specific amount of times in the dungeon before fighting them.

That could be possible. You'd need to add some custom flags though, or re-use existing ones. I'm planning on looking into ways to load custom lists of maps, actors, flags, and etc eventually, once I can get around to editing the game code directly.

4) Can triggers be added in the overworld to begin certain events? To put it simply, I want to make it so that I can make a prompt appear that asks if you want to begin a special episode, but by examining an object that would normally have no purpose in the original game, such as a window or the back of a shop.

That would be possible. But I need to reverse the level data, aka SSA/SSE/SSS format first. With the scripts only, you can't add new enities or markers or triggers, since all the position data is in the matching script data file.

5) Could adding songs entirely instead of replacing them be a thing in the future?

Most likely yes. audioutil isn't yet capable of importing midis and sample though. But its shouldn't be too hard.

And finally, 6) Would it be possible to force the game to skip certain prompts and/or restrictions entirely? Specifically, I'm referring to how story events are usually separated by days where you just do jobs. Is there any sort of way to remove at least some of these days, so that the story events are gotten to quicker? On top of this, after each day there is a prompt that asks if you want to save the game and/or return to the title screen. Can this prompt be replaced with an automatic save instead?

Via ASM editing its all doable. Via script, it might be doable, but I haven't had much time to dig around for those things, and I can't confirm or deny.

I know that unionall.ssb contains the strings for some of the prompts. And several other files do too!

There is a lot of pretty funny debug text that got translated too, and looking at those debug snippets helps understanding how the scripts works too!

Again, I'm very impressed with the work you've done so far. I can't wait to see the possibilities!

Thanks! ^^

Its my pet projects right now tbh, so I really enjoy messing with this game. xD

And I'm eager about seeing what people do with this too! xD

Edited by psy_commando
Link to comment
Share on other sites

Well, anything is possible really. If you're ready to put the time and effort. xD

I made a little video of some quick and dumb edits I did using the script editor:

[video=youtube;iuupE6EUdtg]

And here's my short term roadmap:

  • Scripts
    • Make script handling stable and as friendly as possible.
    • Figure out as many parameters as possible.
    • Reverse and implement script data support, make the matching data file "visible" to its script files.
    • Possibly validate references in-between files, like a sort of linker?
    • Write documentation.

    [*]Maps

    • Reverse map tiles format and implement support and editing.
    • Finish implementing sprites support + rewrite most of gfxcrunch.
    • Possibly add a way to auto cut down user inputed images into usable image strips.
    • Add support for menu and border import/export.
    • Add support for font + character map import/export.
    • Add support for animated backgrounds import/export.
    • Work on first release of level editor.

    [*]Audio

    • Get audioutil audio import working.
    • Possibly work on a dse player

    [*]Code

    • Make level(event) table loaded externally from a SIR0 into the game at runtime.
    • Make starter list loaded externally from a SIR0 into the game at runtime + possibly add more logics/questions etc to the personality quizz.
    • Investigate how to possibly add more actors.
    • And more..

Edited by psy_commando
Link to comment
Share on other sites

European EoS supported fixed! :

[ATTACH=CONFIG]13550[/ATTACH]

Here's an example of how the text for the european version is laid out:

<message_SwitchTalk svar="PARTNER_TALK_KIND">
   <CaseText int="0x1">
       <String language="English" value=" Let's go to Treasure Town." />
       <String language="French" value=" Allons à Bourg-Trésor." />
       <String language="German" value=" Auf nach Schatzstadt." />
       <String language="Italian" value=" Andiamo a Borgo Tesoro." />
       <String language="Spanish" value=" Venga, andando para\nAldea Tesoro." />
   </CaseText>
   <CaseText int="0x2">
       <String language="English" value=" We have to go to Treasure\nTown." />
       <String language="French" value=" Allons à Bourg-Trésor." />
       <String language="German" value=" Wir müssen uns nach\nSchatzstadt begeben." />
       <String language="Italian" value=" Dobbiamo andare a Borgo Tesoro." />
       <String language="Spanish" value=" Vamos a Aldea Tesoro." />
   </CaseText>
   <DefaultText>
       <String language="English" value=" We have to go to Treasure\nTown." />
       <String language="French" value=" Allons à Bourg-Trésor." />
       <String language="German" value=" Wir müssen uns nach\nSchatzstadt begeben." />
       <String language="Italian" value=" Dobbiamo andare a Borgo Tesoro." />
       <String language="Spanish" value=" Vayamos a Aldea Tesoro." />
   </DefaultText>
</message_SwitchTalk>
<Instruction name="message_Close" />

Also fixed the several issues with text the current build I linked in here has! (or at least I hope I did)

Here's the latest build. Its still not release ready though, and probably really buggy!! :

https://app.box.com/s/46p3cth904upbp3hq03vj1csfcav585i

Btw, guys I need your feedback!

Otherwise, I'll wait until I'm sure things are much more polished before releasing anything!

Link to comment
Share on other sites

So far the tool is working great!

However, in my attempt to add dialogue and some BGM fadeouts/fadeins, I keep getting an error when trying to recompile a script back into SSB. It goes:

PluginXML returned an error: "Error parsing start element tag"

Could it have something to do with the portraits, or simply the fact that I attempted to add new dialogue?

New dialogue looks like this:

<Instruction name="message_SetFace" actorid="PLAYER_PERAPPU" face_1="ANGRY" param_2="0x10" />

<Instruction name="message_Talk">

<String language="English" value=" But that's still no excuse!\nEspecially after all we've done!" />

</Instruction>

This is dialogue for Chatot during Sunflora's special episode. The "Angry" portrait was not in the original dialogue, as one can guess. I also copypasted the BGM instructions from both the introduction of Sunflora's episode and the scene right before the one I'm editing, rather than the instructions from the part where she meets with Magnezone, which is where this dialogue is changed.

The instructions look like this for the intro:

<Instruction name="bgm_PlayFadeIn" bgm="0x49" duration_1="0x0" param_2="0x100" />

<Instruction name="bgm_FadeOut" duration="0x96" />

And for the original dialogue:

<Instruction name="bgm_PlayFadeIn" bgm="0x8" duration_1="0x0" param_2="0x100" />

<Instruction name="bgm_FadeOut" duration="0x78" />

So what's going on? Why is this error occurring?

Link to comment
Share on other sites

Hard to tell from just that.

You might just have accidentally erased a < or something like that elsewhere maybe?

I made a new daily build :

https://app.box.com/s/bv0z12ksanioltp5zmy4v7i1bwl4r9a9

I did some bugfixing, I added handling for a few more parameters types, and improved the error output in some common cases. And I made it generate labels for a few more commands. I also got rid of the number that gets appended to attributes in the xml, except for nameless parameters.

Maybe it'll help a bit?

Link to comment
Share on other sites

Well, the new update does help me understand certain commands a bit better, though it didn't fix the problem with that specific script. At the very least, I have a better idea of what the problem could have been: the "CallCommon" command was not something I had copy-pasted in my previous XML. I made a new one to reflect the changes brought by the new tool and I am redoing the script to see if that was the problem.

EDIT: Nope. It seems the problem is adding new dialogue and/or lines in general.

Here's what I do when I add new dialogue:

First, I highlight a line of text so I can copy and paste it. An example of what I highlight:

<Instruction name="message_Talk">

<String language="English" value=" words go here..." />

</Instruction>

Then, I press the Enter key right after that line and paste the new text in.

I'm using notepad++ to edit the XML files, by the way.

I tested this in a different unedited script and encountered the same error I got before.

Is there another tool I should use other than notepad++ to edit the XMLs, or should I just wait for a new version of the script tool?

Edited by Mariohuge
Link to comment
Share on other sites

@Mariohuge

Does the tool says anything, or give any error message in particular?

Also, did you re-dump the script? Did you do a full export or you just export a single script?

And what xml file are you editing in particular?

If you want, you can also try atom : https://atom.io/

It does some nice highlighting and etc for xml.

But I use notepad++ too, so I doubt that's the issue. It might help seeing things better though.

Link to comment
Share on other sites

It just says the same thing I mentioned before. I'll quote the entire message:

!Exception caught!:

Exception: XMLToScript():Can't load XML document "n04a0107.xml"! Plugixml returned an error: "Error parsing element attribute"

Total time elapsed: Time elapsed: 7ms

I have not done the full export/import described in the first download's post, however. I have only used the method to compile singular scripts. I presume that, since you have mentioned this, it would be worthwhile to attempt this. For now, I will try to do this and report my findings.

Link to comment
Share on other sites

Hmm, I tried compiling the same script, and I got the same error. I probably broke single script import at one point. Thanks for the feedback!

I'll try fixing it. In the meantime, you can try the full import/export. It should work for now.

EDIT: I found the issue. The double quotes weren't escaped during export for some reasons:

<Instruction name="message_Mail">
   <String language="English" value="[CN]The Special Episode\n[CN]"Today's 'Oh My Gosh'"\n[CN]stars [CS:Y]Sunflora[CR] as the main character." />
</Instruction>

I'm considering making strings PCData or CData to avoid having to deal with this kind of stuff.

AKA store strings this way instead:

<Instruction name="message_Mail">
   <String language="English">[CN]The Special Episode\n[CN]"Today's 'Oh My Gosh'"\n[CN]stars [CS:Y]Sunflora[CR] as the main character.</String>
</Instruction>

Or maybe using this way:

<Instruction name="message_Mail">
   <String language="English"><![CDATA[[[CN]The Special Episode\n[CN]"Today's 'Oh My Gosh'"\n[CN]stars [CS:Y]Sunflora[CR] as the main character.]]></String>
</Instruction>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...