FiveM custom props are the smallest asset you’ll ever stream and the most likely to half-work: the model loads but you walk straight through it, or it spawns fine for you and never appears for anyone else, or it blinks out of existence ten metres away. Nearly every one of those failures traces back to three files — the .ydr model, its textures and the .ytyp archetype definition — plus one manifest line that people keep getting wrong. Here’s how the prop pipeline actually works, from streaming and script spawning through furniture systems, collision, and what to check before you pay for a pack.
The three files that make a prop: .ydr, .ytd and .ytyp
A streamed prop is a model plus a definition. The .ydr is the drawable: mesh, shaders and material assignments. Textures live either in a separate .ytd texture dictionary or embedded inside the drawable itself. The .ytyp is the piece most people misunderstand — it defines the archetype: the prop’s registered name, bounding box, draw distance and flags. The game never spawns files; it spawns archetypes. No archetype, no prop, however cleanly the model streams.
Collision is the fourth piece, and it hides somewhere different than most buyers expect. A prop should carry an embedded bound inside its .ydr — that’s the surface your character actually stands on. Separate .ybn files are for big static map geometry, not for a chair. And anything meant to break, swing or flex — fences, sign poles, barriers that fall over — ships as a .yft fragment instead of a plain drawable. A pack mixing .ydr and .yft is usually a good sign, not sloppiness.
Streaming a prop pack: the folder and the one manifest line
The resource layout takes thirty seconds. Every asset file goes in stream/, and the manifest registers the archetype file:
`my_props/
├── fxmanifest.lua
└── stream/
├── xd_props.ytyp
├── xd_market_stall.ydr
└── xd_market_stall.ytd`
`fx_version 'cerulean'
game 'gta5'
data_file 'DLC_ITYP_REQUEST' 'stream/xd_props.ytyp'`
That data_file line is the step that gets skipped. FiveM collects everything in stream/ automatically, so the models and textures will stream without it — but the archetypes inside the .ytyp never get registered, and nothing can spawn them. The classic symptom: a map full of your props renders as empty air while vanilla props around them load fine. The path must match exactly, stream/ prefix included. One .ytyp can define dozens of archetypes, so even a large pack normally needs exactly one line.
Spawning custom props from a script
Registered archetypes spawn by name. In CfxLua, backticks compile a string to its joaat hash at load time, which is the tidy way to reference models:
`local model = `xd_market_stall`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local stall = CreateObject(model, coords.x, coords.y, coords.z, true, true, false)
PlaceObjectOnGroundProperly(stall)
FreezeEntityPosition(stall, true)
SetModelAsNoLongerNeeded(model)`
Two debugging natives save hours here. IsModelValid(model) tells you whether the archetype registered at all — if it returns false, your DLC_ITYP_REQUEST line is wrong or missing, and no amount of RequestModel will help. If HasModelLoaded never comes true instead, the .ydr itself isn’t streaming — check the file actually sits in stream/ and the resource restarted. Whether the object should be networked (that first true) is its own topic; for static decoration spawned per-client, pass false and skip the sync cost entirely.
Furniture and housing systems: how scripts consume prop lists
Housing and furniture scripts don’t contain furniture — they contain a config table of archetype names. Each entry is a model name, a label, a price and a category, and the placement UI simply spawns whatever the table offers. When a player decorates, the script stores the model name, coordinates and rotation in the database, then respawns everything when the property loads.
That makes adding a purchased furniture pack a two-step job: stream the resource, then append its archetype names to the furniture config. It also creates a trap nobody warns you about: those database rows reference archetype names forever. Rename an archetype in a pack update, or drop the prop resource from server.cfg, and every player who placed that sofa loads into a half-empty house. Treat streamed furniture packs as permanent infrastructure — never rename archetypes after players have placed them.
Job props: crates, market stalls and roadworks
Job scripts use props in two distinct ways, and picking the right one matters. Persistent scene dressing — the market stall that’s always there — belongs in a map file, not a script loop. Task props are the opposite: the delivery crate that appears at a pickup point, the cones and barriers that spawn around an active roadworks job, the pallet a warehouse worker carries. Spawn them when the task starts, delete them when it ends, and they cost the server nothing while nobody’s working.
Custom archetypes hand jobs a free bonus: targeting systems like ox_target and qb-target can register interactions by model name. A uniquely named crate archetype means “load this crate” appears on exactly that prop, everywhere it spawns, from one target definition — no zones to maintain, no coordinates to keep in sync.
Collision pitfalls: walk-through props and invisible walls
Collision problems are the number one defect in cheap prop packs. Walk-through props mean the .ydr has no embedded bound — the creator exported the mesh and skipped the collision step. Nothing server-side fixes this; the bound has to be authored into the file, which is why you check before buying, not after. Open the .ydr in CodeWalker and toggle the bounds view: if there’s no collision geometry there, there’s no collision in game.
The opposite failure is just as annoying: lazy box bounds. A detailed shelf wrapped in one crude cube collides like a fridge — players hit invisible walls, can’t reach anything placed near it, and the doorway beside it becomes impassable. The .ytyp bounding box causes its own bugs: too small and the prop vanishes while still on screen as the camera swings; too large and it never culls, quietly eating frame time. And PlaceObjectOnGroundProperly works off the bound too — a prop without proper collision also refuses to sit on the ground correctly when scripts spawn it.
Draw distance and LODs: what lodDist should actually be
Every archetype carries a lodDist — the distance at which the prop stops rendering. Creators set it high because it looks great in screenshots; on a busy server with a few hundred streamed props, it’s death by a thousand cuts. Sensible values: 30–60 for small clutter, 80–120 for furniture-sized objects, 150–250 for stall- and kiosk-sized props that anchor a location. A prop without a LOD mesh simply blinks in at its lodDist, so big props that need to read from far away should ship an actual lower-detail LOD model, not just a bigger number.
One line on memory, because it’s covered properly elsewhere: embedded textures duplicate VRAM per prop, so packs sharing one .ytd across a family of props are being kind to your players’ graphics cards.
Replace vs add-on — and how to vet a pack before you buy
A drawable named identically to a vanilla archetype and dropped into stream/ replaces that prop across the entire map — no .ytyp needed, because the archetype already exists. That’s occasionally what you want (a retextured vending machine city-wide) and frequently a disaster: two resources replacing the same prop fight silently, and the loser’s author blames your server. Add-on props with unique archetype names coexist with everything; for anything you’ll place deliberately, add-on is the correct answer.
Before paying for a prop pack, look for proof on four things. Poly counts: a chair or crate should sit in the low thousands of triangles — a 90,000-triangle coffee machine is a render asset ported straight off a stock-model site, and it will hitch when six of them stream in. Collision: embedded bounds you’ve seen in CodeWalker, not “collision included” in a product description. Completeness: a .ytyp covering every model, with names matching the files. Licence: streamed files can’t be protected by escrow — clients have to read them — so you’re relying entirely on the seller’s claim to own the models, and rips from other games or stock-asset sites are DMCA bait that lands on your server, not the seller.
Well-built props are cheap for what they carry: every job, housing and decoration system on your server sits on top of them.