Developer tools
Game Data Browser – Must have tool for every FiveM developer – search & live-preview 453,528 assets
Read it before you buy
These are the same files that come in the download, updated with every release.
lastresort_gamedata
The GTA V game data browser, in game. Search any asset, see it in the world a second later, and copy a working code example with the exact names already filled in.
LastResort Development · intelnpc.com
What it is
You need a toolbox prop. Today that means a wiki list, a guessed name, an alt-tab, a spawn that produces nothing, and another guess.
With this installed you type toolbox, arrow down, press Enter, and it is
standing in front of you. Press Alt+C and a working snippet is on your clipboard.
- Instant search — every keystroke scans the whole index in a few milliseconds
- One-click preview in the world, with rotate and zoom
- 33,912 dumped world positions — every ATM, gas pump, bus stop and jukebox — each one a place you can stand in front of, sorted nearest first
- A copy-ready Lua example for 42 of the 46 categories, verified before release
- Session picks, per-admin favourites, and a live activity timeline
- One panic action that ends every preview, effect and filter server-wide
- Standalone. ESX, QBCore and QBox are detected automatically, never required
- Open source. No escrow, no obfuscation, no fxap
What is in it
| Group | Categories | Entries |
|---|---|---|
| Spawn — props, vehicles, peds, weapons, components, pickups | 6 | 24,429 |
| Motion — animations, scenarios, clipsets, damage packs, waypoints | 5 | 21,906 |
| Effects — particles, timecycles, screen effects, explosions, camera shakes | 5 | 4,279 |
| Looks — clothing, ped props, tattoos, mod kits, liveries, colours | 6 | 39,841 |
| World — IPLs, interiors, zones, garages, world locations | 5 | 1,443 |
| Audio — sounds, speech, radio, music, scenes, banks, alarms, reports | 12 | 7,932 |
| Reference — shaders, handling, flags, restriction tags | 7 | 3,112 |
| Total | 46 | 102,942 |
Plus 269,414 animation clips, 81,206 speech lines and 33,912 world placements, sharded and loaded on demand so they cost nothing until you open the dictionary, voice or location group that holds them.
41 of the 46 categories preview in the world. Four of the rest are reference data with no native that accepts them. The fifth, scenario groups, has a native but previewing one re-populates the world around you, so it ships as search-only. Either way the browser says so on the entry rather than failing when you press Enter.
World locations
Pick World Locations, choose a group, and the entry lists the placements nearest you first with the map zone each one sits in. Press Enter and you are standing at it. The coordinates come from Rockstar's own placement dumps — 121 ATMs, 157 gas pumps, 345 vending machines, 48 bus stops, 6 jukeboxes, 8,065 seats — not from anybody's guess. Each one is labelled with the map zone its coordinate falls inside, so you pick "the one in Vespucci Beach" from the list rather than counting metres.
IPLs, MLO interiors, garages and static emitters carry the same zone label now, so their detail pane says where they are instead of only what they are called. Search still matches the name; the zone is a label you read, not a term you type.
Built from GTA V v3717.0 (Online 1.72), DLC mp2025_02_g9ec.
Requirements
- A FiveM server with OneSync enabled
- No database, no dependencies, no framework
Install
-
Drop
lastresort_gamedatainto yourresourcesfolder. -
Add to
server.cfg:ensure lastresort_gamedata -
Give yourself permission:
add_ace group.admin lastresort_gamedata.browse allow add_ace group.admin lastresort_gamedata.elevated allow -
Restart, then press F10 or type
/gdb.
Full detail, including how to grant access without ACE, in INSTALLATION.md.
Permissions
| Permission | Grants |
|---|---|
lastresort_gamedata.browse |
open the browser, search, preview, copy snippets |
lastresort_gamedata.elevated |
weapons, explosions, IPLs, interiors, cutscenes, world toggles, own-ped playback, the visible-preview flag, and the server-wide panic stop |
Without browse the command does nothing. Categories needing elevated show a
padlock and cannot be previewed.
Permissions are decided server-side and pushed to the client, which is told what it may do rather than asked. The actions that leave your machine — the panic broadcast, favourites and reports — are re-checked on the server when they arrive.
Commands
Prefix is configurable — Config.Command, default gdb.
| Command | Does |
|---|---|
/gdb |
open the browser |
/gdb find <term> |
open it already searching |
/gdb take |
send the current entry's name to chat, console and the pick list |
/gdb waypoint |
travel to the waypoint set on your map |
/gdb back |
return to where the first preview moved you from |
/gdb stopall |
panic: end every preview, effect and filter, everywhere |
/gdb debug |
toggle the live state overlay |
/gdbdebug |
the same overlay, as its own command and optional keybind |
/gdb demo [tour\|<category>] |
scripted showcase, built for recording |
/gdb report |
write a diagnostic file and print its path |
/gdb notifyreset |
retry notification providers previously marked broken |
Keyboard
| Key | Action |
|---|---|
F10 |
open the browser (rebindable in FiveM's key settings) |
/ |
jump to the search field |
↑ ↓ |
move through results |
PgUp PgDn |
move a page at a time |
Enter |
preview the selected entry |
Alt+T |
take — name to chat, console and pick list |
Alt+F |
toggle favourite |
Alt+C |
copy the snippet |
Delete |
stop everything |
Esc |
close, leaving the preview standing |
RegisterKeyMapping supplies a default, not a binding: FiveM writes the mapping into the
player's own fivem.cfg the first time it sees it, and the stored line wins from then on. A key
mapping registered against a fixed command name is therefore frozen at whatever default shipped
first — every later change to Config.Keybind.Open is ignored.
The key is part of the mapped command name here (gdb_open_f10), so changing Config.Keybind.Open
produces a mapping FiveM has never seen and the new default applies immediately, on every client.
One thing the resource cannot undo: a bind written by an earlier version still sits in that
client's fivem.cfg as a plain console line, pointing at gdb. It will keep working alongside the
new key until the player removes it, from the F8 console:
unbind keyboard f7
The search field holds focus from the moment the browser opens, which is why
take, favourite and copy are on Alt — a bare T belongs to whatever you are
typing. T, F and C on their own still work once the search field does not
have focus.
While the browser is open the game does not receive your keystrokes, so typing a search term never moves your character.
Closing with Esc deliberately leaves the preview in the world, so you can look
at it without the panels in the way. Stop all, Delete or /gdb stopall
clears it.
Config
Everything is in config/config.lua. The defaults are release defaults: safe on
a live server, and the demo works with no edits.
| Key | Default | Does |
|---|---|---|
Config.Enabled |
true |
master switch |
Config.Debug |
false |
console logging; turn on when reporting a problem |
Config.Command |
'gdb' |
command prefix |
Config.Keybind.Open |
'F10' |
opening key; Enabled = false removes it |
Config.Dev.Enabled |
false |
with BypassPermissions, grants every player full access — test servers only |
Config.Permissions.Identifiers |
{} |
identifiers granted browse access without ACE |
Config.Permissions.ElevatedIdentifiers |
{} |
identifiers granted full access without ACE |
Config.Categories.* |
true |
per-category switch; a disabled category vanishes from the GUI |
Config.Ui.Scale |
0 |
0 scales the GUI to screen height; any other value forces that zoom |
Config.Ui.Theme |
all empty | recolour the GUI without touching CSS — see below |
Config.Preview.Distance |
2.5 |
how far in front the preview sits |
Config.Preview.KeepOnClose |
true |
the preview survives closing the GUI |
Config.Preview.Visible |
false |
make previews visible to other players (needs elevated) |
Config.Preview.LoadTimeout |
10000 |
ms before a streaming request is abandoned |
Config.Preview.MannequinModel |
mp_m_freemode_01 |
ped used for animation, clothing and weapon previews |
Config.Preview.PedsOnSelf |
true |
previewing a ped model turns you into it; false spawns it in front of you instead |
Config.Search.IncludeClipsInGlobalSearch |
false |
fold all 269,414 clips into cross-category search — see the cost below |
Config.Search.MaxPlaces |
300 |
how many of a location group's placements the nearest list holds; the panel always shows the true total beside it |
Config.Effects.ExplosionDamageScale |
1.0 |
explosion size and damage radius; still audible and visible at 0.0 |
Config.Notify.Provider |
'auto' |
'auto', 'lastresort_notify', 'ox_lib' or 'builtin' |
Config.Picks.MaxFavorites |
500 |
per-admin favourite cap |
Config.RateLimit |
20 / 10s | per-source net event limit |
A config you have edited is never overwritten by an update:
shared/defaults.lua fills in only the keys a new version added.
Recolouring the GUI
Config.Ui.Theme maps design tokens to CSS colours. An empty string keeps the
shipped value, so you only fill in what you want to change:
Config.Ui = {
Scale = 0,
Theme = {
['accent'] = '#00FF88',
['bg-base'] = '#0B0F14',
},
}
| Token | Colours |
|---|---|
accent, accent-hover |
buttons, active states, the search caret |
cyan |
keyboard focus rings and secondary highlights |
bg-base, bg-surface, bg-raised |
the three panel depths |
text-primary |
body text |
dusk-pink, dusk-violet, dusk-orange |
the gradient along the top edge |
Any value CSS accepts works. Contrast is your responsibility once you override these; the shipped palette is checked against WCAG AA.
Folding animation clips into search
Config.Search.IncludeClipsInGlobalSearch = true makes all 269,414 clip names
searchable alongside everything else, so you can find idle_intro without
knowing which of the 20,179 dictionaries holds it. A clip result carries its
dictionary, and previewing one plays that exact clip.
It is off by default because it is not free. Measured in Chromium at 1080p:
| Index load | Worst keystroke | |
|---|---|---|
| Off (the core index alone) | 266 ms | 47 ms |
| On (core index plus every clip) | 456 ms | 149 ms |
Both are one-off costs inside the browser — neither touches server tick or resmon. Turn it on if you work with animations often and can live with a slower single-character search.
For other resources
The index is queryable by any script. This product needs nothing from anyone; anyone may use it. Exports exist on client and server.
local matches = exports.lastresort_gamedata:Search('toolbox', { limit = 10 })
for _, record in ipairs(matches) do
print(record.category, record.name)
end
local adder = exports.lastresort_gamedata:Lookup('vehicles', 'adder')
print(adder.label, adder.class, adder.seats)
local snippet = exports.lastresort_gamedata:GetSnippet(adder)
for _, category in ipairs(exports.lastresort_gamedata:GetCategories()) do
print(category.key, category.count)
end
local clips = exports.lastresort_gamedata:GetClips('missmic4')
local pumps = exports.lastresort_gamedata:GetPlaces('gaspumps')
print(#pumps, pumps[1].model, pumps[1].x, pumps[1].zone)
print(exports.lastresort_gamedata:GetDumpVersion())
| Export | Returns |
|---|---|
Search(term, options) |
records matching a substring; options.category, options.limit |
Lookup(category, name) |
one record, or nil |
GetCategories() |
every enabled category with its count and fields |
GetClips(dictionary) |
clip names in an animation dictionary |
GetPlaces(group) |
every placement in a location group, with its model, coordinate, rotation and map zone |
GetSnippet(record) |
the copy-ready example for a record |
GetDumpVersion() |
the GTA V build the shipped data came from |
Client-side only, for scripts that want to drive the GUI:
| Export | Does |
|---|---|
OpenBrowser(term) |
open the browser, optionally pre-searched |
CloseBrowser() |
close it |
IsBrowserOpen() |
whether it is open |
PreviewStop() |
end the current preview |
Categories load lazily, so a script that only queries vehicles never parses
the other 45 files, and GetPlaces reads only the one group's shard.
Cross-product behaviour
Sibling LastResort resources are detected at runtime and only ever add value:
- Notifications: config override →
lastresort_notify→ox_lib→ built-in feed - Chat output: the standard
chat:addMessageevent, whichlastresort_chatprovides
Installed alone, everything works and nothing is missing.
If a provider is broken on your server — a common case is ox_lib forwarding to
a UI resource that lacks the expected export — this product degrades instead of
failing: the provider is marked broken, the message still reaches you through
the built-in feed, and the failure is remembered so it is logged at most once.
Pin it with Config.Notify.Provider = 'builtin'; /gdb notifyreset clears the
memory once the underlying resource is fixed.
FAQ
Does it need a database? No. Favourites are stored in a JSON file inside the resource, per license identifier.
Do other players see the previews?
No. Preview entities are created locally and hidden from the network. Set
Config.Preview.Visible = true for collaborative scene work; it requires
elevated.
Previewing a ped is the exception, because it changes your own character
rather than spawning one, and a model change is always networked — everyone
sees you as that ped until you stop. Config.Preview.PedsOnSelf = false goes
back to a separate, local figure standing in front of you.
Does it cost performance when idle? No, and not in a hand-waving way: with the browser closed and no preview active, this resource has no thread scheduled at all.
| State | Threads running | Expected resmon |
|---|---|---|
| Browser closed, no preview | none | 0.00 ms |
| Browser open | none — the GUI runs in the NUI process | 0.00 ms |
| Preview active | none, except a waypoint route being drawn | 0.00 ms |
/gdb debug overlay on |
one, per frame, while visible | ~0.02 ms |
/gdb demo tour running |
one, at 100 ms | negligible |
Every thread in the resource is created on demand and exits when its work ends; the framework bridge runs once at start and stops. The index is never parsed Lua-side unless a script calls an export.
Can it leave the world dirty?
Every preview journals what it touched — entities, streamed models, animation
dictionaries, particle handles, weapon assets, IPLs, pinned interiors, waypoint
recordings, audio banks, screen effects, world toggles, and your own character
down to its clothing, head blend and face features — and reverts all of it when
you switch entries, hit Stop all, disconnect, or stop the resource.
/gdb debug shows the journal live, so you can watch it return to zero.
Closing the GUI deliberately does not clean up, so you can inspect a preview
without the panels covering it. Config.Preview.KeepOnClose = false restores
cleanup on close.
Why do some interiors say they are not streamed in? 160 of the 385 interiors belong to DLC. When one of those is not loaded on your client the browser names the DLC rather than pretending the interior does not exist.
Are the code examples actually correct? They are verified as a build step, not by hand. Every native call in every template is checked against 6,089 signatures taken from the CitizenFX documentation, then each filled snippet is compiled with Lua 5.4 and executed against a stub runtime. Five deliberately broken snippets are kept to prove the check still fails when it should.
Can I rebuild the data for a newer GTA V build? Yes, and the tooling ships with the resource. See section 6 of INSTALLATION.md.
Documentation
| File | Contents |
|---|---|
| INSTALLATION.md | install, permissions, first run, rebuilding the data |
| CHANGELOG.md | features, changes and removals per version |
| docs/RESEARCH.md | data provenance, measurements, assumptions |
| docs/coverage-matrix.md | every upstream file and its verdict |
| docs/TESTING.md | build and in-game verification checklist |
| docs/STORE.md | store listing copy |
Credits
Open source, no escrow, no obfuscation. Read every line before you run it.
Installation
- Copy
lastresort_gamedatainto theresourcesdirectory. - Add this to
server.cfg:
set onesync on
ensure lastresort_gamedata
add_ace group.admin lastresort_gamedata.browse allow
add_ace group.admin lastresort_gamedata.elevated allow
- Restart the server, then open the browser with the configured command or key.
Configure
- Use
Config.Permissions.Identifiersfor individual access if you do not use ACE groups. - Keep browse and elevated access separate. Elevated access controls weapons, explosions, interiors, and visible previews.
- Adjust the open key, search limits, preview settings, and theme in the config files.
Verify
- Open the browser and search for a model or animation.
- Run a safe preview and then Stop all to confirm cleanup.
- Test an elevated category with an allowed admin and a regular player.
- Use
/gdb reportif the browser, permissions, or data index does not load.
Important
- No framework or database is required.
- Set
Config.Dev.EnabledandConfig.Dev.BypassPermissionstofalseon a live server. - Elevated access includes dangerous previews, so grant it only to trusted admins.
| Dump file | Verdict | Category | Entries | Reason |
|---|---|---|---|---|
.gitattributes |
excluded | - | - | repository metadata |
.github/FUNDING.yml |
excluded | - | - | repository metadata |
ObjectList.ini |
previewable | objects |
21561 | 21561 createable props, spawned as a frozen preview object |
PedList.ini |
excluded | - | - | name and hash only, fully superseded by peds.json |
README.md |
excluded | - | - | repository documentation |
VehicleList.ini |
excluded | - | - | name and hash only, fully superseded by vehicles.json |
WeaponList.ini |
excluded | - | - | name and hash only, fully superseded by weapons.json |
alarmSounds.json |
previewable | alarms |
60 | 60 alarms, prepared then started and stopped |
ambientAudioBankNames.json |
previewable | ambientaudiobanks |
144 | 144 ambient audio banks, requested and released |
ambientZones.json |
excluded | - | - | 1414 audio zones with no name a scripter addresses directly |
animDictsCompact.json |
previewable | animdicts |
20179 | 20179 dictionaries; 269414 clips sharded and loaded on demand |
animPostFxNamesCompact.json |
previewable | animpostfx |
173 | 173 screen effects with an explicit stop |
assets/ (103 files) |
excluded | - | - | PNG artwork; shipping third-party images in a paid resource is out of scope |
audioSceneNames.json |
previewable | audioscenes |
1147 | 1147 audio scenes, started and stopped by name |
camShakeTypesCompact.json |
previewable | camshakes |
23 | 23 camera shakes applied to the gameplay camera |
cutsceneNames.json |
previewable | cutscenes |
807 | 807 cutscenes, requested and played with an explicit stop; behind the stricter permission because one takes over the screen |
drivingStyleFlagValues.json |
excluded | - | - | 33 driving style bits, outside this product |
eEventType.txt |
excluded | - | - | C enum dump, not an asset name |
explosionTypesCompact.json |
previewable | explosions |
88 | 88 explosion types fired at a safe offset |
flagValues.json |
excluded | - | - | YTYP/YMAP flag research, a modding reference outside this product |
garages.json |
previewable | garages |
32 | 32 garages, previewed at their position |
handlingFlagValues.json |
excluded | - | - | handling flag research, outside this product |
ipls.json |
previewable | ipls |
895 | 895 IPLs, request tracked so the panic stop can always revert them |
missionAudioBankNames.json |
previewable | missionaudiobanks |
22 | 22 mission audio banks, requested and released |
missionCompleteAudioNames.json |
previewable | missioncompleteaudio |
4 | 4 mission complete stingers, played once |
mloInteriors.json |
previewable | interiors |
385 | 385 interiors, pinned in memory at their dumped location |
movementClipsetsCompact.json |
previewable | clipsets |
557 | 557 movement clipsets applied to a walking mannequin |
movementClipsetsWalkingCompact.json |
previewable | clipsets |
557 | 207 walking clipsets, merged as a flag on the clipset index |
musicEventNames.json |
previewable | musicevents |
1585 | 1585 music events, triggered with an explicit cancel |
navigationmesh.md |
excluded | - | - | documentation for an off-repo mega.nz download |
nodes.zip |
excluded | - | - | 3.9 MB zipped vehicle navigation nodes; not an asset name and needs unzipping at build time |
objectslocations/ (35 files) |
previewable | locations |
34 | 34 groups holding 33912 dumped world placements, each one a place to stand at, labelled with the map zone its coordinate falls in; worldExtraVendingMachines.json is empty upstream |
particleEffectsCompact.json |
previewable | particles |
2907 | 2907 effects across 360 assets, played at a marked point |
pedApparelRestrictionTags.json |
search-only | apparelrestrictions |
475 | 475 restriction tags |
pedComponentVariations.json |
excluded | - | - | 615 byte stub; the paid variant of the _free dump, not redistributable |
pedComponentVariations_free.json |
previewable | pedcomponents, pedprops |
35609 | 30396 components and 5213 props cycled on a freemode mannequin |
pedDamagePacks.json |
previewable | peddamagepacks |
72 | 72 damage packs applied to the preview mannequin |
pedHairColors.json |
excluded | - | - | 64 palette swatches, surfaced inside the clothing preview rather than as a category |
pedOverlayCollections.json |
previewable | pedoverlays |
3373 | 3373 tattoos and badges applied by collection and overlay hash |
pedOverlayFacings.json |
excluded | - | - | 8 facing names, already implied by the overlay zone |
pedOverlayTypes.json |
excluded | - | - | folded into the overlay index as the type filter facet |
pedOverlayUpdateGroups.json |
excluded | - | - | 92 internal update groups with no scripting use |
pedOverlayZoneNames.json |
excluded | - | - | folded into the overlay index as the zone filter facet |
peds.json |
previewable | peds |
1109 | 1109 ped models with ped type and head-blend flag |
peds_directorname_gxtkeys.txt |
excluded | - | - | director mode GXT keys; the English label already ships in the peds index |
pickupTypes.json |
previewable | pickups |
175 | 175 pickup types with their world models |
policeReportNames.json |
previewable | policereports |
50 | 50 police reports, played over the radio |
ps3-builds.xml |
excluded | - | - | 853 KB PS3 build history, historical curiosity |
radioStations.json |
previewable | radiostations |
86 | 86 stations set on the preview vehicle |
scenarioGroupNames.json |
search-only | scenariogroups |
235 | 235 group names; groups gate scenarios rather than play on their own |
scenariosCompact.json |
previewable | scenarios |
247 | 247 scenarios played on the preview mannequin |
scriptAudioBankNames.json |
previewable | scriptaudiobanks |
617 | 617 script audio banks, requested and released |
shaders.json |
search-only | shaders |
415 | 415 shaders; modding reference with no in-game preview |
soundNames.json |
previewable | sounds |
2204 | 2204 frontend sounds across 501 refs |
speeches.json |
previewable | speeches |
1083 | 1083 voices; 81206 distinct line names sharded and loaded on demand |
staticEmitters.json |
previewable | staticemitters |
930 | 930 positioned audio emitters, enabled in place |
strings.txt |
excluded | - | - | 844 KB executable string scrape with no scripting use |
timecycleModifiers.json |
previewable | timecycles |
1088 | 1088 screen filters applied live with an explicit stop |
traintracks.json |
excluded | - | - | 12 track configs, consumed by TRACK natives rather than browsed |
vehicleColors.json |
previewable | vehiclecolors |
179 | 161 paints, 13 xenon and 5 window colours applied to the preview vehicle |
vehicleHandlings.json |
previewable | handling |
838 | 838 handling records, previewed from the driver's seat of a car that uses them |
vehicleModKits.json |
previewable | modkits, liveries |
680 | 602 kits, 36282 mods and 78 named liveries applied to the preview vehicle |
vehicleTxdRelationships.json |
excluded | - | - | 993 texture dictionary parents, internal streaming detail |
vehicles.json |
previewable | vehicles |
921 | 921 vehicles with class, manufacturer, seats and mod kits |
vehiclesClasses.json |
excluded | - | - | folded into the vehicles index as the class filter facet |
vehiclesDashboardTypes.json |
excluded | - | - | vehicle metadata already carried per vehicle |
vehiclesFlags.json |
search-only | vehicleflags |
193 | 193 vehicle flag names |
vehiclesManufacturers.json |
excluded | - | - | folded into the vehicles index as the manufacturer filter facet |
vehiclesPlateTypes.json |
excluded | - | - | vehicle metadata already carried per vehicle |
vehiclesRewards.json |
excluded | - | - | 14 reward ids with no browsable meaning |
vehiclesTypes.json |
excluded | - | - | folded into the vehicles index as the type filter facet |
vehiclesWheelTypes.json |
excluded | - | - | vehicle metadata already carried per vehicle |
waypointRecordings.json |
previewable | waypoints |
851 | 851 recordings, drawn across the map as a route rather than walked |
weaponAmmoTypes.json |
excluded | - | - | folded into the weapons index as the ammo filter facet |
weaponCategories.json |
excluded | - | - | folded into the weapons index as the category filter facet |
weaponDamageTypes.json |
excluded | - | - | folded into the weapons index as the damage filter facet |
weaponFlags.json |
search-only | weaponflags |
149 | 149 weapon flag names |
weapons.json |
previewable | weapons, weaponcomponents |
663 | 184 weapons and 479 components, behind the stricter permission |
zones.json |
previewable | zones |
97 | 97 named map zones, previewed by moving the camera to the centre point |
215 paths classified: 73 previewable, 5 search-only, 137 excluded. all 46 shipped categories are wired into shared/categories.lua.
RESEARCH — lastresort_gamedata
Milestone M0. Every number in this document was measured on the checked-out
data, not estimated. Where something could not be verified it is marked
ASSUMPTION and repeated in section 9.
1. Provenance and acquisition
Nothing is fetched at runtime and no raw dump ships inside the resource. The build pulls three repositories as blobless, no-checkout git clones and then checks out only the paths actually needed, per the product line data policy.
| Source | Repository | Used for |
|---|---|---|
| Native docs | citizenfx/natives |
native signatures, parameter semantics |
| CFX native docs | citizenfx/fivem (ext/native-decls only) |
FiveM-specific natives |
tools/fetch_dumps.sh performs the acquisition. It deliberately skips
assets/, nodes.zip and ps3-builds.xml, which together are ~5 MB of blobs
no shipped index draws from. objectslocations/ is fetched — it was skipped
until the World Locations category was added; see section 2.
Build pipeline, in order:
./tools/fetch_dumps.sh
python3 tools/native_index.py --natives build-refs/natives --cfx build-refs/fivem/ext/native-decls --out tools/native_index.json
python3 tools/distill.py --dumps build-refs/dumps --out data/index --enums tools/native_enums.json
python3 tools/coverage.py --dumps build-refs/dumps --index data/index > docs/coverage-matrix.md
python3 tools/verify_snippets.py --index tools/native_index.json
python3 tools/check_natives.py --index tools/native_index.json
The shipped resource depends on none of it at runtime.
2. Coverage matrix
The full per-file matrix is generated, not hand-written:
docs/coverage-matrix.md. tools/coverage.py lists the
upstream repository itself and exits non-zero if any path lacks a verdict,
so the matrix cannot drift when the dumps change.
All 215 paths are classified. The verdict split moved during development as
categories were added — docs/coverage-matrix.md is generated from the code and
is always current; the numbers below are illustrative of the shape, not a
running total.
The remaining exclusions are less severe than the number suggests — 66 of them
are the assets/ images:
| Exclusion group | Files | Why |
|---|---|---|
assets/ PNGs |
66 | third-party artwork; shipping it in a paid resource is out of scope |
| Folded into a parent index as a filter facet | 13 | e.g. vehiclesClasses.json is the vehicle class filter, not a category |
| Superseded by a richer dump | 4 | the .ini name=hash lists, and pedComponentVariations.json (a 615-byte stub of the paid variant) |
| Research/modding reference, not scripting assets | 9 | flag value dumps, strings.txt, ps3-builds.xml, eEventType.txt |
| Deferred with a reason | 3 | speeches.json, waypointRecordings.json, vehicleHandlings.json |
speeches.json was initially excluded at 10.4 MB, then brought in under the
same lazy shard scheme the animation clips use: 1,083 voices and 81,206
distinct line names, playable through PlayPedAmbientSpeechWithVoiceNative.
Vehicle handling and waypoint recordings joined it.
objectslocations/ followed, and the reversal is worth recording because the
original exclusion reason was sound for the question it answered. As props
these are positions of models already browsable by name, which is what the
first verdict said. As places to stand, a coordinate is the entire point,
and 33,912 of them are exactly the data a scripter building a fuel, robbery or
jukebox script has to source by hand today. Two measurements decided it: the
same lazy shard scheme keeps the always-loaded index flat (+2,827 B for the 34
group rows, the 1.16 MB of placements fetched only when a group is opened), and
every one of the 33,912 coordinates but four falls inside a bounding box in
zones.json, so each gets a real map-zone label instead of a bare number.
3. Index sizes after distillation
Measured output of tools/distill.py. Categories are stored columnar, with
low-cardinality string columns replaced by an integer index into a per-column
palette.
| Tier | Files | Entries | Raw | Gzipped |
|---|---|---|---|---|
| Core index (46 categories, always loaded) | 46 | 102,942 | 3.72 MB | 610 KB |
| Animation clips (loaded on demand) | 23 | 269,414 | 6.72 MB | 800 KB |
| World placements (loaded on demand) | 34 | 33,912 | 1.16 MB | 421 KB |
| Speech lines (loaded on demand) | 22 | 81,206 | 1.24 MB | 125 KB |
| Total shipped | 125 | 487,474 | 12.85 MB | 1.91 MB |
Largest single categories: pedcomponents 1.23 MB, animdicts 743 KB,
objects 566 KB.
The shard split is the decision that makes the budget work. Indexing all
269,414 clips, 81,206 speech lines and 33,912 world placements inline would
more than quadruple the always-loaded payload for data that is only meaningful
once a specific dictionary, voice or location group is selected. Clips and
speech shard by first character (data/index/clips/<char>.json,
data/index/speeches/<char>.json); placements shard by group
(data/index/locations/<group>.json), because a group is exactly the unit the
browser asks for. What stays always-loaded is the 34-row group index, 2,827
bytes.
4. Where the index lives, and the search approach
4.1 Transport
The index ships as plain files listed in files{} and is fetched by the NUI
page directly. A FiveM NUI page is served from https://cfx-nui-<resource>/,
so a relative fetch('data/index/vehicles.json') resolves to the resource's
own files. This is verified against working code already in this repo:
lastresort_vehicle_inspection/web/js/app.js:12 derives its resource name by
stripping the cfx-nui- prefix from window.location.hostname.
This avoids the alternatives entirely: no SendNuiMessage payload carrying
megabytes of JSON, no LoadResourceFile on the client, no server round-trip.
The Lua side never parses the index unless a script asks for it through an export.
4.2 Search algorithm — measured, not assumed
Benchmarked in Node 22 over the real distilled index:
| Haystack | Entries | Per keystroke |
|---|---|---|
| Core index | ~100,000 | 1.5 – 5.6 ms |
| Core + every animation clip | ~370,000 | 6.8 – 14.3 ms |
Cold start, measured on the 45-category 1.0 index: 36 ms to read and parse every core file, plus 25 ms to build the lowercase haystack — ~61 ms total. The 46th category added since costs 2,827 bytes and 34 rows, so the figure is unchanged in practice; the placement shards are not in the cold path at all.
Incremental narrowing measured separately: typing t → toolbox (7
keystrokes) costs 25 ms in total, because each keystroke filters the previous
result set rather than rescanning.
Conclusion: a naive indexOf scan is fast enough. No trigram index, no
inverted index, no Web Worker. The measurement says the simple implementation
wins, and the anti-slop contract says to prefer it. Clips stay out of the
default cross-category haystack and are searched in an explicit clip mode,
which keeps the common path in the 1.5–5.6 ms band.
4.2b Rendering, not searching, was the real cost
Measured in Chromium against the live GUI, per keystroke, end to end:
| Query | Matches | Before | After |
|---|---|---|---|
| `` (everything) | ~100,000 | 40.4 ms | 9.5 ms |
a |
61,931 | 122.7 ms | 11.8 ms |
prop_ |
12,476 | 57.6 ms | 15.9 ms |
toolbox |
9 | 8.3 ms | 4.5 ms |
The scan was never the bottleneck — building up to 1,000 DOM rows was. The results list now renders a 120-row window that follows the selection, which is 7× faster at the worst case and puts every keystroke inside one 60 fps frame.
A trigram index was considered and rejected on evidence: these names share a
tiny alphabet of machine-generated morphemes (prop, ent_, _01, mp_), so
only ~13,000 distinct trigrams exist across the whole corpus and the index has
almost no discriminating power. On the most common real query in an object
browser — prop_ — posting-list intersection is slower than the plain scan.
ASSUMPTION-1: these timings are Node 22 on the build machine. FiveM's CEF
runs an older V8 and competes with the game for CPU. Even allowing a
conservative 3–4× slowdown the core index stays well inside one 60 fps frame.
To be confirmed with the in-game debug overlay at M1.
4.3 DLC filtering
Only some dumps carry a DlcName. Measured distinct values:
| Category | DLC field | Distinct values |
|---|---|---|
vehicles |
yes | 47 |
peds |
yes | 43 |
weapons |
yes | 34 |
ipls |
yes | — |
timecycles |
yes | 4 |
pedcomponents / pedprops |
via DlcCollectionName |
84 collections |
objects, animdicts, particles, sounds, … |
no | — |
The brief's DLC filter therefore applies to those categories only. The GUI must hide the filter rather than show an empty one where the field does not exist.
5. Snippet verification
The brief's non-negotiable rule is that every generated example runs as
pasted. tools/verify_snippets.py enforces the mechanical half of that as a
build step, so the in-game paste test only ever has to confirm behaviour:
- Placeholders are filled from the real distilled index, so what is verified is exactly what a customer copies.
- Every native call is checked against the 6,089-signature index built from the CitizenFX docs — existence, exact spelling, and argument count.
- The filled snippet is compiled with
luac5.4, the runtime FiveM targets. - The filled snippet is executed against
tools/fivem_stub.lua, catching undefined locals, nil arithmetic, missing load waits, and loops that never terminate.
Arity checking models a real FiveM rule: Lua callers omit pointer
out-parameters, which come back as extra return values. char* is an input
and stays. The checker therefore accepts a range rather than a single count.
Status: 42 templates, 0 failing.
The checker is proven to fail on bad input — five deliberately broken snippets are all caught with precise diagnostics:
| Negative control | Caught as |
|---|---|
RequestAnimDictionary (typo) |
unknown native RequestAnimDictionary |
TaskPlayAnim with 4 args |
called with 4 arguments, signature TASK_PLAY_ANIM accepts 11 |
local x = |
lua syntax: unexpected symbol near 'end' |
| concat of an undefined global | attempt to concatenate a nil value |
while true do end with no Wait |
did not terminate within 30s; a loop is missing its Wait |
Three real defects were found and fixed by this process during M0:
LoadInteriordoes not exist. The correct native isPinInteriorInMemory.GetVehicleColourswas called without accounting for itsint*out-parameters.shaders.jsonsilently distilled to zero entries because the generic string-list builder was pointed at a dump of objects. The builder now raises instead of emitting an empty category.
ASSUMPTION-2: the stub proves a snippet executes; it cannot prove the game
does the visible thing. Per-category in-game paste tests are the M1–M3
acceptance gate and are listed in docs/TESTING.md.
6. Corrections to the upstream README
| Claim in upstream README | Measured |
|---|---|
| 33,558 component variations, 5,883 props, 96 collections | 30,396 / 5,213 / 88 in pedComponentVariations_free.json |
| 43,428 audio names from 43 unique refs | 2,204 names from 501 refs in soundNames.json |
| 21,631 createable objects | 21,631 keys, of which 70 are _lod variants; 21,561 ship |
The shipped indexes follow the measured values. _lod entries are dropped
because they are level-of-detail meshes, not props anyone spawns deliberately.
ASSUMPTION-3: the two upstream count mismatches are most likely because the
free dump is a reduced variant of the paid one and because soundNames.json
changed format upstream. Either way the shipped indexes describe the files as
they actually are.
7. Data shape findings that change the product
Discovered while distilling, each one affects what the GUI can offer:
- Vehicle mods have no names.
vehicleModKits.jsonmods carry only{Index, Type, Bone, Weight, IsWeapon}. There is nothing to substring-search. Mods are therefore browsed through their kit and mod type, and the kit name is the searchable string. Liveries are the exception — those are named, so they ship as their own searchable category (78 entries). - Ped clothing is freemode-only. All 84 collections resolve to
mp_m_freemode_01ormp_f_freemode_01. Component ids are meaningless on other ped models, so the clothing preview requires a freemode mannequin and the snippet warns when the target ped is a different model. RelativeCollectionDrawableIddiffers fromDrawableId. Both ship; the absolute id is whatSetPedComponentVariationwants, and the relative id is what DLC-collection-aware code needs.- Ped names are cased inconsistently upstream (
A_C_Boarinpeds.json, lowercase in most scripts). The index normalises to lowercase, which is whatGetHashKeyneeds. - Hashes ship signed.
peds.jsonandvehicles.jsonexpose both; weapons exposeIntHash. All verified to match after conversion.
8. Repo conventions and sibling detection
Surveyed across all seven shipped lastresort_* resources. What this product
adopts, and what the survey caught it getting wrong:
| Convention | Applied here |
|---|---|
| Two-line attribution header on every source file | yes |
fxmanifest field order, lua54, repository |
yes; no escrow_ignore, since nothing here is escrowed |
shared/defaults.lua config backfill, loaded straight after config.lua |
yes — mandatory, because an owner keeps their own config.lua across updates |
Framework detection by GetResourceState, never a hard dependency |
yes, bridge/{client,server}.lua |
Sibling detection by GetResourceState, never an event |
yes |
Notification chain: config override → sibling → ox_lib → builtin |
yes |
| ACE first, framework group second, checks always server-side | yes |
Per-source rate limit on every net event + playerDropped cleanup |
yes, server/permissions.lua |
| Commands read from config, never hardcoded | yes, Config.Command |
Shared lrNuiOwner statebag participation |
yes |
Four defects the survey caught in this resource, all fixed:
exports['lastresort_chat']:AddMessage(...)— the real export is lowercaseaddMessage, is server-side only, and takes(target, message). The client call would have failed silently forever. Now uses thechat:addMessageevent, whichlastresort_chatprovides.- The GTA feed fallback was missing the mandatory 99-character clamp.
bridge/server.luacalled framework exports with nopcalland returned a job name as an admin group. A job is not an admin group; the QBCore path is gone and the ESX path is wrapped.- ACE names were bare
gamedata.browse/.elevated; house style islastresort_gamedata.browse/.elevated.
The NUI focus rule
The most important convention in the repo, learned from a real bug: release
focus unconditionally. Never gate SetNuiFocus(false, false) on your own
open flag or on the shared owner bag.
SetNuiFocus is tracked per resource, so releasing can only ever drop your
claim — there is nothing to protect anyone else from. Gating the release is how
a cursor gets stuck for the rest of the session. The shared lrNuiOwner
statebag is the only part that takes an ownership check, and only on clear,
because that value is shared.
This product's first implementation had the gate. It was removed.
Collision check
gdb as a command prefix, F10 as a keybind, and lastresort_gamedata.* as
ACE names collide with nothing in the suite. Exports are PascalCase and
domain-explicit (Search, Lookup, GetCategories, GetSnippet,
OpenBrowser) to stay clear of the shared vocabulary already in use
(Notify, Open, Close, GetHistory, …).
This product overlaps no sibling's features, so unlike lastresort_npc_chat
under lastresort_intel_npc it never self-shuts-down.
9. Open ASSUMPTION items
| Id | Assumption | How it gets resolved |
|---|---|---|
ASSUMPTION-1 |
Search timings measured in Node 22 hold in FiveM's CEF within a 3–4× margin | M1, in-game debug overlay reports real per-keystroke cost |
ASSUMPTION-2 |
A snippet that executes against the stub also does the right thing in game | M1–M3 in-game paste tests per category, docs/TESTING.md |
ASSUMPTION-3 |
Upstream README count mismatches are staleness, not a broken dump | measured counts ship; revisit if upstream regenerates |
ASSUMPTION-4 |
resolved — speeches.json ships, sharded by voice name |
done: 1,083 voices, 81,206 lines |
10. Preview method and cleanup guarantee, per kind
Every previewable category maps to a handler in client/preview/. The registry
keeps exactly one preview per admin and journals everything it touches, so the
guarantee is the same everywhere: switch, close, disconnect, resource stop and
panic all drain the same journal.
| Kind | Method | Cleanup | Trap avoided |
|---|---|---|---|
| model / vehicle / ped | validity gate → RequestModel bounded → create local, frozen, no collision |
DeleteEntity + SetModelAsNoLongerNeeded |
CreateObjectNoOffset, because CREATE_OBJECT shifts Z by the bounding radius and makes swaps jump |
| weapon | RequestWeaponAsset → GiveWeaponToPed + SetCurrentPedWeapon |
RemoveWeaponAsset |
60 of 184 weapons have no world model; confirmed with HasPedGotWeapon |
| pickup | CreateNonNetworkedAmbientPickup |
RemovePickup |
networked pickups are collectable by the whole server |
| anim | DoesAnimDictExist → RequestAnimDict bounded → TaskPlayAnim → confirm with IsEntityPlayingAnim |
StopAnimTask with blend-out 1.0, then RemoveAnimDict |
a blend-out of 0.0 locks the ped out of animation until it dies |
| scenario | TaskStartScenarioAtPosition with warp |
immediate scenario exit → ClearPedTasks |
many scenarios need a prop or mapped point and silently idle |
| clipset | RequestClipSet bounded → set movement + strafe → task the ped to walk |
reset before RemoveClipSet |
invisible on a stationary ped; only 207 of 557 are true walking sets |
| particle | RequestNamedPtfxAsset → UseParticleFxAsset → start looped |
stop + remove by handle, radius sweep at the recorded coord, then release the asset | UseParticleFxAsset binds only the next start call |
| timecycle | validate with GetTimecycleModifierIndexByName, snapshot, apply |
clear both slots, restore the snapshot | SetTimecycleModifier silently no-ops on a bad name |
| explosion | documented eExplosionTag id → AddOwnedExplosion |
StopFireInRange + particle sweep, restore proofs |
list position is not the id |
| ipl / interior | snapshot state, fade, SetFocusPosAndVel + NewLoadSceneStart |
restore the recorded prior state, unpin, ClearFocus |
neither reverts on resource stop by itself |
| audio | play / request by name | stop, release bank, release sound id | banks stay pinned until released |
11. Adversarial review
The preview methods were re-checked by an independent pass whose only brief was to find what is wrong. Three of its findings were confirmed against the native documentation and fixed in the shipped code:
SetVehicleDoorsLocked(vehicle, 4)does not lock a preview vehicle. State4isVEHICLELOCK_LOCKED_PLAYER_INSIDE— "locked once a player enters, preventing others from entering" — which is not what a display vehicle wants. Now2,VEHICLELOCK_LOCKED.- The particle cleanup swept a 25 m radius unconditionally.
RemoveParticleFxInRangedestroys effects owned by other resources. It ran on every teardown, including the ones where the handle had already been stopped cleanly — so every preview would have silently killed other scripts' vehicle smoke, fire and weather effects within 25 m of the admin. The sweep is now the fallback for an orphaned handle only. - Preview start had no re-entrancy guard.
startyields while streaming, so two rapid activations could interleave and the second would purge the journal of the first mid-load.
The first attempt at a fix was a busy latch that refused the second start, and
it had a bug of its own: stop() cleared the very flag start() had just set,
so the guard never engaged. tests/preview.test.lua caught that. The latch was
then replaced outright, because refusing the newer preview is the wrong
behaviour — an admin arrowing down a list expects the latest entry to win. The
shipped guard is a monotonic generation token
(client/preview/registry.lua): the second start proceeds, the first notices
its token is stale, purges only what it created, and returns silently.
tests/preview.test.lua covers all three fixes in 16 assertions.
Findings that did not apply to the shipped code, because the journal design
already handles them: streamed assets are tracked before the bounded wait, so
a load timeout releases rather than leaks; and onResourceStop, disconnect and
panic all drain the same journal.
12. Status of this document
Complete. Sections 1–7 and 9 were verified directly against the checked-out data; section 8 against the seven shipped sibling resources; section 10 against the CitizenFX native documentation, with each trap traced to the specific native doc that records it.
STORE — lastresort_gamedata
Tebex listing copy. Nothing here uses Rockstar or Next GTA logos, artwork, screenshots or trademarks.
Title
Game Data Browser — search, preview and copy any GTA V asset, in game
Short description
Stop alt-tabbing to wiki lists. Search 453,562 asset names from inside your server, see any prop, ped, vehicle, animation or effect standing in front of you a second later, and copy a working code example with the names already filled in.
Long description
The loop this ends
You need a toolbox prop. So you open a wiki list, guess a name, alt-tab back, spawn it, get nothing, and guess again. Twenty minutes for one prop.
With this installed you type toolbox, arrow down, press Enter, and it is
standing in front of you. Press Alt+C and a working snippet is on your clipboard.
Seconds, not minutes, without leaving the game.
Everything, in one panel
- 21,561 props · 921 vehicles · 1,109 peds · 184 weapons
- 20,179 animation dictionaries holding 269,414 clips
- 1,083 speech voices holding 81,206 lines
- 2,907 particle effects · 1,088 timecycle modifiers · 173 screen effects
- 30,396 clothing components · 5,213 ped props · 3,373 tattoos and badges
- 602 mod kits · 838 handling profiles · 895 IPLs · 385 interiors
- Plus scenarios, clipsets, pickups, explosions, camera shakes, zones, garages, waypoint routes and the full audio set
Search that keeps up with you
Every keystroke scans the whole index in a few milliseconds. Results are ranked
— exact match first, then prefix, then the rest — and grouped by category, so
searching toolbox reads as 8 props and 1 animation dictionary, not nine
undifferentiated rows.
No loading spinner. No pagination. Scroll as far as you like.
Preview in the world, not in a thumbnail
The interface sits down the sides of your screen on purpose: the middle is where the preview goes.
Props and vehicles spawn on the ground in front of you, frozen and collision-free, rotatable and zoomable, swapping instantly as you arrow through results. Previewing a ped turns you into it — arrow down the list and you change character every keypress, which is how you actually judge a model. Your own character is captured first and handed straight back when you stop. Animations and scenarios play on a mannequin — or on your own ped. Weapons are held, not dropped in the grass. Particle effects fire at a marked point. Timecycle filters apply live and revert on stop. Clothing cycles on a freemode mannequin. Handling profiles put you in the driver's seat of a car that actually uses them. Waypoint routes are drawn across the map.
Only you see it. Previews are local and hidden from the network unless you
deliberately enable the visible-preview flag for collaborative scene work. The
one exception is a ped preview, which changes your own character and is
therefore visible to everyone, as any model change is —
Config.Preview.PedsOnSelf = false puts it back to a separate figure standing
in front of you.
Closing the panel leaves the preview standing, so you can walk around it.
33,912 places, sorted by how far away they are
Every ATM, gas pump, vending machine, bus stop, jukebox, dartboard, telescope, oil jack and park bench in Los Santos, at its real coordinate, pulled from Rockstar's own placement data. Open World Locations, pick a group, and the list is ordered nearest you first, each entry naming the map zone it sits in — 121 ATMs, 157 gas pumps, 345 vending machines, 48 bus stops, 6 jukeboxes. Press Enter and you are standing at it, in your car if you were driving.
This is the part you cannot get from a wiki: building a fuel script, a robbery
script or a jukebox script means sourcing those coordinates by hand, one
screenshot at a time. /gdb waypoint takes you to any pin you drop on the map,
and /gdb back returns you to where you started.
Code examples that actually run
42 of the 46 categories ship a minimal, self-contained Lua example with the real names already filled in — load-and-play for an animation, create-and-place for a prop, asset-and-start for an effect. The other four are flag and reference sets that no native takes by name, and the entry says so instead of inventing one.
These are verified, not assumed. Before release, every native call in every template is checked against 6,089 signatures from the official CitizenFX documentation, then each filled snippet is compiled and executed. Five deliberately broken snippets are kept in the build to prove the check still fails when it should.
Pick entries as you go, favourite the ones you keep returning to.
Leak-proof, by design
Every preview journals what it touched — entities, streamed models, animation dictionaries, particle handles, weapon assets, IPLs, pinned interiors, waypoint recordings, audio banks, screen effects, world toggles, and your own character down to its clothing, head blend and face features — and reverts all of it when you switch entries, hit Stop all, disconnect, or stop the resource.
/gdb debug shows that journal live, so you can watch it return to zero rather
than take our word for it.
Built to fit
- Standalone. ESX, QBCore and QBox are detected automatically and never required. No database.
- 0.00 ms when the browser is closed and nothing is previewing.
- Two permission levels, so juniors can browse props while weapons, explosions and world edits stay locked. Permissions are decided server-side, and everything that leaves the machine is re-checked on arrival.
- Every category can be switched off in config and vanishes from the GUI.
- Recolour it from config to match your own branding, no CSS editing.
- Scales to your screen — 1366×768 through 4K.
- Fully keyboard-operable, with a visible focus ring on every control.
- Open source. No escrow, no obfuscation, no fxap. Read every line.
- A documented query interface so your own scripts can search the same index.
- Rebuildable. When a new GTA V build lands, the distillation tooling ships with the resource.
Feature bullets
- 453,562 asset names across 46 categories, searchable instantly in game
- 41 categories preview in the world; the other five say so up front
- 33,912 real world positions on top of those — ATMs, gas pumps, bus stops, jukeboxes — reached by picking their group and listed nearest you first, with the map zone each one stands in
- One-click preview with rotate, zoom and instant result swapping
- A verified copy-ready Lua example for 42 of the 46 categories
- Picks, favourites and a live activity timeline
- Panic stop that clears every preview, effect and filter server-wide
- Live debug overlay and an AI-ready diagnostic report command
- Demo tour mode for recording your own trailer
- Standalone with automatic ESX / QBCore / QBox detection
- Open source, no escrow
Suggested trailer shots
/gdb demo tour is a single-take scripted sequence built for exactly this.
- Cold open. Standing in an empty lot.
/gdb— the panels fade in, the dusk gradient catching the top edge. Two seconds, no narration. - The promise, in one shot. Type
toolboxletter by letter; the count falls from 102,942 to 9 as the fingers move. Press Enter. The prop appears in the empty centre of the screen. - Flipping pages. Hold the down arrow through the props category — a new prop in the world every frame, like flipping a catalogue. This is the shot that sells the product.
- The snippet. Cut to the detail pane, press
Alt+C. Overlay: "pasted straight into a fresh resource — it runs." Then show it running. - Scale montage. Vehicles (a supercar drops in), Peds (you become each one as you arrow down), Animations (a mannequin starts dancing), Particles (fire erupts), Timecycles (the world turns amber).
- Clothing cycle. Arrow through ped components; the mannequin changes outfit each keypress.
- The panic. Several effects running, screen filter on, particles going.
Press
Delete. Everything stops in one frame. Cut to/gdb debugshowing the journal at zero. - Close. Wordmark on black with the dusk gradient. "Game Data Browser — LastResort Development."
Record at 1080p or higher; the GUI scales with the screen and stays legible when downscaled for a store page.
Tags
fivem developer tools admin props animations particle effects
standalone esx qbcore qbox open source data browser
Suggested price band
Developer tooling with a one-off install and no per-player runtime cost. Price against admin and developer utilities rather than gameplay scripts.
Support notes for the listing
- Requires OneSync. No database, no dependencies.
- Ships with the ACE lines a buyer needs to paste into
server.cfg. /gdb reportproduces a self-contained diagnostic file; asking for that file answers most support questions in one round.
TESTING — lastresort_gamedata
Each item is a command plus the observable result it must produce. Everything runs with default config and no arguments.
M0 — Build verification
M0 ships no runtime code, so its checklist verifies the build pipeline and the data it produces. Run from the resource root.
1. Acquire the reference data
./tools/fetch_dumps.sh
Expected: build-refs/dumps, build-refs/natives and build-refs/fivem
exist. build-refs/dumps contains no assets/, objectslocations/,
nodes.zip or ps3-builds.xml — those are deliberately not checked out.
2. Build the native signature index
python3 tools/native_index.py --natives build-refs/natives --cfx build-refs/fivem/ext/native-decls --out tools/native_index.json
Expected: 6049 natives indexed (±, as CitizenFX documents more), and
tools/native_enums.json: eExplosionTag (85). The command exits non-zero if
fewer than 5000 natives parse, which means the clones are incomplete.
3. Distill the indexes
python3 tools/distill.py --dumps build-refs/dumps --out data/index --enums tools/native_enums.json
Expected, per the shipped build:
- 45 categories, no category reporting
0 entries— World Locations is the 46th and is written by the next step total 12248035 B raw, 1567622 B gzipped- the warning
11 explosion tags have no documented eExplosionTag value animclips 269414 entriesacross 23 shards
3b. Build the World Locations index
python3 tools/locations.py build-refs/dumps data/index
Expected:
locations 34 groups 2827 B 1442 B gzlocationplaces 33912 entries 1211789 B (34 shards, loaded on demand)skipped empty dumps: worldExtraVendingMachines- a
+zoneline for each ofipls(892/895 named),interiors(375/385),garages(32/32) andstaticemitters(908/930) total 13471752 B raw, 2003949 B gzipped, across 46 categories
Re-running it is a no-op: the zone columns are added only once, and a second run leaves every file byte-identical.
4. Prove the coverage matrix is exhaustive
python3 tools/coverage.py --dumps build-refs/dumps --index data/index
Expected: exits 0, ends with a 215 paths classified: … line, and confirms
all 46 shipped categories are wired into shared/categories.lua.
Exits non-zero if the upstream repository gained a file with no verdict, or if a shipped category has no dump mapped to it.
5. Verify every snippet
python3 tools/verify_snippets.py --index tools/native_index.json
Expected: exits 0, ending with
42 templates, 0 failing
46 shipped categories: 42 with snippets, 4 documented as snippet-less
6. Prove the verifier actually fails
The check above is only worth trusting if it rejects bad input. Each of these must be reported, and each must make the command exit non-zero:
| Break this | Expected report |
|---|---|
| rename a native in any template to a non-existent one | unknown native <name> |
drop arguments from a TaskPlayAnim call |
called with N arguments, signature TASK_PLAY_ANIM accepts 11 |
delete the = from a local x = line |
lua syntax: unexpected symbol near ... |
| concatenate an undeclared variable | attempt to concatenate a nil value |
remove the Wait(0) from a load loop |
did not terminate within 30s; a loop is missing its Wait |
mv data/snippets/zones.lua /tmp/ |
categories with neither a snippet nor a NO_SNIPPET reason: zones |
Restore the file afterwards and confirm the command exits 0 again.
7. Confirm the runtime tables agree
python3 tools/check_natives.py --index tools/native_index.json
lua5.4 tools/check_defaults.lua
Expected: 0 unknown native calls across the resource's own Lua, and
defaults.lua and categories.lua agree. Both exit 0; the second fails if a
category is added to shared/categories.lua without a default, which is how a
new category silently vanishes on a server that kept its own config.lua.
8. Confirm the distilled data round-trips
python3 - <<'EOF'
import json, os
index = "data/index"
manifest = json.load(open(os.path.join(index, "manifest.json")))
source = {d["DictionaryName"]: d["Animations"]
for d in json.load(open("build-refs/dumps/animDictsCompact.json"))}
total = 0
for shard in manifest["clipShards"]:
for name, clips in json.load(open(f"{index}/clips/{shard}.json")).items():
assert source[name] == clips, name
total += len(clips)
print("clip shards round-trip exactly:", total)
EOF
Expected: clip shards round-trip exactly: 269414.
9. Run the unit tests
for t in tests/*.test.lua; do lua5.4 "$t"; done
Expected: four files, 46 assertions, none failing. They cover the notification fallback, the permission ladder, preview supersede and cleanup, and ground placement per entity type.
M1–M3 — In-game checklist
Run with default config on a bare server. Grant yourself both ACE permissions
first (see INSTALLATION.md).
Opening and search
| # | Do this | Expect |
|---|---|---|
| 1 | /gdb |
the browser opens, the cursor appears, and a curated "Start here" list is shown |
| 2 | Type toolbox |
the count falls to single digits within one keystroke, no stutter |
| 3 | Press ↓ then ↑ |
selection moves, the detail pane follows, the name is the largest thing on screen |
| 4 | Open the Categories tab and click Vehicles |
the scope chip appears, the count becomes 921 |
| 5 | Click the chip's × |
scope clears, the count returns to 102,942 |
| 6 | Esc |
the browser closes and the cursor is released |
| 7 | /gdb again |
it reopens where you left off |
| 8 | /gdb find adder |
opens already searching, adder selected |
Preview and cleanup
| # | Do this | Expect |
|---|---|---|
| 9 | Select any prop, Enter |
it appears in front of you, frozen, no collision |
| 10 | Hold ↓ through several props |
each replaces the last; never two at once |
| 11 | Click rotate and zoom | the preview turns and moves; nothing is left behind |
| 12 | Select a vehicle, Enter |
it spawns settled on the ground, doors locked |
| 13 | Select a ped, Enter |
a ped spawns facing you, frozen, not reacting |
| 14 | Animation Dictionaries → pick a dictionary → pick a clip → Enter |
the mannequin plays the clip on a loop |
| 15 | Pick a clip that is not in the dictionary | a clear message, no silent failure, no stuck mannequin |
| 16 | Particle Effects → Enter |
the effect plays at the marked point |
| 17 | Timecycle Modifiers → Enter |
the screen filter applies immediately |
| 18 | Esc while the filter is on |
the browser closes and the filter stays, so you can look at it |
| 19 | Press Delete or run /gdb stopall |
filter reverts, world returns to normal |
| 20 | /gdb debug |
overlay shows journal 0 tracked and active none |
World locations and teleporting
| # | Do this | Expect |
|---|---|---|
| L1 | Search atms, Enter |
the screen fades and you are standing at the nearest ATM |
| L2 | Look at the detail pane | a Nearest list, first entry the smallest distance, each labelled with its map zone |
| L3 | Click the third chip, Enter |
you move to that one, not the first |
| L4 | Search seats, select it |
the chip header reads 300 of 8,065, not 8,065 |
| L5 | Get in a car, then preview any location | the car comes with you and lands on the ground, not in it |
| L6 | Preview a location on Mount Chiliad, on foot | you land on the mountain, not inside it |
| L7 | /gdb back |
you return to where the first preview took you from, facing the way you were |
| L8 | /gdb back again |
"Nothing to go back to", no teleport |
| L9 | Drop a map waypoint, /gdb waypoint |
you are standing on it, on the ground |
| L10 | /gdb waypoint with no waypoint set |
"Set a waypoint on the map first", no teleport |
| L11 | Preview a location, then Delete |
you are back where you started, with your vehicle |
| L12 | Select any IPL, interior, garage or static emitter | the detail pane lists a zone naming the part of the map it sits in |
The panic stop
| # | Do this | Expect |
|---|---|---|
| 20 | Start a particle effect, then a timecycle filter, then a ped preview | all three active |
| 21 | Press Delete (or /gdb stopall) |
everything stops in one frame |
| 22 | /gdb debug |
journal 0 tracked, active none — no residue |
| 23 | Start a preview, then restart lastresort_gamedata from the console |
nothing is left in the world, no stuck cursor |
| 24 | Start a preview, then disconnect and rejoin | nothing is left in the world |
Snippets
| # | Do this | Expect |
|---|---|---|
| 25 | Select a prop, press C |
"Snippet copied." |
| 25b | Take three entries with T, open the Picks tab, remove one, then clear the list |
each removal is immediate and the list empties |
| 26 | Paste into a fresh empty resource's client script and start it | the prop spawns, then deletes itself after ten seconds |
| 27 | Repeat for a vehicle, a ped, an animation, a particle effect and a timecycle modifier | each runs exactly as pasted |
| 28 | Press T on several entries, then Export picks |
the snippet pane holds every pick, each labelled |
Permissions
| # | Do this | Expect |
|---|---|---|
| 29 | Remove lastresort_gamedata.elevated, reconnect, /gdb |
Weapons, Explosion Types, IPLs and MLO Interiors appear dimmed and cannot be previewed |
| 30 | Remove lastresort_gamedata.browse, reconnect, /gdb |
nothing happens beyond a refusal message |
| 31 | Set Config.Categories.particles = false, restart |
Particle Effects is gone from the rail entirely, not merely greyed |
Demo, report and siblings
| # | Do this | Expect |
|---|---|---|
| 32 | /gdb demo tour |
a scripted sequence runs across categories and cleans up at the end |
| 33 | /gdb stopall mid-tour |
the tour ends immediately and the world is clean |
| 34 | /gdb report |
a path is printed; the file names the version, framework, siblings, non-default config, live state and recent log |
| 35 | Start lastresort_notify alongside it |
notifications route through it instead of the GTA feed |
| 36 | Run with no sibling installed | everything still works; notifications use the built-in feed |
Performance
| # | Do this | Expect |
|---|---|---|
| 37 | resmon 1 with the browser closed and nothing previewing |
0.00 ms |
| 38 | Open the browser and search continuously | no frame drops while typing |
Changelog
2026-09-02
- 1.1.0: World Locations, and the engine's own teleport.
2026-08-22
- Make Config.Keybind.Open actually move the key, and open the ACE gate.
- Document that the keybind default is only a default.
2026-08-17
- 1.0.2: ped previews become you; fix the model-swap frame.
- Stop the black boxes, scale with the screen, and stop typing from walking.
- Three defects from the adversarial review, and tests that hold them.
- Remember a broken notification provider, and index the CFX natives we were missing.
- Two ways past ACE, and move the keybind off F7.
2026-08-11
- Initial release with one searchable browser for GTA models, animations, effects, interiors, audio, and world data.
- Added ranked global search with grouped results and on-demand loading for large animation and speech datasets.
- Added live previews for props, vehicles, peds, weapons, animations, particles, timecycles, interiors, zones, and audio.
- Added verified, copy-ready Lua examples for supported categories.
- Added session history, persistent admin favorites, and server-wide preview cleanup.
- Added
/gdb stopall,/gdb debug,/gdb demo, and/gdb reporttools. - Added client and server exports for search, lookup, category data, snippets, and browser control.
- Added automatic ESX, QBCore, QBox, notification, and sibling-resource detection.
- Added ACE, identifier allowlist, and separate elevated permissions.
- Added keyboard navigation, theme configuration, rate limits, and validation for client payloads.
- v1.1.0Latest
- 1.1.0: World Locations, and the engine's own teleport.
Must have tool for every FiveM developer! Easy to use!
Hi everyone! My next big script is made for developers, for faster and more detailed server development. You press F10 (or whatever key/command you set) and you can instantly search locations, effects, animations, sounds, props, vehicles, clothes — 453,528 assets with detailed data. Build your server from native GTA content: it’s already in the game, it doesn’t eat extra resources, and it’s what enriches the gameplay the most!
- 453,528 asset names in 45 categories, instant in-game search
- Live preview in the world for 40 categories — rotate, zoom, instant swap as you move through the results
- You see the code right away: Alt+C copies working Lua code with the real names already filled in (41 categories, verified against 6,089 native signatures from the official CitizenFX docs)
- Pick list + favorites + Lua export for your current project, no database needed
- Full reset with one key — you don’t litter while testing
- Standalone, auto-detects ESX / QBCore / QBox, 0.00 ms while closed
- Two permission levels with server-side checks
- Built-in LastResort Notify integration (ox_lib and chat fallback)
- Full, unencrypted source — no escrow, no obfuscation, no fxap
Commands in short: F10 open · Enter preview · Alt+C copy code · Alt+T pick list · Alt+F favorites · Delete full reset · more /gdb commands in the docs
Requirements: OneSync. No database and no dependencies needed (lastresort_notify is optional).
What you get
- The full source code. Every Lua, config and UI file, readable and editable. Rename it, restyle it or hook your own systems into it.
- No escrow, no license checks. No key and nothing that phones home. It keeps running as long as your server does.
- Free updates. New versions land in your account for as long as we maintain the script. Download the latest one whenever you like.
- One community per purchase. Use it on that community's live, development and test servers. Reselling or re-uploading the code is not allowed.
Get Game Data Browser – Must have tool for every FiveM developer – search & live-preview 453,528 assets
€19.90, paid once through Stripe. The download is in your account right after payment.
