fs-assets
Tools for Foxhole game assets, written in Rust
with Python bindings. It reads the game's .pak directly (no external
extraction or conversion tools) to:
- build the item catalog: every item, vehicle and structure that can be stored in a stockpile, with names in every game language, faction, icons and whether it can be crated;
- build the icon-template database (HDF5) used to recognise stockpile icons in screenshots, for the base game and for icon mods;
- dump and re-pack
.locrestranslations and package them as a mod.pak.
It ships as a Python package (fs_assets) and a standalone command-line tool
(fs-assets) with the same operations.
Installation
pip install fs-assets
Wheels are published for Linux (x86_64), Windows (x64) and macOS (arm64) with
HDF5 statically linked, so nothing else needs to be installed. A standalone
fs-assets binary for each platform is attached to every
GitHub release.
Command line
The game pak is usually at
<Steam>/steamapps/common/Foxhole/War/Content/Paks/War-WindowsNoEditor.pak.
# Item catalog straight from the game pak
fs-assets build-catalog --pak War-WindowsNoEditor.pak -o catalog.json
# Icon-template database for the base game
fs-assets add-mod --pak War-WindowsNoEditor.pak --catalog catalog.json --db templates.h5
# Check an icon mod, then add it under its own name. Mods that don't ship the
# subtype/crate overlays borrow them from the game pak.
fs-assets check-paks --catalog catalog.json --pak IconMod.pak
fs-assets add-mod --pak IconMod.pak --vanilla-pak War-WindowsNoEditor.pak \
--catalog catalog.json --db templates.h5 --mod-name icon-mod
# Replace one icon at two resolutions from a PNG
fs-assets modify-icon --db templates.h5 --code RifleW --faction wardens \
--category item --icon rifle.png --resolution 1080,1440 --replace
| Command | What it does |
|---|---|
unpak |
Extract files from a .pak (optionally only paths containing --include). |
convert |
Convert one .uasset to JSON or PNG. |
build-catalog |
Build the catalog from the game pak or an extracted directory. --full keeps audio, visual and engine-internal fields. |
add-mod |
Add a mod's (or the base game's) icons to the template database. Re-adding a mod replaces its templates. --pak can be repeated (later paks win); --resolution rebuilds only some resolutions. |
check-paks |
Report how many of the catalog's icons and overlays some paks contain, reading only the pak indexes. |
modify-icon |
Add, replace (--replace) or remove (--remove) a single template from a PNG or .uasset. |
locres-dump / locres-pack |
Convert a .locres to editable JSON and back. |
pack |
Pack a directory into a mod .pak. |
grep-strings |
Find text baked into .uasset/.uexp files instead of a .locres. |
Run fs-assets <command> --help for every option.
Translation workflow
fs-assets unpak War-WindowsNoEditor.pak --include Localization -o game
fs-assets locres-dump game/War/Content/Localization/Foxhole-Content/pt/Foxhole-Content.locres \
--reference game/War/Content/Localization/Foxhole-Content/en/Foxhole-Content.locres \
-o pt.json
# edit the "text" fields of pt.json
mkdir -p mod/War/Content/Localization/Foxhole-Content/pt
fs-assets locres-pack pt.json -o mod/War/Content/Localization/Foxhole-Content/pt/Foxhole-Content.locres
fs-assets pack mod -o Translation.pak
--reference uses the English file, which contains every key, so keys missing
from the target language appear in the JSON with the English text to
translate. Hashes are carried over unchanged.
Python
import fs_assets
stats = fs_assets.build_catalog(pak="War-WindowsNoEditor.pak", output="catalog.json")
fs_assets.add_mod(
pak=["IconMod_1.pak", "IconMod_2.pak"],
vanilla_pak="War-WindowsNoEditor.pak",
catalog="catalog.json",
db="templates.h5",
mod_name="icon-mod",
progress=lambda stage, done, total: print(stage, done, total),
)
coverage = fs_assets.pak_coverage(catalog="catalog.json", pak="IconMod.pak")
for template in fs_assets.read_templates("templates.h5", 1080):
print(template["code"], template["mod_name"], template["crated"])
print(fs_assets.database_statistics("templates.h5"))
Long operations release the GIL and accept a progress(stage, done, total)
callable, so they can run in a GUI worker thread. The package is fully typed;
the shapes of the returned dictionaries are in fs_assets.types.
Development
Requires a Rust toolchain and, for local builds, the system HDF5 library
(libhdf5-dev on Debian/Ubuntu).
cargo test # unit tests
cargo clippy --features python --all-targets -- -D warnings
cargo fmt --check
pip install maturin
maturin develop --release # build and install the Python package
pytest tests/python
Build with --features static-hdf5 to compile HDF5 from source and link it
statically (needs CMake and a C compiler), as the release workflow does.
Some tests need real game assets in tests/fixtures/. Those files are not
distributable, so the tests are ignored by default; with the fixtures in place,
run them with cargo test -- --ignored.
Releases are published by pushing a vX.Y.Z tag that matches the version in
Cargo.toml.
License
MIT. Foxhole is a trademark of Siege Camp; this project is not affiliated with or endorsed by Siege Camp.
Metadata
Release files for fs-assets 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| fs_assets-0.1.0.tar.gz | 158.6 kB | With provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fs_assets-0.1.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| fs_assets-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| fs_assets-0.1.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 11.9 MB
Release files / fs_assets-0.1.0.tar.gz
| Download URL | fs_assets-0.1.0.tar.gz |
|---|---|
| Size | 158.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ad8f0c587e4f10c23af93bd2d47c92e97c3cc9b0385c7cb8eeed535dad44a36f
|
|
BLAKE2b-256 checksum How to use checksums |
f7f190608d7b9e711fa08098f8672f5108b75aae6bf7f25f57431729400a0588
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / fs_assets-0.1.0-cp310-abi3-win_amd64.whl
| Download URL | fs_assets-0.1.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0695afd79d26ce518fc0c36fa76028cf20865916df6c194b8b0eb2cdff2f9f1f
|
|
BLAKE2b-256 checksum How to use checksums |
77fd5a03dc5f4949e49461ed26dc1a3bd1ca912993daa0e6b39d273d81d1835c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / fs_assets-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | fs_assets-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 3.8 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8c1b36137cfe6279266fd9e79dfe32892ec67a89d1ab4b22b617106b486ab9b7
|
|
BLAKE2b-256 checksum How to use checksums |
2adf08271ce8f22338b3e63f573b84e03be8139db0ec02f0d780d71fbd24dcfb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / fs_assets-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | fs_assets-0.1.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
85f581f32088a62b35a550308f3fd6c3668f1e752f67a1e84f46d0aef9c2a52f
|
|
BLAKE2b-256 checksum How to use checksums |
70e4285812296e56ac4f8309fdd3490a7623e28a80159b86211c938899de4ff7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logSecurity for fs-assets 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 4 files in this release have been uploaded with provenance metadata.
Attestation for fs_assets-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.