
Optimizing assets for FiveM
Texture compression, mipmaps, LODs, file size, and crash checks for streamed assets.
Syntax
Platform team
Asset optimization in FiveM has a simple target: make each streamed file cheaper for the client to load, draw, and keep in memory. Smaller files help, but the healthiest result is the one that lowers runtime pressure without breaking the asset.
The right fix depends on the file. A vehicle with no LODs needs model work. A texture dictionary full of oversized alpha textures needs resizing and better compression. A prop with broken collision needs the model checked before you chase texture size.
Start with the file that costs you
Most streamed assets cost you in one of three places: texture memory, geometry, or bad references. Use the file type to decide where to look first.
| File | Main pressure | Zoovdev tool | What to check |
|---|---|---|---|
.ytd | Texture memory, disk size, mipmaps, alpha formats | Optimize Textures | Texture dimensions, DDS compression, unused entries, mipmaps |
.yft | Vehicle geometry, fragments, draw distance behavior | Optimize Vehicles | LOD output, model names, no _hi.yft uploads |
.ydr | Prop geometry, materials, embedded textures | Optimize Props | Material count, texture links, collision setup, export health |
.ydd | Clothing drawable size and texture use | Optimize Clothing | Texture size, drawable count, item scale, in-game clothing menu tests |
.ybn | Collision cost and broken bounds | Authoring tools | Simple bounds, correct materials, placement, crash testing |
fxmanifest.lua | Resource loading and data references | Code Agent | files entries, data_file lines, stream folder paths, meta references |
YTD and DDS mean different things
A .ytd is a RAGE texture dictionary. It stores named textures used by .ydr, .yft, and .ydd files. A .dds is a texture file format often used as the source, export, or intermediate format for those texture entries.
When someone says to compress a YTD, they usually mean resizing and recompressing the textures inside it. DDS compression is GPU texture block compression. It is different from zip-style archive compression because the graphics card can sample the compressed blocks directly.
| Format | Good use | Tradeoff |
|---|---|---|
BC1 / DXT1 | Diffuse or color textures without smooth alpha | Small, 8 bytes per 4x4 block, but rough on gradients and limited alpha |
BC3 / DXT5 | Diffuse, livery, decal, or UI-like textures that need alpha | Good support, 16 bytes per 4x4 block, twice the size of BC1 |
BC5 | Normal maps or two-channel mask data | Cleaner for two-channel data, wrong choice for full color textures |
BC7 | High-quality color or alpha textures, close-up liveries, painted detail | Cleaner than older formats in many cases, but slower to encode, larger than BC1, and newer DDS headers can bother older tool paths |
| Uncompressed | Debugging or special cases where the format requires it | Very high memory use. Avoid it for normal streamed content. |
Mipmaps
Mipmaps are smaller copies of the same texture. A 1024 x 1024 texture gets 512 x 512, 256 x 256, and smaller levels down the chain. The renderer samples the lower levels when the object is farther away.
Good mipmaps reduce shimmer, crawling edges, and noisy texture sampling at distance. They add texture data, but for world props, vehicles, clothing, and map assets, they are usually the right trade. Generate mipmaps after the final resize and compression so the chain matches the exported texture.
- Keep mipmaps for vehicles, props, clothing, signs, and map surfaces that can be seen from a distance.
- Be careful removing mipmaps from textures with alpha edges. The asset may look sharp in a preview and shimmer badly in game.
- Only skip mipmaps for a specific reason, such as a texture path that is never sampled at distance.
Power of 2 texture sizes
Use power-of-two texture sizes, often written as PO2, POT, or power of 2: 64, 128, 256, 512, 1024, 2048, and 4096. For RAGE and GTA assets, this is a safety rule, not just a tidy export habit.
Non-PO2 textures can do more than waste memory. In RAGE paths, they can break sampling or fail in ways that look unrelated to size. One common bad result is texture bleed: the material starts pulling pixels from nearby texture entries in the dictionary, so a prop, vehicle, or clothing item looks like it is referencing the wrong texture.
Practical texture targets
There is no useful single size limit for every server. The real limit depends on how many resources stream at once, how close players get to the asset, the texture format, and client hardware. A common community warning line is a single texture dictionary reaching about 16 MB of physical texture memory. Treat that as a reason to inspect the asset, not as a pass or fail law.
| Asset | Good starting point | Notes |
|---|---|---|
| Small props, clutter, decals | 256 to 512 | Use 1024 only when the player reads or inspects the surface up close. |
| Readable signs, posters, branded props | 512 to 1024 | Use 2048 for large, close, readable art. Crop empty space before raising size. |
| Vehicle liveries and diffuse maps | 1024 to 2048 | Use 4096 for close-up show vehicles or high-detail liveries, then test memory cost. |
| Vehicle normals, roughness, specular, masks | 512 to 1024 | These can often be smaller than the diffuse. Use the right data format, such as BC5 for normal maps. |
| Clothing | 512 to 1024 | Reserve 2048 for large garments with visible detail. Small accessories rarely need it. |
| MLOs and map textures | 512 to 1024 per reused material | Split dictionaries logically and reduce repeated 2K or 4K surfaces before touching geometry. |
| Texture size | BC1 / DXT1 with mipmaps | BC3 / DXT5 or BC7 with mipmaps |
|---|---|---|
| 1024 x 1024 | About 0.7 MiB | About 1.3 MiB |
| 2048 x 2048 | About 2.7 MiB | About 5.3 MiB |
| 4096 x 4096 | About 10.7 MiB | About 21.3 MiB |
Vehicle optimization and _hi.yft
For vehicles, the main model-side optimization is generating LODs for the .yft files. Do not include _hi.yft versions in the Zoovdev vehicle optimizer. The optimizer skips that type and builds LOD data from the normal vehicle model files.
A larger optimized .yft can be a good result. The file may contain more data because it now has lower-detail models for distance rendering. The benefit is that clients can draw cheaper geometry when the vehicle is far away. Texture savings for vehicles usually come from the related .ytd files.
- Upload the normal
.yftvehicle files, not_hi.yftfiles. - Run
.ytdfiles through texture optimization separately. - Test spawning the vehicle, driving away from it, returning to it, and restarting the resource.
- Keep model names, texture dictionary names, and vehicle meta references aligned.
Props, clothing, and collision
Props in .ydr and clothing in .ydd usually benefit from sane geometry, fewer wasted materials, and smaller texture dictionaries. If textures are embedded in the drawable, check both the model and texture output after export.
Collision in .ybn should be simpler than the visual mesh. Bad bounds can cause physics issues, broken interaction, or crashes that look unrelated to the model. Test collision in game after export, especially for MLOs, large props, and moved map pieces.
Resource and manifest checks
FiveM streams assets placed in a resource's stream/ folder automatically. Do not list streamed .ytd, .yft, .ydr, or .ydd files in files just because they are in stream/. Use the manifest to reference data and meta files that need explicit loading.
files {
'data/**/*.meta'
}
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'Bad data_file lines can make a healthy asset look broken. If streamed files are in the right stream/ folder but the resource still behaves badly, check meta references, file names, and data file declarations before blaming compression.
Crash symptoms and how to narrow them down
Asset crashes often show up as symptoms instead of a clean file name. You may see invalid pointer wording, neither virtual nor physical memory errors, DirectX query or GPU hangs, failed to call inflate() for streaming file, or a crash that only happens when someone spawns a vehicle, approaches an area, opens a clothing menu, or starts a resource.
- Reproduce the crash on a local or staging server with as few resources running as possible.
- Disable recent streamed assets, then re-enable them in halves until the crash returns.
- For vehicles, spawn one model at a time. Test the spawn, a short drive, distance streaming, and resource restart.
- For texture checks, temporarily swap the
.ytdwith a known-good dictionary or remove optional textures to separate texture issues from model issues. - Check
fxmanifest.lua,files,data_file, stream folder paths, and meta references. - Watch when the crash happens. On join points to global map, clothing, or always-loaded resources. On approach points to a map, prop, or MLO. On spawn points to a vehicle. On menu open points to ped or clothing content.
A good Zoovdev workflow
- Run texture dictionaries through Optimize Textures and check dimensions, compression, mipmaps, and alpha use.
- Run vehicle
.yftfiles through Optimize Vehicles without_hi.yftuploads. - Use Optimize Props for prop models and Optimize Clothing for clothing drawables.
- Use Code Agent to inspect resource manifests, data file references, and asset naming when a resource still behaves badly.
- Test the optimized resource in game before mixing it back into a large production pack.