Skip to content

Common-Leap/EffectLibraryRust

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EffectLibraryRust

Rust library and CLI for loading and saving Nintendo Switch VFX effect files (.eff, .ptcl). Decompiles .eff archives into editable JSON/text assets and re-encodes them with byte-for-byte parity against the reference C# exporter.

Crates.io: effect_library 1.1.0

Build

From the repo root:

cargo build --release --bin effect_converter

The binary is written to target/release/effect_converter.

CLI usage

Decompile an effect archive to a folder:

./target/release/effect_converter dump /path/to/ef_mario.eff /path/to/output

Recompile a decompiled folder back to .eff:

./target/release/effect_converter build /path/to/output/ef_mario /path/to/ef_mario_NEW.eff

Or install the effect_library crate from crates.io (binary name: effect_converter):

cargo install effect_library
effect_converter dump /path/to/ef_mario.eff /path/to/output
effect_converter build /path/to/output/ef_mario /path/to/ef_mario_NEW.eff

Header-only effects (no Base.ptcl) skip build, matching C# behavior.

Using as a Rust crate

Add a dependency from crates.io:

[dependencies]
effect_library = "1.1.0"

Or use a path/git checkout when working on this repo:

[dependencies]
effect_library = { path = "crate" }
# effect_library = { git = "https://github.com/Common-Leap/EffectLibraryRust" }

Load and dump an .eff file

use effect_library::{Dumper, NamcoEffectFile};
use std::fs;

let data = fs::read("ef_mario.eff")?;
let namco = NamcoEffectFile::load(&data)?;

Dumper::dump_namco(&namco, "output/ef_mario")?;

Rebuild from a decompiled folder

use effect_library::Creator;
use std::fs;

let namco = Creator::create_namco_from_folder("output/ef_mario")?
    .expect("effect has Base.ptcl");
fs::write("ef_mario_NEW.eff", namco.save()?)?;

Creator::create_ptcl_from_folder rebuilds only the embedded PTCL when you do not need the EFFN wrapper.

Work with PTCL directly

use effect_library::PtclFile;
use std::fs;

let bytes = fs::read("Base.ptcl")?;
let ptcl = PtclFile::load(&bytes)?;
let roundtrip = ptcl.save();

Export embedded BFRES / BNTX / BNSH assets

use effect_library::bfres::{export_single_model, ResFile};
use effect_library::bntx;
use effect_library::bnsh;

let source = namco.ptcl_file.as_ref().unwrap()
    .primitive_info.as_ref().unwrap()
    .binary_data.as_ref().unwrap();
let bfres_bytes = export_single_model(source, model_index)?;
let normalized = ResFile::canonicalize(&bfres_bytes)?;
let reordered = bntx::reorder_and_save(&bntx_bytes, &texture_names)?;
let bnsh_bytes = bnsh::canonicalize(&shader_bytes)?;

Verification

Scripts under crate/scripts/ download/build reference tools and locate local game .eff files automatically. Game assets are not redistributable; setup symlinks References/effect/ from a known export path or $EFFECT_REFERENCE_PATH.

cd crate
python3 scripts/compare_setup.py --all          # optional: prefetch tools + effect symlink
python3 scripts/batch_eff_roundtrip.py          # C# dump → C# vs Rust rebuild (328 effects)
python3 scripts/batch_eff_compare.py            # C# vs local dump accuracy
python3 scripts/compare_published_vs_optimized.py  # crates.io 1.0.0 vs local
python3 scripts/speedtest_csharp_rust.py        # dump-only timing
python3 scripts/speedtest_roundtrip.py --csharp # dump + build timing

Temp output goes under References/tmp/ and is removed when each script finishes.

Integration tests in creator.rs optionally use folders under /tmp/ when present; they skip otherwise.

Credits

Publishing (maintainers)

From the repo root, after cargo login:

cargo publish -p effect_library

About

A Rust Library which replicates EffectLibrary's eff decompile and compile functions. Also much faster (vroom).

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Rust 90.0%
  • Python 10.0%