Multipass compiler/decompiler suite for touhou binary script files.
truth stands for "touhou rust thing".  Or maybe it stands for "touhou rust thtk". I dunno, I mostly just picked it because trustd and truecl sound pretty dope.
Tools provided:
trustdfor.stdfilestruanmfor.anmfilestrumsgfor most msg filestrumsg --missionformission.msg
Supports all danmaku titles TH06–TH185. That is:
TH06 (EoSD), TH07 (PCB), TH08 (IN), TH09 (PoFV), TH09.5 (StB), TH10 (MoF), TH11 (SA), TH12 (UFO), TH12.3 (GFW), TH12.5 (DS), TH13 (TD), TH14 (DDC), TH14.3 (ISC), TH15 (LoLK), TH16 (HSiFS), TH16.5 (VD), TH17 (WBaWC), TH18 (UM), TH18.5 (BM)
Uwabami Breakers is also supported (use
-g alcostgor-g 103)
Get the latest Windows releases right here on GitHub!
Development builds may also be posted occationally on the #tools-dev channel on the ZUNcode discord server.
For even more bleeding edge, see Building from source below.
See these doc pages:
- A primer on script syntax.
 - A comparison to thtk.
 
Usage of trustd is pretty straightforward, so we'll take this opportunity to describe some features common to all of the tools.
Here's how you primarily use it:
trustd decompile -g13 -m map/any.stdm in.std -o out.stdspec
trustd compile -g13 in.stdspec -o out.stdThe subcommands can be abbreviated to any unambiguous prefix, e.g. trustd decomp or even trustd d.
Similar to thtk, the -m flag imports an ECLMAP-style file. Generally speaking this is only needed during decompilation, because when you are compiling a script, it can contain a reference to its own mapfile:
#pragma mapfile "./map/any.anmm"If you frequently decompile files for experimental purposes, you can also set the environment variable TRUTH_MAP_PATH to automatically locate mapfiles during decompilation.  Each directory listed in this PATH-like variable will be checked for a file named any.stdm if you are compiling STD, any.anmm if you are compiling ANM, and etc.
You can decompile an ANM file into a script, similar to thanm -l.
truanm decompile -g12 -m map/any.anmm in.anm -o out.specANM files also contain images.  You can extract these using truanm extract:
truanm extract -g12 in.anm -o images/
# shorthand
truanm x -g12 in.anm -o images/At this time, image extraction is not thoroughly tested and may have some bugs.
ANM scripts contain entry blocks that each declare an image contained in the ANM file.
// there are other fields, but most will use reasonable defaults
entry {
    path: "subdir/image.png",
    scripts: {
        sprite0: {id: 0, x: 0.0, y: 0.0, w: 50.0, h: 50.0},
    },
}To compile an ANM file, you will likely need to supply some source of these images. There are two types of image sources: ANM files and image directories.
If you are recompiling a script obtained from an ANM file, the original ANM file will serve as a suitable image source, which can be provided through the -i/--image-source flag:
truanm compile -g12 edited.spec -i original.anm -o out.anmWhen using an ANM file as an image source, each entry in the current script will pull the image from the entry with the same filepath inside the image source.  This mechanism can also be used to copy over any missing metadata from an entry.  In cases where multiple entries have the same path (which can happen for virtual files like "@" and "@R"), the duplicates are matched in order of appearance.
If you have a thcrap patch or a directory containing the output of truanm extract, that can also be used as an image source:
truanm compile -g12 cool.spec -i path/to/images -o out.anmIn this case, the example entry above (with the path "subdir/image.png") would try to load path/to/images/subdir/image.png if it exists.  As long as an image can be found, all fields on an entry will be automatically filled with reasonable defaults.
You can supply multiple image sources! For instance, if you are recompiling an ANM file and adding additional images (or replacing some of the images), you could supply:
truanm compile -g12 edited.spec -i original.anm -i my/extra/images -o out.anm
The ordering of the image sources is important when replacing images; here, -i my/extra/images appears last, so it takes top priority when multiple image sources define the same image.
Note that, similar to mapfiles, image sources can alternatively be defined inside the script using #pragma image_source:
// equivalent to prepending '-i original.anm -i my/extra/images' to argument list
#pragma image_source "original.anm"
#pragma image_source "my/extra/images"If you're using thcrap and something bothers you about the fact that both your ANM file and your thcrap patch contain copies of the same images, you can put has_data: "dummy" on an entry (the default is has_data: true).  This will cause it to generate magenta dummy data in the ANM file, to be hot-swapped out by thcrap.  Note that such an entry can still automatically grab the image dimensions from an image source.
MSG files are nothing special; just follow the same instructions for STD files, but using trumsg.
Well. Some MSG files are special:
mission.msgin TH095 and TH125 is a completely different format from other MSG files. To work with it you must supply the--missionflag.- Ending (e.g. 
e01.msg) and Staff Roll (e.g.staff1.msg) files use a different instruction set. It is possible to work with them but you'll need to create a special mapfile. Ping me on Discord and I'll see if I can throw one together. 
Install rust, and then:
git clone https://github.com/ExpHP/truth
cd truth
# Debug builds  (for optimized builds, change it to `cargo run --release`)
cargo run -- trustd d -g10 -m map/any.stdm in.std -o out.stdspec
cargo run -- trustd c -g10 out.stdspec -o out.std
# If you want optimized binaries installed globally:
cargo install --path=.Important: Notice that development builds use cargo run -- trustd instead of cargo run --bin=trustd.  This is because most binaries in this project are actually shims around the main binary (truth-core), and if you do --bin=trustd then that main binary won't be rebuilt.
