sylveonlove Posted February 22, 2015 Posted February 22, 2015 my apologies. I haven't seen the screenshots in-game so i thought it was like gates to infinity. Didn't like those graphics anyway the gba and ds ones were better
psy_commando Posted February 22, 2015 Author Posted February 22, 2015 Oh. Its alright. You also reminded me I had a couple more screenshots I wanted to get on the frontpage
psy_commando Posted February 26, 2015 Author Posted February 26, 2015 Alright, so I managed to get a little more data on meta-frames with -1 as their image index. Those files in the "/GROUND/" folder have orphaned images that aren't referred to by meta-frames ( in some all meta-frames have a -1 image index. Which begs the question, what is the image index for actually ?): "d28p34a3.wan" "d30p33a4.wan" "d51p11a1.wan" "d52p32a3.wan" "d52p32a9.wan" "d53p41a1.wan" "d57p43a2.wan" "h02p99c4.wan" "h02p99c5.wan" "p14p01a1.wan" "s01p01a1.wan" "s08p01a1.wan" "s13p01a1.wan" "s13p03a1.wan" "s13p03a2.wan" "s18p01a3.wan" "s18p01a4.wan" "s20p01a1.wan" "s20p01a2.wan" "v01p05b1.wan" "v01p05b2.wan" "v01p05b3.wan" "v04p03a1.wan" "v05p03a1.wan" "v05p03a2.wan" "v10p03c1.wan" "v19p06a1.wan" "v23p04a1.wan" "v24p04a2.wan" "v37p02a1.wan" And these files are pokemon sprites that got several -1 image indexes in their meta-frames : 0055_diglett 0056_diglett 0057_dugtrio 0058_dugtrio 0102_haunter 0119_koffing 0158_moltres 0277_houndoom 0400_mesprit 0408_magnezone 0423_dusknoir 0424_dusknoir 0425_dusknoir 0436_darkrai 0441_grovyle 0459_beautifly-f 0460_beautifly-m 0485_ninjask 0497_sableye 0502_aggron 0561_tropius 0587_latios 0589_groudon 0591_jirachi Looking at those and looking a debug output from my utility, I was able to figure out that, in every meta-frames groups* where at least one meta-frame has an image index of -1, the value of the "unk15" byte for that frame, or for preceeding and following frames, is non-zero! Or at least, it seems to be non-zero more often when there is a frame with an image index of -1 around! At first, I believed that, the value in unk15, only when the image index was -1, would essentially contain the index of the image the meta-frame refer to. And while it worked for a few sprites, its definitely not the case for all of them! And now, I've found sprites that have a unk15 value that wildly exceeds the amount of images stored in the sprite... For example a sprite with 60 images had unk15 values that would go up to 104! *Meta-frames groups represent a complete frame to be used as an animated frame. They usually contain a single meta-frame, but it can also contain several assembling them into a more complex resulting image. Meta-frames groups are pointed to by a table, which points to the area right after the SIR0 header, where the meta-frames are stored. The last meta-frame of a group has a bitflag to indicate that its the last frame in a group. All of that and more is detailed in my notes though. See my personal notes for details: https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/FileFormats/SIR0_Sprite.txt I'm really in need of a second opinion on this. I'm afraid I'm missing something possibly very obvious. That's what held me back last time, until TruePikachu popped up and basically figured most of the missing blocks at the time. If anyone has question on the format and wants to help researching, feel free to ask !
evandixon Posted February 26, 2015 Posted February 26, 2015 (edited) I haven't looked at the file format, but with the images you extract, and the xml files generated, I was able to make this program. Simply open it and point it to a directory that contains the xml files and image folder, and it will to the best of its ability show the animated version of it. Works (almost) flawlessly on small Pokémon sprites, and probably doesn't render larger ones 100% correctly. Any parts of the meta frame that do not exist (like -1, which turns into 65535 because I stored it in a uint16) are simply ignored, so you can tell what it's supposed to be. The background color should become transparent, but may not when those parts aren't loaded. Good work getting this far! [Edit] One more thing. Slight typo in the xml for frames.xml... <Resolution> <Width>32</Width> <[u]Heigth[/u]>32</[u]Heigth[/u]> </Resolution> Animation Viewer.zip Edited February 26, 2015 by evandixon
psy_commando Posted February 26, 2015 Author Posted February 26, 2015 I haven't looked at the file format, but with the images you extract, and the xml files generated, I was able to make this program.Simply open it and point it to a directory that contains the xml files and image folder, and it will to the best of its ability show the animated version of it. Works (almost) flawlessly on small Pokémon sprites, and probably doesn't render larger ones 100% correctly. Any parts of the meta frame that do not exist (like -1, which turns into 65535 because I stored it in a uint16) are simply ignored, so you can tell what it's supposed to be. The background color should become transparent, but may not when those parts aren't loaded. Good work getting this far! [Edit] One more thing. Slight typo in the xml... <Resolution> <Width>32</Width> <[u]Heigth[/u]>32</[u]Heigth[/u]> </Resolution> Wow, that's so neat ! I wanted to write one, but I never really got around to Well, actually, I had the base layout done and etc in C#, but then I completely messed up my project file because somehow a component is referring to itself and crashing the editor?? The debug output refuses to tell me which component or what line.. Anyways, honestly, I tend to prefer messing with the actual data than making GUIs (If I had made a dll with my code it would have been much more fun making UIs IMO) Also, I recently changed the XML structure a bit for the meta-frames, so for the next release it will be a little different. Here's an example of the new output: frames.xml <FrameGroup> <!--0--> <Frame> <ImageIndex>0</ImageIndex> <Unk0>0x0</Unk0> <Offset> <X>492</X> <Y>244</Y> </Offset> <Unk1>0xc</Unk1> <Unk15>0x0</Unk15> <Resolution> <Width>32</Width> <Height>32</Height> </Resolution> <VFlip>0</VFlip> <HFlip>0</HFlip> <Mosaic>0</Mosaic> <XOffsetBit6>0</XOffsetBit6> <XOffsetBit7>0</XOffsetBit7> <YOffsetBit3>0</YOffsetBit3> <YOffsetBit5>0</YOffsetBit5> <YOffsetBit6>0</YOffsetBit6> </Frame> </FrameGroup> (Also, the "name" attribute that some element have will be filled eventually, once I properly identify all the animation for each characters types! There are 2 main kinds so far. Regular characters have 13 animation groups, and extended characters (Hero/Partner) have 35. And then some specific pokes have extra animations too for cutscenes.) However, I probably won't change it again afterwards. Well, I mean, besides the tags that begin with "unk". And possibly the meta-frame offset values. Because, according to what I gathered(turtwig's sprite), the actual perfect center is around 248, 490. So I could basically subtract that from the value to give something relative to the center of the sprite "layer". But, I'm still not sure why the number is that big in the first place, so to be really careful I just write it as-is. I also feel that the naming for meta-frame and meta-frames group is a bit unintuitive and I'd like to change that to something more accurate. For example, a meta-frame group is basically the actual meta-frame the game refers to, not a group of meta-frames. And meta-frames are really a construct of possibly several images.. If you have any suggestions on that it would be appreciated! I'm not a native english speaker too, so that doesn't help Also, thanks for pointing out the typo! For some obscure reasons I always mix up the way the "th"/"ht" at the end of length and height are written ^^; And a -1 index doesn't necessarily implies that the image doesn't exist or can't be displayed. If you look at diglett for example, he leaves a little trail of dirt when he moves around. And it seems that, by using -1, the game instead of allocating another slot in memory to load that dirt image again, just refers to the instance of that image that's already loaded. If you want to have a better idea of what I mean, look at these videos : This is a modified bulbasaur sprite, where the frames of all the running animations are -1. But the idle animations and etc, are all untouched. You'll notice that the game just takes whatever is loaded in memory at the time and tries to display it according to the parameters of the -1 meta-frame. Its especially obvious when I move from one map to the other, moving into the mess hall and out, or climbing the ladder, etc.. : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/temp/gfxutil_repack_15_28415.avi This one is another modified bulbasaur sprite, but this time I copied twice the single meta-frame in several meta-frame groups, offset them a little, and changed the image index for those extra meta-frames to -1 ( keeping unk15 set to 0) : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/temp/gfxutil_repack_57_1074.avi And thanks for the compliment, its really appreciated
psy_commando Posted February 27, 2015 Author Posted February 27, 2015 Alright, I made a new alpha release. Hopefully it got much more robust now ! I fixed a ton of annoying little things. And now, you don't have to update the frame.xml file when you change the resolution of an image. As long as the image resolution is one of the valid ones, the utility will automatically fix all references to that image. And it can be turned off using the -noresfix option! Here's the download link: https://github.com/PsyCommando/ppmdu/releases/download/ppmd_GfxCrunch_0.13a/ppmd_gfxcrunch_0_13.zip * Disabled raw image inport/export for sprites, as it causes issues and is generally not worth it. The program will default to PNG if the raw image format is specified at the command line! * Changed the format of the XML being outputed. So the output of the earlier version cannot be read by this version correctly! * Fixed a bug with character sprites(type 1) that had no particle offset. A null pointer would be written to the WAN header, but only type 0 sprites can have that pointer null! * Fixed SIR0 encoded pointer list for sprites that had null pointers in their header. The null pointers would not be properly skipped when building the list! * Added support for unpacking PKDPX compressed sprites directly. * Fixed logging so that its turned off by default! * Log files are now named after the input filename/directory name! * Added automatic updating of the sprite's meta-frames resolution, when the meta-frame refers to an image in the "imgs" folder, and the resolution of the image differs from the one in the XML data. * Added command-line option "noresfix" to disable the above feature. * Fixed printing of the readme triggering an exception. * Modified the sprite pack file building code so that sprite directories in the input folder do not need to begin with a number! The files are instead read in alphanumerical order. * And a lot of little things.. I've been holding back on this one for a while to make sure it works and that it isn't too rough around the edges. So I hope there won't be too many issues with it !
psy_commando Posted March 2, 2015 Author Posted March 2, 2015 Alright, since I'm really stuck when it comes to sprite research, I began looking at other formats. And I found the level-up data for all pokemons. Its all stored in "/BALANCE/m_level.bin". The file is a pack file that can be unpacked using ppmd_packfileutil, and then the individual files are sir0 wrapped pkdpx compressed files. I have updated dopx and unpx to handle those without having to manually remove the SIR0 container with an hex editor. I'll post the new binaries later today. I'll also update the wiki, but there is still a little doubt in my mind with the order the stats are stored.. /BALANCE/m_level.bin --------------------- m_level.bin is a pack file, with each of its sub-files compressed into PKDPX files, and then wrapped into SIR0 containers. The first sub-file index seems deliberately forced to 0x1200, given there is an extra unneeded row of 0xFF padding before the first one. Its purpose is to indicate the total amount of experience required to reach a level, and indicate the stat increase for each levels up until level 100, for every pokemon in the game! The structure of its sub-files, once decompressed, and after having been removed from its SIR0 container, is exactly the same for each of them. - 571 sub-files. 1 for each pokemons. And possibly a few that are used for special purpose, given there are less pokemon than that in gen 4? - Exactly 100, 12 bytes entries, one after the other. - The entry for level 1 is entirely null, given there is no level 0, and no exp requirements or stat growth needed. Base stats must be stored somewhere else! The first three entries are for Bulbasaur, Ivysaur and Venusaur. The 3 are identical though. But if someone wanted it'd be possible to change each's stats growth individually! The format of a single entry goes as follow: Offset Length Type Description ------ ------ ---- ----------- 0x0 4 int32 The total amount of experience needed to reach that level. 0x4 2 uint16 HP growth for this level. 0x6 1 uint8 Attack growth for this level. 0x7 1 uint8 Defense growth for this level. 0x8 1 uint8 Special attack growth for this level. 0x9 1 uint8 Special defense growth for this level. 0xA 2 uint16 Null. ------ ------ ---- ----------- Total: 12 bytes See my notes : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/FileFormats/m_level.txt Also, I took a quick look at "/BALANCE/waza_p.bin". And looking at a japanese dictionary, "waza" or "わざ" or 技, means technique/art. It most likely refers to either moves or TMs. So I'm going to take a look at that too. EDIT: Here are the new utilities binaries that supports the sir0pkdpx and sir0at4px formats properly!: ppmd_packfileutil 0.53: https://github.com/PsyCommando/ppmdu/releases/download/ppmd_packfileutil_0.53/ppmd_packfileutil_0_53.zip ppmd_dopx 0.31 : https://github.com/PsyCommando/ppmdu/releases/download/ppmd_dopx_0.31/ppmd_dopx_0_31.zip ppmd_unpx 0.41 : https://github.com/PsyCommando/ppmdu/releases/download/ppmd_unpx_0.41/ppmd_unpx_0_41.zip Will update front page shortly.
evandixon Posted March 2, 2015 Posted March 2, 2015 Also, I took a quick look at "/BALANCE/waza_p.bin". And looking at a japanese dictionary, "waza" or "わざ" or 技, means technique/art. It most likely refers to either moves or TMs. So I'm going to take a look at that too. Seeing that there's 2 waza_p files, I'd speculate that one is level up moves and the other is TMs. But I can't say since I've done no research on it at all. It would be cool to control this sort of thing. Maybe in the near future I can use your tools/research to make an editor for m_level.bin, so we can be 100% sure which stat is which. It might be ordered differently, because I looked in JEditor's source for handling Pokémon, and the stats are ordered: Attack, Sp. Attack, Defense, Sp. Defense. It's also possible that the developers used an inconsistent order for storing stats, but that'd just feel weird.
psy_commando Posted March 2, 2015 Author Posted March 2, 2015 It would be cool indeed ! One thing I noticed is that, one of the section in the waza_p.bin file has a number of entries very close to the pokemon count, so maybe that's actually what it is. Here's what I got on the file's layout this far: Offset Length Type Description: ------- ------ ---- ------------ 0x0 4 char[4] SIR0 magic number 0x4 4 uint32 Pointer to WazaHeader 0x8 4 uint32 Pointer to SIR0 encoded ptr list 0xC 4 - Null DataBlockA - Unknown [ ... ] PaddingBytes 0-3 - 0xAA padding bytes to align the next block on 4 bytes. DataBlockB - Seems to contain pokemon data. Has 559 entries of 26 bytes each! [ Entry 26 - An entry. [ ] ... ] PaddingBytes 0-15 - 0xAA padding bytes to align the next section on 16 bytes. PtrTable - A table of pointers to entries within DataBlockA. [ Pointer 4 uint32 A pointer to an entry within DatablockA. ... ] PaddingBytes 0-15 - 0xAA padding bytes to align the next section on 16 bytes. WazaHeader 8 - The header the SIR0 refers to. [ PtrDataBlockB 4 uint32 A pointer to the beginning of DataBlockB. PtrPtrTable 4 uint32 A pointer to the beginning of the PtrTable. ] PaddingBytes 0-15 - 0xAA padding bytes to align the next section on 16 bytes. SIR0EcodedPtrOffsets - The encoded ptr list for the SIR0 container. [ ... ] https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/FileFormats/waza_p.txt Actually I tested changing values in the game, and it worked as expected, but I lost my evening yesterday, because I had a brainfart while trying to figure out which value is which. I forgot that I had a cheat to change the exp for the partner pokemon, which was bulbasaur. And I forgot it was on. So I thought I was somehow corrupting the values because bulbasaur had always a negative exp count towards the next level. So I wasted a lot of time packing and repacking everything a hundred times, trying to figure out what I was doing wrong.. So, I'm still not too eager to test this yet again. For now But I'm pretty sure this ordering is the correct one.. And what's JEditor ?
evandixon Posted March 2, 2015 Posted March 2, 2015 And what's JEditor ? My program, Sky Editor, was the first save editor for Explorers of Sky. matix2267 did more research, especially on Pokémon, making Sky JEditor (Sky Editor, in Java). Both our tools are open source, so I incorporated some of his java code into Sky Editor, applying it for the older games (Time/Darkness/Red/Blue). If the stats are really stored in different orders in the save and ROM, the developers must have a cruel sense of humor. That, or they were made by different people who didn't directly collaborate.
psy_commando Posted March 2, 2015 Author Posted March 2, 2015 Oh, alright. I thought you were saying an existing editor was able to edit m_level.bin. And, if you're saying that they're in the opposite order in the savegame, its also possible they're in that order in the stat growth file. I had to guess the value over several level-up, because of that dumb mistake I did yesterday, so even though I put different values in each slots Its possible the reading was inaccurate... But like I said, after I take a little break, I'll do this properly. Unless you want to try it yourself ? I put up the updated tools you'd need to make this much much easier to edit than having to remove and put back the SIR0 container over the compressed pkdpx! I also wrote 3 handy little batch scripts to batch decompress and compress the content of a folder passed as argument: (just replace the exe names with however they're named on your side ^^ Batch compress to "sir0pkdpx" the content of a folder, and delete the input file: @echo off for %%f in (%1\*.*) do ( ppmd_dopx_xp.exe -z "%%f" "%%f.sir0pkdpx" del "%%f" ) Batch decompress only "sir0pkdpx" files inside a folder, and delete the input file: @echo off for %%f in (%1\*.sir0pkdpx) do ( ppmd_unpx_xp.exe "%%f" del %%f ) And here's another one to build the m_level.bin file with the forced fist file offset: @Echo off ppmd_packfileutil_xp.exe -a 0x1200 %1 All of these work with drag and drop, which is really convenient! Howver, it might just be easier to just decompress, edit and recompress a single file I recommend using bulbasaur, if you want to try, because we're sure he's always the very first pokemon!
psy_commando Posted March 3, 2015 Author Posted March 3, 2015 Alright, I figured out the exact order of the stats: Offset Length Type Description ------ ------ ---- ----------- 0x0 4 int32 The total amount of experience required to reach that level. The value is absolute, not relative to the last level! 0x4 2 uint16 HP growth for this level. 0x6 1 uint8 Attack growth for this level. 0x7 1 uint8 Special attack growth for this level. 0x8 1 uint8 Defense growth for this level. 0x9 1 uint8 Special defense growth for this level. 0xA 2 uint16 Null. ------ ------ ---- ----------- Total: 12 bytes Its basically Attack, SpAttack, Defense, SpDefense. I had to set to 0 the stats growth for the previous levels to get a better reading. And at the same time I noticed that the base stats for bulbasaur are : Atk 3 Def 2 SpA 4 SpD 3 This will probably help finding where base stats are stored.
psy_commando Posted March 6, 2015 Author Posted March 6, 2015 (edited) I figured out a big part of the format of "/BALANCE/monster.md" ! Its very straightforward. I was able to deduct a lot of it just by cross referencing and comparing pokemon with similarities together! monster.md ----------- This file contains the base data for every pokemon in the game. NOTES: - The first entry is a dummy entry. - The file contains 1,155 entries. Offset: Length: Type: Description: ------- ------- ------- ----------------------------------- 0x0 4 char[4] Magic number "MD\0\0" { 0x4D, 0x44, 0x0, 0x0 } 0x4 4 uint32 NbPokemonEntries PokemonData (NbPokemonEntries-1) This contains the data for all the pokemon in the game! [ PokemonEntry 68 Entry for a single pokemon. [ 0x00 NatDexNb#1 2 uint16 National pokedex number. (Can be null in some entries) 0x02 Category 2 uint16 The index of the pokemon's category string. "Seed Pokemon" for example.(Can be null) 0x04 NatDexNb#2 2 uint16 The national pokedex number, again? 0x06 Unk#1 2 uint16 unknown, seems to be 0x1 for most pokemon ! In the later entries, it contains a number that increases. 0x08 PreEvoDexNb 2 uint16 The national pokdex number for this pokemon's pre-evo. Is 0 if no pre-evo! 0x0A EvolutionMethod? 2 uint16 The evolution method required to evolve to this pokemon. Null if unused. (See evolution methods below) 0x0C EvoParam#1 2 uint16 The first parameter for the evolution method. Null if unused. 0x0E EvoParam#2 2 uint16 The second parameter for the evolution method. Null if unused. 0x10 SpriteIndex 2 uint16 The index of the pokemon's sprite. Its the index inside the three pokemon sprite files inside the "/MONSTER/" directory! 0x12 Unk#4 1 uint8 Unknown 0x13 Unk#5 1 uint8 Unknown 0x14 PrimaryType 1 uint8 The pokemon's primary type. (see pokemon types below) 0x15 SecondaryType 1 uint8 The pokemon's secomdary type. 0x16 Unk#8 1 uint8 Unknown 0x17 IQGroup 1 uint8 The pokemon's IQ group (see IQ group below) 0x18 PrimaryAbility? 1 uint8 The pokemon's primary ability's ID. (see abilities below) 0x19 SecondaryAbility? 1 uint8 The pokemon's secondary ability's ID. (can be null) 0x1A Unk#11 2 uint16 Unknown 0x1C Unk#12 2 uint16 Unknown 0x1E Unk#13 2 uint16 Unknown, often is the same value as Unk#14 ! 0x20 BaseHp? 2 uint16 The hp the pokemon has at lvl 1? 0x22 Unk#14 2 uint16 Unknown, seems to often be the same value as Unk#13 ! 0x24 BaseAtk 1 uint8 The attack stat of the pokemon at lvl 1. 0x25 BaseSpAtk 1 uint8 The special attack stat of the pokemon at lvl 1. 0x26 BaseDef 1 uint8 The defense stat of the pokemon at lvl 1. 0x27 BaseSpDef 1 uint8 The base special defense of the pokemon at lvl 1. 0x28 Unk#15 2 uint16 Unknown, seems to be 0x99 on several pre-evos. 0x2A Unk#16 2 uint16 Unknown 0x2C Unk#17 1 uint8 Unknown 0x2D Unk#18 1 uint8 Unknown 0x2E Unk#19 1 uint8 Unknown 0x2F Unk#20 1 uint8 Unknown 0x30 Unk#21 2 uint16 Possibly max level for the pokemon ? 0x32 Unk#22 2 uint16 Unknown. 0x34 Unk#23 2 uint16 Seems to be part of an array together with the 3 next values 0x36 Unk#24 2 uint16 0x38 Unk#25 2 uint16 0x3A Unk#26 2 uint16 End of array. 0x3C Unk#27 2 uint16 Unknown 0x3E Unk#28 2 uint16 Unknown 0x40 Unk#29 2 uint16 Unknown 0x42 Unk#30 2 uint16 Unknown ] ... ] ------- ------- ------- ----------------------------------- =========================== Evolution Requirements =========================== Here are the possible values for the evolution requirement, and how the value of the parameter is used / split : *NOT 100% sure* Value Method Parameter(s) ( 4 bytes available ) ----- ------ ------------------------------------------------- 0x01 Level(+Item) (uint16)Level required to evolve,(uint16)Item ID 0x02 IQ(+Item) (uint16)IQ Req, (uint16)Additional Item ID? 0x03 Item(s) (uint16)Item ID ? (uint16)Additional Item ID? 0x05 Link Cable (uint16)0x00, (uint16)0x01 Known Item IDs --------------- 0x8B - Up-Grade 0x8C - King's Rock 0x8D - Thunderstone 0x8E - Deep Sea Scale 0x8F - Deep Sea Tooth 0x91 - Moonstone 0x92 - Fire Stone 0x93 - Water Stone 0x94 - Metal Coat 0x96 - Dragon Scale 0x98 - Dubious Disc 0x9A - Reaper Cloth 0x9B - Razor Fang 0x9C - Razor Claw 0x9D - Electirizer 0x9E - Magmarizer 0xA3 - Coronet Rock 0xA4 - Mossy Rock 0xA5 - Icy Rock Known Other Item IDs ? ------------------ 0x01 - Link Cable ? 0x04 - 0x05 - Sun Ribbon 0x06 - Lunar Ribbon 0x07 - Beauty Scarf ### NOTE TO SELF : 3 evo-related uint16 for the following evos IQ Togetic 0x02 0x96 0x00 Crobat 0x02 0x96 0x00 Pikachu 0x02 0xC8 0x00 IQ + Item Espeon 0x02 0x64 0x05 Umbreon 0x02 0x64 0x06 Link Cable Gengar 0x05 0x00 0x01 Item + Link Cable Slowing 0x03 0x8C 0x01 Steelix 0x03 0x94 0x01 Kingdra 0x03 0x96 0x01 Electivire 0x03 0x9D 0x01 Magmortar 0x03 0x9E 0x01 Porygon2 0x03 0x8B 0x01 Porygon-Z 0x03 0x98 0x01 Dusknoir 0x03 0x9A 0x01 Gorebyss 0x03 0x8E 0x01 Huntail 0x03 0x8F 0x01 ### ======================= Pokemon Types ======================= Here are the possible values for the pokemon type bytes : Value Type ----- ---------- 0x00 -NONE- 0x01 Normal 0x02 Fire 0x03 Water 0x04 Grass 0x05 Electric 0x06 Ice 0x07 Fighting 0x08 Poison 0x09 Ground 0x0A Flying 0x0B Psychic 0x0C Bug 0x0D Rock 0x0E Ghost 0x0F Dragon 0x10 Dark 0x11 Steel ============== IQ Group ============== Here are the possible values for a pokemon's IQ group: Value IQ Group ----- --------- 0x00 A 0x01 B 0x02 C 0x03 D 0x04 E 0x05 F 0x06 G 0x07 H 0x08 - (Not sure why those two are skipped ) 0x09 - 0x0A I 0x0B J ========================= Pokemon Abilities ========================= Here are the possible abilities: Value Ability ----- ------------ 0x06 Intimidate 0x10 Torrent 0x13 Shell Armor 0x24 Water Absorb 0x2B Run Away 0x46 Blaze 0x47 Pickup 0x4C Shield Dust 0x59 Gluttony 0x63 Adaptability 0x6D Quick Feet 0x1A Overgrow (Latest version of my personal notes : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/FileFormats/monster.md.txt ) I'm also working on a utility to organize and convert all the stats data spread over several files inside the /BALANCE/ directory into XML, along with possibly the other data directories introduced in EoS. I'm going for a one file per pokemon and per category approach this time, since its much less complex than the sprites! Of course, the utility will be able to put everything back together into the appropriate files from the XML! (For the "mappa_*.bin" and "mappa_g*.bin" files I'll have to do something differently probably, as those are tightly linked to every individual dungeons.) EDIT: Seems like I forgot that truepikachu already had figured out a big chunk of "monster.md" and the stats growth.. http://projectpokemon.org/forums/showthread.php?40199-Pokemon-Mystery-Dungeon-2-Psy_commando-s-Tools-and-research-notes&p=192560&viewfull=1#post192560 Anyways, I guess at least I validated some of those things... Though I wasted a lot of time doing all that from scratch.. Edited March 8, 2015 by psy_commando
Jellynater Posted March 7, 2015 Posted March 7, 2015 Here I have what I found from part of the RAM. This is just about a pokemon while in a dungeon, at some point I will post the other bits I found.
Anty-Lemon Posted March 7, 2015 Posted March 7, 2015 Here I have what I found from part of the RAM.This is just about a pokemon while in a dungeon, at some point I will post the other bits I found. If PMD2's Pokemon data is set up like PMD1's is (which is likely), the block you found does not contain all of the hero Pokemon's data. The tile the Pokemon is currently standing on has a pointer to the beginning of the Pokemon's data, which in turn has a pointer to the beginning of that block.
psy_commando Posted March 15, 2015 Author Posted March 15, 2015 So I learned some more stuff on the monster.md, m_level.bin, and waza_p.bin files! waza_p.bin contains the list of level-up moves, HM/TM moves, and egg moves that each pokemon can learn! Each group of 3 pointers points to the 3 lists for a single pokemon. The lists are encoded integers, and should be decoded in a similar fashion to the SIR0 encoded ptr offset list, without adding each subsequent results to each others, just like the stats growth entries in m_level.bin! The level-up move list is basically just the move id, and then the level at which its learned. The HM/TMs list and egg moves list are just a list of move ids. Here are the values for Bulbasaur decoded by hand: Level-Up list: 81 1A 01 => 0x9A, 1 => Tackle lvl 1 81 59 03 => 0xD9, 3 => Growl lvl 3 82 49 07 => 0x149, 7 => Leech Seed lvl 7 81 36 09 => 0xB6, 9 => Vine Whip lvl 9 81 47 0D => 0xC7, 13 => Poison Powder lvl 13 81 67 0D => 0xE7, 13 => Sleep Powder lvl 13 81 4B 0F => 0xCB, 15 => Take Down lvl 15 81 7B 13 => 0xFB, 19 => Razor Leaf lvl 19 0A 15 => 0x0A, 21 => Sweet Scent lvl 21 81 14 19 => 0x94, 25 => Growth lvl 25 81 0C 1B => 0x8C, 27 => Double-Edge lvl 27 83 78 1F => 0x1F8, 31 => Worry Seed lvl 31 5E 21 => 0x5E, 33 => Synthesis lvl 33 83 66 25 => 0x1E6, 37 => Seed Bomb lvl 37 00 HM/TMs list: 0x12 => 18 => Cut 0x18 => 24 => Swagger 0x1D => 29 => Rock Smash 0x30 => 48 => Return 0x32 => 50 => Strength 0x38 => 56 => Double Team 0x43 => 67 => Facade 0x4C => 76 => Giga-Drain 0x68 => 104 => Endure 0x81 0x17 => 151 => Solar Beam 0x81 0x23 => 163 => Bullet Seed 0x81 0x35 => 181 => Swords Dance 0x81 0x45 => 197 => Toxic 0x81 0x5F => 223 => Sunny Day 0x81 0x63 => 227 => Sleep Talk 0x81 0x68 => 232 => Rest 0x82 0x07 => 263 => Secret Power 0x82 0x11 => 273 => Flash 0x82 0x18 => 280 => Sludge Bomb 0x82 0x2D => 301 => Protect 0x82 0x30 => 304 => Substitute 0x82 0x44 => 324 => Hidden Power 0x82 0x46 => 326 => Attract 0x82 0x48 => 328 => Frustration 0x82 0x68 => 360 => Wide Slash 0x83 0x0A => 394 => Vacuum-Cut 0x83 0x3B => 443 => Energy Ball 0x83 0x4A => 458 => Grass Knot 0x83 0x57 => 471 => Natural Gift 0x84 0x16 => 534 => Captivate 0x00 egg moves list: 0x0B => 11 => Charm 0x54 => 84 => Grass Whistle 0x77 => 119 => Nature Power 0x81 0x06 => 134 => Safeguard 0x81 0x57 => 215 => Amnesia 0x81 0x69 => 233 => Ingrain 0x81 0x6D => 237 => Curse 0x81 0x7D => 253 => Petal Dance 0x82 0x03 => 259 => Light Screen 0x82 0x29 => 297 => Magical Leaf 0x82 0x5C => 348 => Skull Bash 0x84 0x19 => 537 => Leaf Storm 0x00 (I used the "item_p_Sky.xlsx" excel datasheet (the keyvalues sheet) from over there to get the move ids : http://apointlessplace.net/wms/research/ ) Here are my latest notes on the format: https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/FileFormats/waza_p.txt The other part of the file contains data for every single moves in the game! They're all ordered in the same way as in the excel sheet. Move #1 is Iron Tail for example. The typing of the move is not contained in there however.. Replacing everything with random junk changed the way the move worked, the effects, the amount of PPs, the accuracy, and etc. But not the typing.. Also, I'm able to parse and write back perfectly the waza_p.bin and monster.md files now with my code! m_level.bin isn't perfect, but only because my PX compression algorithm is a little less efficient on that kind of data. The file is read fine in-game however. They probably have some kind of optimization going on depending on the type of content. I usually get better compression on images, by on data that doesn't repeat itself a lot I get worse results than the original files. Still its like 5% bigger, so not such a big issue.. I still don't know what the waza_p2.bin file is for exactly... waza_p2.bin is only in EoS, and has a lot of duplicate entries with waza_p.bin, from looking at a binary comparison. I don't know yet how the game decides which one to use, or if its even using both! Also, changing all entries in "monster.md" to 0 or 1 randomly will cause this : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/randomvals_monstermd4.avi https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/randomvals_monstermd5.avi Notice how for some reasons some pokes that don't evolve normally, like chatot are the evolved form of bulbasaur, instead of being a bulbasaur.. Also notice how the AI refuses to move around, I'm not exactly sure why.. And the base experience gain seems to be stored somewhere in monster.md, since I would only get 1 exp from fainting starly. The game seems fairly robust with random values (still nowhere near as robust as Pokemon : Gale of Darkness! That game was unkillable ) Now, the big issue I'm left with, is that I have no ideas how the game associates the data in monster.md, with the rest spread around several other files.. They all have a different amount of entries.. MoveSets : 553 StatsGrowth : 571 MonsterMD : 1,155 Kaomado : 1,155 And it appears that, "monster.md" doesn't contain info on what entry in each files to use.. kaomado.kao and monster.md are however perfectly aligned to eachothers, and the portraits are most likely assigned by matching entry indexes from both files! But, it doesn't appear to be the case for the others. This is very, very problematic, because as long as I can't figure this out, I'm stuck. I can't output or label properly the data I'd convert from those files, if I can't link them together! Any input or ideas on how to find those links would be really much appreciated !! I'm guessing there is a possibility its a table inside the overlays, or the main binary.. And while I'm working on ppmd_statsutil, here are 2 little utilities for ROM researchers. If you have no ideas what they're for, you probably don't need those. They're just more convenient than having to decode all those numbers by hand : SIR0PtrOffsetsDecoder : Use this to decode a SIR0 pointer offset list, which can help tremendously in finding out more about what a sir0 file contains! Just copy/paste the SIR0's ptr offset list only, and put it into its own separate file, and drag-and-drop that onto the .bat file, it will output the result in "decoded.txt". The program itself only output the result to the console, so use the batch script, or pipe the output! IntegerListDecoder : Use this one to decode a list of encoded integers. Things like the stats growths in "m_level.bin", the move lists in "waza_p.bin". You can just put all the lists one after the other in a new file, and drag-and-drop that onto the .bat file and all the decoded lists will be outputed to "decoded.txt" ! Here I have what I found from part of the RAM. This is just about a pokemon while in a dungeon, at some point I will post the other bits I found. Thanks! It might come in handy later! That "faction" ally/enemy byte stands out as pretty interesting to me! Its an odd way of doing things.
psy_commando Posted March 20, 2015 Author Posted March 20, 2015 Alright, so I figured out how they're all linked together.. Its something I was told several times over, but I never really believed... The pokemons in kaomado.kao, and monster.md, aren't pokemon, but more like unique entities. And for every single pokemon, there is duplicate entity with for only difference its gender. For pokemons with a single gender or one that's genderless, that second entry has an invalid gender value. This basically means that, it would be possiblt to add face portraits for the females of any species if you've want to Also for people using the awesome Hex Edit hexeditor(I don't think I could have figured half of everything I did without that hexeditor! Rainbow hex data color scheme ftw! Source code is also available), I managed to implement integer decoding and sir0 offset decoding! Using this I was able to make a move data viewer, and a SIR0 pointer locator. It makes things so easy. So I'm going to share them here (Just put the xml files in your Hexedit appdata folder. Or wherever you put your template folder if you changed it from the default. By default, just open up a file explorer window and type this in the address bar : "%APPDATA%\ECSoftware\HexEdit" without quotes, and paste the xml files in there. ) And then to open them, just open the file you want to use this on, and go into the top menu bar "Template->Open Other->waza_p.bin" for the waza_p.bin file, or "Template->Open File Type->SIR0 File". If your SIR0 file has .sir0 file extension, hex edit will open it automatically once you open the template sidebar ! To open the template sidebar, just go into the "Template" menu, and check either "Split Window" or "Tabbed Window". To hide the template sidebar, just check "Hide Tree View". For people looking to find the pointer location in an unknown SIR0 file, this would probably come in handy : Template file here: https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/hexedit_templates/_sir0.xml And for those looking to investigate or modify move data in the waza_p.bin files : Template file here : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/hexedit_templates/waza_p.bin.xml By default however, Hex Edit will only display the first 20 elements in all lists. To change that, go into "Tools->Options->Workspace->Templates" and set the value to something bigger, I usually set mine to 600+, when not testing, and I set it to a lower value when testing, because some templates can freeze the whole thing when they're very complex! And to see the actual values, and edit them easily, you should right click on the grey bar with the name of the template, and check the "Data" entry in the popup menu. Stretch the sidebar as needed. And then, when its possible to edit data, you can just double click on the data, and you'll be able to edit the value and input it as either hex or decimal, or when its an enum field, you'll even get a nice dropdown menu for picking an option ! Just be sure to uncheck "Design Mode" in the "Template" menu, because it will freeze. The structure of the whole thing in design mode is a little too much to handle for the tree display. I wrote it all directly in the XML, so I didn't use design mode much. https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/Tutorials/UsingHexEditTemplate/RecommendedSettings.png Both of those template are pretty complex, and might freeze Hex Edit for a minute, so give it some time. Mainly the waza_p.bin.xml one, because its doing a lot of processing, and I'm not good at optimizing those things The SIR0 one is nearly instant on my computer though, on a file with a good amount of pointers offsets to parse. Of course, those are just research tools, and I'm still working on ppmd_statsutil and etc..
psy_commando Posted March 30, 2015 Author Posted March 30, 2015 So, after nearly a month of messing around, here's the first alpha release for ppmd_statsutil! https://github.com/PsyCommando/ppmdu/releases/download/ppmd_statsutil_0.1a/ppmd_statsutil_0_1.zip Its nothing all that great yet though, but I figured I might as well release something, and see if it helps figuring out the remaining details about the game data! Right now, it supports only exporting/importing Pokemon data, move data, and the game text. And it only works with Explorers of Sky this far, at least AFAIK(didn't test with the others yet). And only doing so one at a time! Don't try drag and drop on this one! It won't work. There's no way to figure out what you want from doing that! You have to specify at the command line whether you're importing or exporting with the "-i" or "-e" option. And then you must specify what you want to export/import using the "-pk" "-mv" or "-str" option, for respectively, pokemon data, move data, and game strings. Move data and Pokemon data are exported to XML, and the game strings are exported to a text file, where each line is a single string entry. All control characters are escaped using a backslash. For example \n is a newline, and \0 marks the end of the string. Other unprintable characters are represented using a decimal number after a backslash, instead of a character. To edit anything you'll need to have a reference for the move IDs and ability, type, movement ids and etc.. This is because while nearly all of those have strings associated, most of those values contain duplicate strings, which makes it unpractical and extremely error prone. Plus, the tool is mainly intended to be used by another more complete tool with a user interface that would handle this kind of things. Luckily, you can find references in a couple of places, namely the project pokemon wiki ! : http://projectpokemon.org/wiki/Pmd2_monster.md and the item_p_Sky.xlsx file over there !: http://apointlessplace.net/wms/research/ Here's bulbasaur's XML data as example : <?xml version="1.0"?> <Pokemon GameVersion="EoS"> <!--In-game text--> <Strings> <Name>Bulbasaur</Name> <Category>Seed</Category> </Strings> <!--Primary gender entity--> <GenderedEntity> <PokeID>1</PokeID> <Unk31>1</Unk31> <PokedexNumber>1</PokedexNumber> <Unk1>1</Unk1> <EvolutionReq> <PreEvoIndex>0</PreEvoIndex> <Method>0</Method> <Param1>0</Param1> <Param2>0</Param2> </EvolutionReq> <SpriteIndex>0</SpriteIndex> <Gender>1</Gender> <BodySize>1</BodySize> <PrimaryType>4</PrimaryType> <SecondaryType>8</SecondaryType> <MovementType>0</MovementType> <IQGroup>5</IQGroup> <PrimaryAbility>26</PrimaryAbility> <SecondaryAbility>0</SecondaryAbility> <Bitfield>0x70</Bitfield> <ExpYield>7</ExpYield> <RecruitRate1>82</RecruitRate1> <RecruitRate2>82</RecruitRate2> <BaseStats> <HP>22</HP> <Attack>3</Attack> <SpAttack>4</SpAttack> <Defense>2</Defense> <SpDefense>3</SpDefense> </BaseStats> <Weight>153</Weight> <Size>27</Size> <Unk17>0xa</Unk17> <Unk18>0xa</Unk18> <Unk19>0x1</Unk19> <Unk20>0x8</Unk20> <Unk21>0x64</Unk21> <BasePokemonIndex>1</BasePokemonIndex> <ExclusiveItems> <ItemID>574</ItemID> <ItemID>575</ItemID> <ItemID>576</ItemID> <ItemID>577</ItemID> </ExclusiveItems> <Unk27>0x2ee</Unk27> <Unk28>0x15</Unk28> <Unk29>0x1b</Unk29> <Unk30>0x1c</Unk30> </GenderedEntity> <!--Secondary gender entity--> <GenderedEntity> <PokeID>1</PokeID> <Unk31>1</Unk31> <PokedexNumber>1</PokedexNumber> <Unk1>1</Unk1> <EvolutionReq> <PreEvoIndex>0</PreEvoIndex> <Method>0</Method> <Param1>0</Param1> <Param2>0</Param2> </EvolutionReq> <SpriteIndex>0</SpriteIndex> <Gender>2</Gender> <BodySize>1</BodySize> <PrimaryType>4</PrimaryType> <SecondaryType>8</SecondaryType> <MovementType>0</MovementType> <IQGroup>5</IQGroup> <PrimaryAbility>26</PrimaryAbility> <SecondaryAbility>0</SecondaryAbility> <Bitfield>0x70</Bitfield> <ExpYield>7</ExpYield> <RecruitRate1>82</RecruitRate1> <RecruitRate2>82</RecruitRate2> <BaseStats> <HP>22</HP> <Attack>3</Attack> <SpAttack>4</SpAttack> <Defense>2</Defense> <SpDefense>3</SpDefense> </BaseStats> <Weight>153</Weight> <Size>27</Size> <Unk17>0xa</Unk17> <Unk18>0xa</Unk18> <Unk19>0x1</Unk19> <Unk20>0x8</Unk20> <Unk21>0x64</Unk21> <BasePokemonIndex>1</BasePokemonIndex> <ExclusiveItems> <ItemID>574</ItemID> <ItemID>575</ItemID> <ItemID>576</ItemID> <ItemID>577</ItemID> </ExclusiveItems> <Unk27>0x2ee</Unk27> <Unk28>0x15</Unk28> <Unk29>0x1b</Unk29> <Unk30>0x1c</Unk30> </GenderedEntity> <StatsGrowth> <!--Level 1--> <Level> <RequiredExp>0</RequiredExp> <HP>0</HP> <Attack>0</Attack> <SpAttack>0</SpAttack> <Defense>0</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 2--> <Level> <RequiredExp>9</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 3--> <Level> <RequiredExp>23</RequiredExp> <HP>2</HP> <Attack>1</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 4--> <Level> <RequiredExp>40</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 5--> <Level> <RequiredExp>88</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 6--> <Level> <RequiredExp>193</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 7--> <Level> <RequiredExp>300</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 8--> <Level> <RequiredExp>563</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 9--> <Level> <RequiredExp>1136</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 10--> <Level> <RequiredExp>1711</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 11--> <Level> <RequiredExp>2616</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 12--> <Level> <RequiredExp>4828</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 13--> <Level> <RequiredExp>7046</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 14--> <Level> <RequiredExp>10985</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 15--> <Level> <RequiredExp>14927</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 16--> <Level> <RequiredExp>19348</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 17--> <Level> <RequiredExp>23774</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 18--> <Level> <RequiredExp>28688</RequiredExp> <HP>3</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 19--> <Level> <RequiredExp>33607</RequiredExp> <HP>2</HP> <Attack>2</Attack> <SpAttack>2</SpAttack> <Defense>2</Defense> <SpDefense>2</SpDefense> </Level> <!--Level 20--> <Level> <RequiredExp>38528</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>2</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 21--> <Level> <RequiredExp>43488</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>2</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 22--> <Level> <RequiredExp>49233</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>2</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 23--> <Level> <RequiredExp>54983</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 24--> <Level> <RequiredExp>60739</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 25--> <Level> <RequiredExp>68068</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 26--> <Level> <RequiredExp>76985</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 27--> <Level> <RequiredExp>86688</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 28--> <Level> <RequiredExp>97176</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 29--> <Level> <RequiredExp>108451</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 30--> <Level> <RequiredExp>120511</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 31--> <Level> <RequiredExp>133358</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 32--> <Level> <RequiredExp>146991</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 33--> <Level> <RequiredExp>162993</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 34--> <Level> <RequiredExp>179782</RequiredExp> <HP>3</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 35--> <Level> <RequiredExp>197356</RequiredExp> <HP>2</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 36--> <Level> <RequiredExp>215717</RequiredExp> <HP>2</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 37--> <Level> <RequiredExp>234863</RequiredExp> <HP>2</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 38--> <Level> <RequiredExp>254795</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 39--> <Level> <RequiredExp>275513</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 40--> <Level> <RequiredExp>297017</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 41--> <Level> <RequiredExp>319308</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 42--> <Level> <RequiredExp>342385</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 43--> <Level> <RequiredExp>366247</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 44--> <Level> <RequiredExp>391681</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 45--> <Level> <RequiredExp>418687</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 46--> <Level> <RequiredExp>447265</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 47--> <Level> <RequiredExp>477415</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 48--> <Level> <RequiredExp>509138</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 49--> <Level> <RequiredExp>542432</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 50--> <Level> <RequiredExp>577298</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 51--> <Level> <RequiredExp>613736</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 52--> <Level> <RequiredExp>651746</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 53--> <Level> <RequiredExp>691054</RequiredExp> <HP>1</HP> <Attack>0</Attack> <SpAttack>1</SpAttack> <Defense>0</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 54--> <Level> <RequiredExp>730368</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 55--> <Level> <RequiredExp>769691</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 56--> <Level> <RequiredExp>809022</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 57--> <Level> <RequiredExp>848361</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 58--> <Level> <RequiredExp>887707</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 59--> <Level> <RequiredExp>927061</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>0</SpAttack> <Defense>1</Defense> <SpDefense>0</SpDefense> </Level> <!--Level 60--> <Level> <RequiredExp>966424</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 61--> <Level> <RequiredExp>1005793</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 62--> <Level> <RequiredExp>1045171</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 63--> <Level> <RequiredExp>1084557</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 64--> <Level> <RequiredExp>1123951</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 65--> <Level> <RequiredExp>1163352</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 66--> <Level> <RequiredExp>1202761</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 67--> <Level> <RequiredExp>1242179</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 68--> <Level> <RequiredExp>1281604</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 69--> <Level> <RequiredExp>1321036</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 70--> <Level> <RequiredExp>1360477</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 71--> <Level> <RequiredExp>1399926</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 72--> <Level> <RequiredExp>1439383</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 73--> <Level> <RequiredExp>1478847</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 74--> <Level> <RequiredExp>1518319</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 75--> <Level> <RequiredExp>1557799</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 76--> <Level> <RequiredExp>1597287</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 77--> <Level> <RequiredExp>1636783</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 78--> <Level> <RequiredExp>1676287</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 79--> <Level> <RequiredExp>1715798</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 80--> <Level> <RequiredExp>1755317</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 81--> <Level> <RequiredExp>1794845</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 82--> <Level> <RequiredExp>1834380</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 83--> <Level> <RequiredExp>1873922</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 84--> <Level> <RequiredExp>1913473</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 85--> <Level> <RequiredExp>1953032</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 86--> <Level> <RequiredExp>1992599</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 87--> <Level> <RequiredExp>2032173</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 88--> <Level> <RequiredExp>2071756</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 89--> <Level> <RequiredExp>2111345</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 90--> <Level> <RequiredExp>2150943</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 91--> <Level> <RequiredExp>2190549</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 92--> <Level> <RequiredExp>2230163</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 93--> <Level> <RequiredExp>2269785</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 94--> <Level> <RequiredExp>2309414</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 95--> <Level> <RequiredExp>2349052</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 96--> <Level> <RequiredExp>2388696</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 97--> <Level> <RequiredExp>2428349</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 98--> <Level> <RequiredExp>2468010</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 99--> <Level> <RequiredExp>2507679</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> <!--Level 100--> <Level> <RequiredExp>2547402</RequiredExp> <HP>1</HP> <Attack>1</Attack> <SpAttack>1</SpAttack> <Defense>1</Defense> <SpDefense>1</SpDefense> </Level> </StatsGrowth> <!--Moveset from waza_p.bin--> <Moveset> <!--Learns 14 move(s)--> <LevelUpMoves> <Learn> <Level>1</Level> <MoveID>154</MoveID> </Learn> <Learn> <Level>3</Level> <MoveID>217</MoveID> </Learn> <Learn> <Level>7</Level> <MoveID>329</MoveID> </Learn> <Learn> <Level>9</Level> <MoveID>182</MoveID> </Learn> <Learn> <Level>13</Level> <MoveID>199</MoveID> </Learn> <Learn> <Level>13</Level> <MoveID>231</MoveID> </Learn> <Learn> <Level>15</Level> <MoveID>203</MoveID> </Learn> <Learn> <Level>19</Level> <MoveID>251</MoveID> </Learn> <Learn> <Level>21</Level> <MoveID>10</MoveID> </Learn> <Learn> <Level>25</Level> <MoveID>148</MoveID> </Learn> <Learn> <Level>27</Level> <MoveID>140</MoveID> </Learn> <Learn> <Level>31</Level> <MoveID>504</MoveID> </Learn> <Learn> <Level>33</Level> <MoveID>94</MoveID> </Learn> <Learn> <Level>37</Level> <MoveID>486</MoveID> </Learn> </LevelUpMoves> <!--Has 12 egg move(s)--> <EggMoves> <MoveID>11</MoveID> <MoveID>84</MoveID> <MoveID>119</MoveID> <MoveID>134</MoveID> <MoveID>215</MoveID> <MoveID>233</MoveID> <MoveID>237</MoveID> <MoveID>253</MoveID> <MoveID>259</MoveID> <MoveID>297</MoveID> <MoveID>348</MoveID> <MoveID>537</MoveID> </EggMoves> <!--Can learn 30 HM/TM move(s)--> <HmTmMoves> <MoveID>18</MoveID> <MoveID>24</MoveID> <MoveID>29</MoveID> <MoveID>48</MoveID> <MoveID>50</MoveID> <MoveID>56</MoveID> <MoveID>67</MoveID> <MoveID>76</MoveID> <MoveID>104</MoveID> <MoveID>151</MoveID> <MoveID>163</MoveID> <MoveID>181</MoveID> <MoveID>197</MoveID> <MoveID>223</MoveID> <MoveID>227</MoveID> <MoveID>232</MoveID> <MoveID>263</MoveID> <MoveID>273</MoveID> <MoveID>280</MoveID> <MoveID>301</MoveID> <MoveID>304</MoveID> <MoveID>324</MoveID> <MoveID>326</MoveID> <MoveID>328</MoveID> <MoveID>360</MoveID> <MoveID>394</MoveID> <MoveID>443</MoveID> <MoveID>458</MoveID> <MoveID>471</MoveID> <MoveID>534</MoveID> </HmTmMoves> </Moveset> <!--Moveset from waza_p2.bin--> <Moveset> <!--Learns 14 move(s)--> <LevelUpMoves> <Learn> <Level>1</Level> <MoveID>154</MoveID> </Learn> <Learn> <Level>3</Level> <MoveID>217</MoveID> </Learn> <Learn> <Level>7</Level> <MoveID>329</MoveID> </Learn> <Learn> <Level>9</Level> <MoveID>182</MoveID> </Learn> <Learn> <Level>13</Level> <MoveID>199</MoveID> </Learn> <Learn> <Level>13</Level> <MoveID>231</MoveID> </Learn> <Learn> <Level>15</Level> <MoveID>203</MoveID> </Learn> <Learn> <Level>19</Level> <MoveID>251</MoveID> </Learn> <Learn> <Level>21</Level> <MoveID>10</MoveID> </Learn> <Learn> <Level>25</Level> <MoveID>148</MoveID> </Learn> <Learn> <Level>27</Level> <MoveID>140</MoveID> </Learn> <Learn> <Level>31</Level> <MoveID>504</MoveID> </Learn> <Learn> <Level>33</Level> <MoveID>94</MoveID> </Learn> <Learn> <Level>37</Level> <MoveID>486</MoveID> </Learn> </LevelUpMoves> <!--Has 12 egg move(s)--> <EggMoves> <MoveID>11</MoveID> <MoveID>84</MoveID> <MoveID>119</MoveID> <MoveID>134</MoveID> <MoveID>215</MoveID> <MoveID>233</MoveID> <MoveID>237</MoveID> <MoveID>253</MoveID> <MoveID>259</MoveID> <MoveID>297</MoveID> <MoveID>348</MoveID> <MoveID>537</MoveID> </EggMoves> <!--Can learn 30 HM/TM move(s)--> <HmTmMoves> <MoveID>18</MoveID> <MoveID>24</MoveID> <MoveID>29</MoveID> <MoveID>48</MoveID> <MoveID>50</MoveID> <MoveID>56</MoveID> <MoveID>67</MoveID> <MoveID>76</MoveID> <MoveID>104</MoveID> <MoveID>151</MoveID> <MoveID>163</MoveID> <MoveID>181</MoveID> <MoveID>197</MoveID> <MoveID>223</MoveID> <MoveID>227</MoveID> <MoveID>232</MoveID> <MoveID>263</MoveID> <MoveID>273</MoveID> <MoveID>280</MoveID> <MoveID>301</MoveID> <MoveID>304</MoveID> <MoveID>324</MoveID> <MoveID>326</MoveID> <MoveID>328</MoveID> <MoveID>360</MoveID> <MoveID>394</MoveID> <MoveID>443</MoveID> <MoveID>458</MoveID> <MoveID>471</MoveID> <MoveID>534</MoveID> </HmTmMoves> </Moveset> </Pokemon> And here's the XML data for the move Iron Tail as an example : <?xml version="1.0"?> <Move> <!--Pokemon Mystery Dungeon: Explorers of Sky move data--> <!--In-game text--> <Strings> <Name>Iron Tail</Name> <Description>"Basic Information"[CS:E][bAR][CR]\nInflicts damage on the target. It may\nalso reduce the target's [CS:E]Defense[CR] by\n1 level.\n\n\n\n\nDetailed Information:[CLUM_SET:108][M:B20]\n[C]\n"Detailed Information"[CS:E][bAR][CR]\nRange:[CLUM_SET:36] Enemy in front\nType:[CLUM_SET:36] Steel/Physical\nHit Ratio[CLUM_SET:54]:[CLUM_SET:62][move_hit_ratio]\nPower[CLUM_SET:54]:[CLUM_SET:62][move_power]\n\n\n\nBasic Information:[CLUM_SET:100][M:B20]</Description> </Strings> <!--Move data from waza_p.bin--> <Data> <BasePower>40</BasePower> <Type>17</Type> <Category>0</Category> <Unk4>0</Unk4> <Unk5>0</Unk5> <BasePP>10</BasePP> <Unk6>15</Unk6> <Unk7>125</Unk7> <Accuracy>78</Accuracy> <Unk9>75</Unk9> <Unk10>1</Unk10> <Unk11>99</Unk11> <Unk12>8</Unk12> <Unk13>0</Unk13> <Unk14>0</Unk14> <Unk15>0</Unk15> <Unk16>1</Unk16> <Unk17>1</Unk17> <Unk18>11</Unk18> <MoveID>1</MoveID> <Unk19>0</Unk19> </Data> <!--Move data from waza_p2.bin--> <Data> <BasePower>40</BasePower> <Type>17</Type> <Category>0</Category> <Unk4>0</Unk4> <Unk5>0</Unk5> <BasePP>10</BasePP> <Unk6>15</Unk6> <Unk7>125</Unk7> <Accuracy>78</Accuracy> <Unk9>75</Unk9> <Unk10>1</Unk10> <Unk11>99</Unk11> <Unk12>8</Unk12> <Unk13>0</Unk13> <Unk14>0</Unk14> <Unk15>0</Unk15> <Unk16>1</Unk16> <Unk17>1</Unk17> <Unk18>11</Unk18> <MoveID>1</MoveID> <Unk19>0</Unk19> </Data> </Move> Also, one of the more powerful feature of this tool is the "gamelang.xml" file. Its a very simple XML file that contains the name of the "text_*.str" file for all supported languages, along with a locale string associated with that language to allow parsing special charactersets, and a list of string indexes for move names, pokemon names and etc, within the the "text_*.str" file! This XML file can be edited by anyone and more languages can be added, along with the appropriate string indexes for all the relevant things in the game text! The gamelang.xml file included is very incomplete for now though, with only support for the English game! Here's the current entry for Explorers of Sky for example: <!--Begin List for Explorers of Sky--> <Game name="EoS"> <Language name="English" strfile="text_e.str" locale="en-US"> <StringBlock> <Name>Pokemon Names</Name> <Begin>8734</Begin> <End>9334</End> </StringBlock> <StringBlock> <Name>Pokemon Categories</Name> <Begin>9334</Begin> <End>9934</End> </StringBlock> <StringBlock> <Name>Move Names</Name> <Begin>8173</Begin> <End>8734</End> </StringBlock> <StringBlock> <Name>Move Descriptions</Name> <Begin>10145</Begin> <End>10704</End> </StringBlock> <StringBlock> <Name>Item Names</Name> <Begin>6773</Begin> <End>8173</End> </StringBlock> <StringBlock> <Name>Item Short Descriptions</Name> <Begin>12104</Begin> <End>13504</End> </StringBlock> <StringBlock> <Name>Item Long Descriptions</Name> <Begin>10704</Begin> <End>12104</End> </StringBlock> <StringBlock> <Name>Ability Names</Name> <Begin>13789</Begin> <End>13913</End> </StringBlock> <StringBlock> <Name>Ability Descriptions</Name> <Begin>13913</Begin> <End>14037</End> </StringBlock> <StringBlock> <Name>Type Names</Name> <Begin>13770</Begin> <End>13989</End> </StringBlock> </Language> I could probably add stuff for exporting small sections of the game text, like only abilities, or only pokemon, or types, etc, if anyone would have any use for that. If there are any feature requests, or any issues with the tool, let me know!
evandixon Posted March 30, 2015 Posted March 30, 2015 Have you determined the specific text encoding for the text_e.str? I thought it was shift jis, but a few characters don't re-encode right when I use it, like the arrows when shifting a move up or down.
psy_commando Posted March 30, 2015 Author Posted March 30, 2015 Well, from what I could find out, the "en-US" locale on Windows is basically ANSI codepage 1252. http://web.archive.org/web/20130813083656/http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx And that works pretty well from what I've seen this far! Also, all symbols that appears in the text are triggered by a tag that changes the font to use, so its possible you lost some characters while parsing the file, and those tags aren't read properly anymore ? Also, I wrote obscenities in the game and didn't have any issues XP EDIT: Also, wouldn't Shift-JIS be more appropriate for "text_j.str" ? Because, the name of the file changes based on the language and the encoding too.
kleenexfeu Posted March 30, 2015 Posted March 30, 2015 Hi, I've not read the whole thread but I want to say a big THANKS for you psy_commando and for all of those who contribuate to the research on PMD However I've barely download your ppmd_statutil and I have a problem when I try to run it. It simply open un close immediately, I don't know what to do to solve this Thank's in advance for your help, and thank's again for your research (un edited judgment attack hitting the whole floor is really awesome )
evandixon Posted March 30, 2015 Posted March 30, 2015 Hi, I've not read the whole thread but I want to say a big THANKS for you psy_commando and for all of those who contribuate to the research on PMD However I've barely download your ppmd_statutil and I have a problem when I try to run it. It simply open un close immediately, I don't know what to do to solve this Thank's in advance for your help, and thank's again for your research (un edited judgment attack hitting the whole floor is really awesome ) It's a command line tool, so drag an appropriate file onto the program.
kleenexfeu Posted March 30, 2015 Posted March 30, 2015 It doesn't work either A window appears for just 0,5 second and then disappears immediately EDIT : I've put the program directly in system32 to run it and see if there is some problem, but nothing particular appears, it just says "To export data, do... to import data, do..." and so on
evandixon Posted March 30, 2015 Posted March 30, 2015 It doesn't work either A window appears for just 0,5 second and then disappears immediately Try this: 1. Copy the appropriate file into the same folder as the program. 2. While holding shift, right click next to the program (make sure you're right-clicking the folder while inside of it). 3. Select "open command window here". 4. Type ppmd_statutil.exe "myfile.ext" (replacing myfile.ext with your file) 5. You should be presented with a message of success, or an error message (which can be used to investigate further).
psy_commando Posted March 30, 2015 Author Posted March 30, 2015 It's a command line tool, so drag an appropriate file onto the program. Well, that won't work with this one right now, you have to either make a shortcut or a batch file. Actually, I could even ship it with a few batch files that would handle the drag-and-drop.. There's an issue with the item data parser, so just dragging and dropping the game's data dir onto it will just end with an "not implemented" exception ^^; It should be fixed next release, but I figured it was good enough for testing Hi, I've not read the whole thread but I want to say a big THANKS for you psy_commando and for all of those who contribuate to the research on PMD However I've barely download your ppmd_statutil and I have a problem when I try to run it. It simply open un close immediately, I don't know what to do to solve this Thank's in advance for your help, and thank's again for your research (un edited judgment attack hitting the whole floor is really awesome ) You're welcome But, like evandixon said, its a command line utility, so you have to do extra work. Well, for now anyways. So, if you're using windows vista/7, go to the directory you're extracted the whole zip to, hold the shift key, right click on some empty space in the folder window, and click "Open command window here..". Then, the readme has a few pre-made lines for specific operations: ---------------------------------------------------------------------------------------------------- How to use: ---------------------------------------------------------------------------------------------------- Exporting: ---------- * Exporting Pokemon data to XML: Type this at the command line (without the first set of quotes): "ppmd_statsutil.exe -e -pk "path/To/PMD2/ROM/Data/Directory" "Path/To/Output/Directory"" Replace the paths with the appropriate paths! You can omit the output path, and the xml data will be exported to a default directory. * Exporting move data to XML: Type this at the command line (without the first set of quotes): "ppmd_statsutil.exe -e -mv "path/To/PMD2/ROM/Data/Directory" "Path/To/Output/Directory"" Replace the paths with the appropriate paths! You can omit the output path, and the xml data will be exported to a default directory. * Exporting game text to text file: Type this at the command line (without the first set of quotes): "ppmd_statsutil.exe -e -str "path/To/PMD2/ROM/DataDir" "Path/To/Output/File/text.txt"" Replace the paths with the appropriate paths! And replace the filenames as desired. You can omit the output path, and the text data will be exported to a text file with the default name. Importing: ---------- * Importing Pokemon data from XML back into the game: Enter this at the commandline (without the first set of quotes): "ppmd_statsutil.exe -i -pk "Path/To/Input/XMLdata/Directory" "path/To/Target/PMD2/ROM/Data/Directory"" Replace the paths with the appropriate paths! The output path is mandatory! * Importing moves data from XML back into the game: Enter this at the commandline (without the first set of quotes): "ppmd_statsutil.exe -i -mv "Path/To/Input/XMLdata/Directory" "path/To/Target/PMD2/ROM/Data/Directory"" Replace the paths with the appropriate paths! The output path is mandatory! * Importing game text from a text file back into the game: Enter this at the commandline (without the first set of quotes): "ppmd_statsutil.exe -i -str "Path/To/Input/File/text.txt" "path/To/PMD2/ROM/DataDir"" Replace the paths with the appropriate paths! The output path is mandatory! So if you want to export Pokemon data from the extracted ROM data located at "C:/directory/pmd2rom/data", you'd write this in the command prompt: ppmd_statsutil.exe -e -pk "C:/directory/pmd2rom/data" "-e" tells the program you want to export. "-pk" tells the program you want to operate on pokemon data. "C:/directory/pmd2rom/data" is the path to the extracted rom's data. The utility is mainly meant to be used by software devs to make their own more user friendly tools however. That's why its command line, because its way faster to develop and easier to use from any other GUI utility. I'm also going to make a very rudimentary GUI for this one too, pretty much the same thing as packfileutil and kaoutil, just to make it easier to handle for most people until more complete and user friendly tools are available. EDIT: Oh well, got ninja-ed
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now