unpackd
is a tool for the Pokémon Essentials, to extract data binaries (.rxdata
) to readable .rb
and .yaml
files and to combine them back, Thus making your game to be version-controlled and to be collaborated on.
$ unpackd.exe --help
Essentials Unpack\'d v3.0.0
`unpackd` is a tool \for Pokémon Essentials, to extract data binaries (.rxdata)
to readable .rb and .yaml files and to combine them back, thus making
your game to be version-controlled and to be collaborated on.
Usage:
unpackd.exe [options] {--extract|--combine|-b|-r}
Commands:
-e, --extract Extract given binaries(.rxdata) into individual .yaml/.rb
-c, --combine Combine given .yaml/.rb files into binaries(.rxdata)
-b, --backup Make Backup for given binary(.rxdata) files
-r, --revert Revert given binary(.rxdata) from Backup Folder
Options:
-d, --project=<s> Essentials project path. (default: Current Folder)
-f, --files=<s+> File Names for .rxdata/.yaml/.rb to operate on. (Default: *)
-F, --force Used with `--combine` to Pack Data Forcefully
-s, --silent Do not output any information while processing
-v, --version Print version and exit
-h, --help Show this message
- To Extract
Scripts.rxdata
andTilesets.rxdata
of a game in "D:\Examples\MyEssentialsGame":
$ unpackd.exe --extract --project "D:\Examples\MyEssentialsGame" --files scripts tilesets
This will create 3 Folders,
Backup
,Scripts
, andYAML
in the "D:\Examples\MyEssentialsGame\Data" folder.
- Firstly, Backup files will be created in
Data\Backup
(*.rxdata.backup
files)Scripts.rxdata
consists of many ruby scripts and these now will be extracted to individual.rb
files placed in grouped folders within theData\Scripts
folder.Scripts.rxdata
will be replaced with a loader file, this file can read the individual.rb
files in theData\Scripts
Folder, Therefore making Game.exe still playable! This would not work, if the game is encrypted !Tilesets.rxdata
will be extracted to a readableTilesets.yaml
file withinData\YAML
folder.- If at any point, unpackd is unable to perform the extraction, mentioned Backup files will be reinstated.
- To Combine { ruby scripts in
Data/Scripts
toScripts.rxdata
} and {Tilesets.yaml
toTilesets.rxdata
}:
$ unpackd.exe --combine --project "D:\Examples\MyEssentialsGame" --files scripts tilesets
This will create 3 Folders,
Backup
,Scripts
, andYAML
in the "D:\Examples\MyEssentialsGame\Data" folder.
- Firstly, Backup files will be created in
Data\Backup
(*.rxdata.backup
files)- Will check if the
Scripts.rxdata
is a loader file or an already data-packed file.
- If in case, it is already a packed data file, this operation will skip, unless
--force
flag is passed along.- Else, ruby scripts will be reintegrated back into
Scripts.rxdata
Tilesets.yaml
will be converted back toTilesets.rxdata
.- If at any point, the script is unable to perform a combination, mentioned Backup files will be reinstated.
- To create a general Backup for
Scripts.rxdata
andTilesets.rxdata
:
$ unpackd.exe --backup --project "D:\Examples\MyEssentialsGame" --files scripts tilesets
- To Revert an already created backup of
Scripts.rxdata
andTilesets.rxdata
:
$ unpackd.exe --revert --project "D:\Examples\MyEssentialsGame" --files scripts tilesets
-
Put
unpackd.exe
in the game directory, it is a light file and it removes the need to pass the--project
flag -
Currently, only
Tilesets
andScripts
are understandable, I am not sure about the rest of the files. -
To add
YAML
in your version control add!Data/YAML/
to.gitignore
.-
$ echo !Data/YAML/ >> .gitignore
-
-
Extracted
Scripts.rxdata
cannot be loaded into RPG Maker, even with the loader file, always combine it, if you plan on using the script editor of RPG Maker. -
Using
---files
flag again and again for the same files, can be a bit effortful, create a batch file or makefile for your workflow, I have added a makefile.template in the repo, as a base to add on. -
Suppose your game throws an error, but you couldn't note it down. You try to run the game again, but now
Game.exe
just shows a blank screen and it exits. This happens due to caching of binary files, Now, I don't know how to delete/ignore those cache but, I know, by--combine --force
again (or by--combine
then--extract
, if you are working with loader),Game.exe
assumes it is a new binary. (Warn: This would corrupt backup) -
In Case, you don't use a VCS (big mistake), be aware of backups! Suppose you made changes to a file, and combined it to run the game and it did not work (right now the file is bad but the backup is good). but if you make another change and combined forcefully, even if the file is good, the backup becomes bad!
Essentials Unpack'd is quite different from original files and libs, but Authors must be credited for the grand majority of the work that unpackd
do, without them this would have not been possible.
- Howard "SiCrane" Jeng for original YAML importer/exporter; serialization, data conversion.
- Aaron Patterson for
psych 2.0.0
bug fixes. - Andrew Kesterson for converting a simple forum post to a working version-controlled ruby gem!
- Rachel Wall for code optimization and maintenance since 2014.
- Maruno for all processes regarding
Scripts.rxdata
, extract, combine, and loader.
$ git clone https://github.com/ra101/Essentials-Unpackd.git
$ cd Essentials-Unpackd
$ gem install bundler
$ bundle install
$ bundle exec unpackd {--extract|--combine|-b|-r} [options]
unpackd
consists of following parts:
rgss.rb
: Stub classes for serialization of RPG Maker game dataserialize.rb
: core mechanice behind data processingpsych.rb
: Overriding Psych lib to make output more readableunpackd
: The script you call on the frontend.
One thing that unpackd
really can't help you with right now (and, ironically, probably one of the reasons you want it) is map collisions. Consider this situation:
- The project has 10 maps in it, total.
- Developer A makes a new map; it gets saved by the editor as 'Map011'.
- Developer B makes a new map, in a different branch; it also gets saved by the editor as 'Map011'.
- Developer A and Developer B attempt to merge their changes -- the merge fails because of the collision on the 'Map011' file.
The best way to avoid this is to use blocks of pre-allocated maps. You appoint one person in your project to be principally responsible for the map assets; it then becomes this person's responsibility to allocate maps in "blocks" so that people can work on maps in a distributed way without clobbering one another. The workflow looks like this:
- The project has 10 maps in it, total.
- Developer A needs to make 4 maps. He sends a request to the "map owner", requesting a block of 4 maps.
- The map owner creates 4 default, blank maps, and names them all "Request #12345" for Developer A
- Developer A starts working on his maps
- Developer B needs to make 6 maps. He sends a request to the "map owner", requesting a block of 6 maps.
- The map owner creates 6 default, blank maps, and names them all "Request #12346" for Developer B
- Developer B starts working on his maps
Using this workflow, it doesn't matter what order Developers A and B request their map blocks in or what order the map owner creates their map blocks in. By giving the map owner the authority to create the map blocks, individual developers can work freely in their map blocks: they can rename them, reorder them, change all of the map attributes (size, tileset, and so on), without getting in danger of a map collision.
While this may seem like an unnecessary process, it is a reasonable workaround. For a better explanation of why unpackd
can't do this for you, read the next section.
You can add new elements to the YAML files manually, and leave their id:
field set to null
. This will cause the unpackd
pack action to automatically assign them a new ID number at the end of the sequence (e.g., if you have 17 items, the new one becomes ID 18). This is mainly handy for adding new scripts to the project without having to open the RPG Maker editor and paste the script in; just make the new script file, add its entry in YAML/Scripts.yaml, and the designer will have your script accessible the next time they repack and open the project.
Also, the unpackd
tool sets the ID of script files to an autoincrementing integer. The scripts exist in the database with a magic number that I can't recreate, and nothing in the editor (RPG VX Ace anyway) seems to care if the magic number changes. It doesn't even affect the ordering. So in order to support adding new scripts with null IDs, like everything else, the magic numbers on scripts are disregarded and a new ID number is forced on the scripts when the unpackd
pack
action occurs.
Note that this does not apply to map files; do not try changing the map ID numbers manually (see the "Avoiding Map Collisions" workflow, above, and "Why unpackd can't help with map collisions", below).
If you look at the map collision problem described above, the way out of this situation might seem obvious: "Rename Map011.yaml in one of the branches to Map012.yaml, and problem solved." However, there are several significant problems with this approach:
- The ID numbers on the map files correspond to ID number entries in MapInfos.yaml (and the corresponding MapInfos binary files)
- The ID numbers are used to specify a parent/child relationship between one or more maps
- The ID numbers are used to specify the target of a map transition/warp event in event scripting
This means that changing the ID number assigned to a map (and, thereby, making it possible to merge 2 maps with the same ID number) becomes very nontrivial. The event scripting portion, especially, presents a difficult problem for unpackd
to overcome. It is simple enough for unpackd
to change the IDs of any new map created, and to change the reference to that ID number from any child maps; however, the events are where it gets sticky. The format of event calls in RPG Maker map files is not terribly well defined, and even if it was, I sincerely doubt that you want unpackd
tearing around in the guts of your map events.
From SiCrane:
I used cygwin's ruby 1.9.3 and the Psych 2.0.0 ruby gem, which appears to be the most recent version. However, Psych 2.0.0 has some bugs that impacted the generated YAML (one major and one minor) which I monkey patched, and since I was already rewriting the Psych code, I added some functionality to make the generated YAML prettier. Long story short, this code probably won't work with any version of Psych but 2.0.0.