FiveFury
FiveFury is a Python library for reading, writing, and packaging GTA V asset files: drawables, collisions, map metadata, animations, navigation data, texture dictionaries, text tables, audio containers, cutscenes, DLC metadata, and RPF archives.
It targets practical modding workflows — declarative high-level helpers for common authoring tasks, with access to the underlying binary and resource layers when you need them. Heavy operations (vertex packing, collision generation, hashing, crypto, resource layout, archive scanning) run in a bundled native extension.
Installation
pip install fivefury
Python 3.11+ is required.
The Assimp-backed import helpers (assimp_to_ydr, obj_to_ydr, fbx_to_ydr, obj_to_nav) additionally require the impasse package and a native assimp library reachable through the environment (usually via PATH).
Format support
| Format | Status | Scope |
|---|---|---|
YDR |
Full | Drawables: models, LODs, materials, shaders, lights, embedded textures and bounds, skeletons, skinning |
CDR |
Read | PS3 drawables: materials, LODs, QB/EDGE geometry, compressed indices, skeletons and skinning |
YDD |
Full | Drawable dictionaries, creation from named drawables, ped-component rigging helpers |
YBN |
Full | Primitive, composite, geometry, and BVH bounds; collision generation from triangle meshes |
YCD |
Full | Clip dictionaries: skeletal, object, UV, camera, and root-motion tracks |
YMAP |
Full | Entities, car generators, occluders, timecycle modifiers, LOD/distant lights |
YTYP |
Full | Base/time/MLO archetypes, extensions, rooms, portals, entity sets |
YMF |
Full | Map manifests, IMAP/ITYP dependencies, generation from YMAP sets |
YTD |
Full | Texture dictionaries: read/write, extraction, embedded-asset helpers |
YND |
Full | Path nodes, links, area partitioning, junction heightmaps |
YNV |
Full | Navmeshes: sectors, polys, portals, validation, basic OBJ partitioning |
heightmap.dat |
Full | World-height grids, native quantization, row RLE, water masks, spatial queries |
water.xml |
Full | Water surfaces, triangle corners, calming regions, wave amplitude and direction |
CUT |
Full | Cutscenes, plus the readable .cuts script format for round-trip authoring |
GXT2 |
Full | Hashed text tables with binary read/write and text import/export |
AWC |
Full | Audio containers: PCM/WAV extraction, authoring from WAV/MP3/OGG/FLAC |
RPF |
Full | RPF7 archives: nested archives, folder/ZIP conversion, encrypted archive reading |
| DLC metadata | Full | setup2.xml, content.xml, dlclist.xml, title-update patch overlays |
GTXD |
Full | Parent texture dictionary metadata (XML and binary RBF) |
YFT |
Partial | Fragment read/write: drawables, physics LODs/groups/children, composite bounds |
REL |
Partial | Audio metadata banks; typed models for synths, curves, categories, and common sound graphs |
YED |
Partial | Expression dictionaries: inspection, spring editing, small dictionaries from scratch |
YMT |
Partial | META/PSO/RBF read/write with typed helpers for known roots; unknown payloads preserved |
YPT |
Partial | Embedded texture dictionary discovery/extraction only |
YWR, YVR |
Indexed | Detected by GameFileCache and RPF tooling; no dedicated parser yet |
YFD, YPDB, MRF |
— | Not implemented |
YDR and CDR expose the same format-neutral drawable interface for LODs, models, meshes, materials, parameters, textures, and shader metadata. Their binary layouts remain isolated: PC/Enhanced authoring stays in ydr, while PS3 resource pages, QB/EDGE geometry, and console shader additions stay in cdr.
Quick start
Create a YMAP and pack it into an RPF
from fivefury import Ymap, create_rpf
ymap = Ymap(name="example_map")
ymap.entity("prop_tree_pine_01", position=(100, 200, 0), lod_dist=150.0)
ymap.car_gen("sultan", (110, 205, 0), heading=90)
ymap.save("example_map.ymap", auto_extents=True)
archive = create_rpf("mods.rpf")
archive.add("stream/example_map.ymap", ymap)
archive.save("mods.rpf")
Build a drawable
from fivefury import YdrMeshInput, create_ydr
ydr = create_ydr(
meshes=[
YdrMeshInput(
positions=[(0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)],
indices=[0, 1, 2],
texcoords=[[(0.0, 0.0), (1.0, 0.0), (0.0, 1.0)]],
)
],
material_textures={"DiffuseSampler": "example_diffuse"},
name="example_drawable",
)
ydr.save("example_drawable.ydr")
Existing drawables can be read with read_ydr(...), then edited through update_material(...), add_embedded_texture(...), set_bound(...), skeleton and skinning helpers, and saved back. assimp_to_ydr(...) imports any mesh format Assimp can read.
Generate collision
from fivefury import BoundMaterial, BoundMaterialType, build_bound_from_triangles, save_ybn
triangles = [
((0.0, 0.0, 0.0), (4.0, 0.0, 0.0), (0.0, 4.0, 0.0)),
((4.0, 0.0, 0.0), (4.0, 4.0, 0.0), (0.0, 4.0, 0.0)),
]
bound = build_bound_from_triangles(
triangles,
material=BoundMaterial(type=BoundMaterialType.CONCRETE),
)
save_ybn(bound, "floor_collision.ybn")
Generated geometry is chunked as needed and gets BVH and octant data. The same bounds model backs standalone YBN files, embedded YDR collisions, and YFT physics — a drawable's render mesh can also be converted directly with ydr.ensure_bound_from_render_geometry().
Author water
from fivefury import WaterData, WaterQuad, WaterWaveQuad
water = WaterData()
water.add(
WaterQuad.rectangle(
center=(100.0, 200.0, 12.5),
size=(80.0, 40.0),
alpha=26,
limited_depth=True,
)
)
water.add(
WaterWaveQuad.from_angle(
bounds=(60, 180, 140, 220),
amplitude=1.2,
degrees=90.0,
)
)
water.translate(x=500, y=-200, z=20.0).save("water.xml")
Author a world height map
from fivefury import HeightMap, HeightMapBounds
heightmap = HeightMap.empty(
columns=10,
rows=10,
bounds=HeightMapBounds(0.0, 0.0, 0.0, 500.0, 500.0, 800.0),
)
heightmap.set_height(4, 6, minimum=32.0, maximum=78.0)
heightmap.set_water(4, 6)
heightmap.save("heightmap.dat")
Convert audio to AWC
from fivefury import convert_audio_to_awc
convert_audio_to_awc("music/song.flac", "stream/song.awc", channels=2)
Work with RPF archives
from fivefury import RpfArchive, RpfExportMode, rpf_to_zip, zip_to_rpf
zip_to_rpf("unpacked_mod_folder", "packed_mod.rpf")
rpf_to_zip("packed_mod.rpf", "packed_mod.zip", mode=RpfExportMode.STANDALONE)
with RpfArchive.from_path("packed_mod.rpf") as archive:
archive.to_folder("out", mode=RpfExportMode.STANDALONE)
Encrypted standalone archives open directly; FiveFury initializes the bundled crypto context automatically. Export modes: STORED (raw bytes), STANDALONE (valid standalone files with RSC7 containers), LOGICAL (inner payloads).
Index a game installation
from fivefury import GameFileCache
cache = GameFileCache(r"C:\Program Files (x86)\Steam\steamapps\common\Grand Theft Auto V")
cache.scan_game(use_index_cache=True)
asset = cache.get_asset("prop_tree_pine_01", kind=".ydr")
cache.extract_asset(asset, "prop_tree_pine_01.ydr")
cache.extract_asset_textures("prop_tree_pine_01.ydr", "textures")
GameFileCache indexes loose files and archives, loads supported formats lazily, exposes typed lookups by name/hash/kind, resolves textures through YTD, GTXD parent chains, and embedded dictionaries, and can generate YMF manifests for custom maps. Scan scope is configurable (dlc_level, exclude_folders, load_audio, load_vehicles, load_peds).
Author DLC metadata
from fivefury import write_dlc_folder_metadata
write_dlc_folder_metadata("build/my_pack", pack_name="my_pack", order=60)
Scans the extracted DLC folder, infers common entries (nested .rpf, .ityp requests, audio data, text metadata), and writes setup2.xml and content.xml. DlcPatch builds update.rpf title-update overlays.
API conventions
High-level objects follow a consistent shape: add_* for collections, set_* for single assignments, build() to normalize derived state, and validate() to collect consistency issues before writing. Formats with stable game-side names expose typed enums (shaders, LODs, render masks, archetype asset types, bound materials, track formats).
License
FiveFury is released under the CC0-1.0 public domain dedication. See LICENSE.
Release notes live in CHANGELOG.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fivefury-0.2.16.tar.gz.
File metadata
- Download URL: fivefury-0.2.16.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
980b29a65c5edd6726ea0df5cfd11bef60b3e08f506730cf1b8b553e695335a9
|
|
| MD5 |
6831ab118fdd773080dc9808b0466cf3
|
|
| BLAKE2b-256 |
7d20bf5c1430eaecb846111ce379fcb51a6f90f6df95960ce986bdd7945ce53c
|
File details
Details for the file fivefury-0.2.16-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: fivefury-0.2.16-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29e7d2a4a55b2be57f50392c35942d1cc204c3395eb4794026f00acb1406cb59
|
|
| MD5 |
e244fcca1d8e115c12912c200351bc10
|
|
| BLAKE2b-256 |
ca3992725fda9efc05c653736963bdd4241f0807757e289274574a202bd15eef
|