Lumo Emotes
Emote menu, animation studio and body-language toolkit with about 5,000 animations.
Version 1.0.3 · Frameworks QBCore · Qbox · ESX · standalone
Config files · Exports & events · Changelog
Emote menu, animation studio and body-language toolkit for FiveM. One resource, ~5,000 animations, works on QBCore, Qbox, ESX and standalone with no hard dependency.
The UI is React + TypeScript in the Lumo field-terminal style — near-black panels, lime accent, hairline dividers, viewfinder brackets, Barlow type.
Licence: see LICENSE.txt and Credits and licence at the end. The animation tables in shared/animations/ are GPL-3.0 and always stay readable.
1. What's in it
| ~5,000 animations | emotes, prop emotes, dances, paired emotes, in-vehicle, animal, walk styles, expressions, weapon styles |
| Prop + particle emotes | multi-prop attachment with per-bone offsets, looped and one-shot particle effects |
| Paired emotes | request the nearest player (or pick one from the list); on accept both halves play with the partner attached so they line up |
| Aim-and-place | drop any emote anywhere — aim to position, arrows to nudge, scroll to rotate, Z for height, E to commit |
| Hover previews | the emote plays on a network-invisible clone of your character beside the menu — animal emotes preview on a dog, in-vehicle emotes preview seated in a copy of whatever you are driving |
| Favourites wheel | hold a key, point, release |
| Quick slots | drag an emote onto a slot, bind the key in FiveM's own settings |
| Emote creator | two-ped studio with a free camera that writes ready-to-paste animation tables |
Prop tuner (/animpos) | nudge a live prop into place and generate the offsets |
| Body language | pointing, hands up, ragdoll, crouch, crawl, sit on any chair, optional holstering and idle animations |
| Per-character memory | favourites, quick slots, walk, expression and weapon style are saved to the database and follow the character |
2. Installing
- Put the
lumo-emotesfolder in yourresources/folder. - Add it to
server.cfgafter your framework and oxmysql:
cfg
ensure oxmysql
ensure qb-core # or qbx_core / es_extended / nothing
ensure lumo-emotesThat's it. No SQL to import, nothing to configure for your framework.
No hard dependencies — the resource starts with none of these present. Optional, detected at runtime:
- A framework —
qbx_core,qb-coreores_extendedis picked up automatically (force one withConfig.Framework). Profiles are keyed per character, so two characters keep separate favourites, and messages use the framework's own notifications. Standalone servers key the profile on the Rockstar licence and use ox_lib's notify or the menu's built-in toast. - oxmysql — persists favourites, quick slots, walk style, expression and weapon style. The table
lumo_emotes_profilesis created automatically on first start. Without oxmysql the profile falls back to local storage, which is per-machine but still survives restarts. - qb-target or ox_target — needed by the "sit on any chair" module (force one with
Config.Target). - lumo-ui — if you run it, the menu follows its accent colour and Classic/Circle preset.
All framework code lives in framework/client.lua and framework/server.lua. If you run a custom core, those two short files are the only ones to adapt.
Which parts follow the character rather than the account is set by Config.CharacterSpecific.
Stop any other emote resource first so the keybinds don't fight.
3. Controls
| Action | Default | Notes |
|---|---|---|
| Open / close menu | F3 | or /emotemenu |
| Cancel emote | X | or /emotestop — also stands you up out of a crawl or crouch |
| Favourites wheel | hold Z | release over an entry to play it |
| Point finger | B | |
| Hands up | off | Config.Modules.Handsup; most frameworks already ship one |
| Ragdoll | unbound | bind it yourself — see below |
| Crouch | unbound | bind it yourself — see below |
| Crawl | unbound | bind it yourself; press again to roll onto your back |
| Quick slots 1–7 | unbound | bind in Settings › Key Bindings › FiveM |
| Dance speed | Page Up / Page Down | on anything tagged speed; the menu shows a speed control while one plays |
| Trigger effect | E | on anything tagged fx |
Every one of these is rebindable in FiveM's key-binding settings; the values in config.lua are only the defaults offered the first time.
Ragdoll, crouch and crawl ship unbound on purpose. Whatever default they were given collided with something — crawl on Left Shift meant sprinting dropped you onto your face, and ragdoll on Z fought the emote wheel. Bind them to keys that are free on your server under Settings › Key Bindings › FiveM.
FiveM saves a keybind the first time it sees a command name and never re-reads the default afterwards, so changing
Config.ModuleKeysdoes nothing for a player who has already joined. Rename the command if you need to push a new default to everyone.
If another resource already owns X (qb-smallresources' hands-up, for example), set Config.CancelEmote = false and have that resource call exports['lumo-emotes']:CancelIfActive() first: it returns true when it stopped an emote, crouch or gesture.
Commands
/e <name> play anything by id or by its menu name
/e open the menu
/e c stop
/emoteplace <name> go straight into aim-and-place with that emote
/emotestop stop
/walkreset clear your walk style (or use Reset in the menu's settings)
/expressionreset clear your expression
/animpos tune the props on the emote you're playing
/emotecreator open the creator studio/emote, /dance, /walk, /expression and /sync are aliases for /e — they all search everything.
4. Adding animations
Animation tables live in shared/animations/ and use the RPEmotes table shape, so anything written for dpemotes or rpemotes drops in unchanged.
lua
-- shared/animations/emotes.lua
["myemote"] = {
"anim@amb@nightclub@lazlow@ig1_vip@", -- dictionary
"clubvip_base_laz", -- clip
"My Emote", -- menu label
animationOptions = {
emoteLoop = true,
emoteMoving = false,
prop = "prop_cs_beer_bot_01",
propBone = 60309,
propPlacement = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
}
},A scenario instead of a clip:
lua
["atm"] = { "scenario", "PROP_HUMAN_ATM", "ATM" },Option keys are read case-insensitively (emoteLoop and EmoteLoop both work), because packs in the wild are inconsistent about it. shared/registry.lua normalises everything into one shape before anything else sees it.
Streamed packs
shared/animations/creators/ holds pack files that only register themselves when their entry in Config.Creators is true. Put the pack's .ycd/.ydr/.ytd files in a stream/ folder, its rows in a creators/<Name>.lua file, then add ['<Name>'] = true to Config.Creators. Turn one on only once the matching files are actually streaming, or the emote will silently do nothing. A pack file is plain Lua that starts with
lua
if not (Config.Creators and Config.Creators['MyPack']) then return endand then adds rows to Config.Props, Config.Custom.Dances and so on.
The creator studio
/emotecreator spawns a ped and a free camera. Pick Solo or Two people at the top, then either search the catalogue to load an existing animation as a starting point — usually the fastest route — or type a dictionary and clip directly. Attach props and particles, drag to orbit, scroll to zoom, and hit Generate: the panel and the F8 console both get a block you can paste straight into an animation file. In Two people mode the second ped appears and the Pairing tab carries the attachment offsets, which are written into the generated pair.
Placing an emote
Click the pin on any emote card (or right-click it and choose Place in the world, or run /emoteplace <name>). A translucent copy of your character follows wherever you aim:
| aim | coarse position — it lands on whatever surface you point at |
| arrow keys | nudge the spot forward / back / left / right |
| scroll | rotate (or raise / lower in height mode) |
| Z | swap scroll between rotate and height |
| Ctrl (hold) | fine steps on everything |
| E | commit |
| X | back out |
That combination is what lets you land exactly on a bench edge or a ledge rather than near it.
The prop tuner
Play a prop emote, run /animpos, then nudge with the arrow keys (X/Y), Page Up/Down (Z) and the numpad (rotation). Hold Shift for fine steps, Tab to switch to the second prop, Enter to print the offsets, Backspace to leave.
5. Rebuilding the UI
Open-source edition only — the escrow edition ships the compiled UI without nui/.
bash
cd nui
npm install # only needed once
npm run build # writes html/dist/npm run dev serves the UI in a browser with mock data (src/dev-mock.ts) so layout work doesn't need the game running.
6. For other resources
lua
exports['lumo-emotes']:play('wave')
exports['lumo-emotes']:stop()
exports['lumo-emotes']:isPlaying()
exports['lumo-emotes']:current() -- id of the running emote, or nil
exports['lumo-emotes']:openMenu()
exports['lumo-emotes']:list() -- the full cataloguelua
TriggerClientEvent('lumo-emotes:play', src, 'wave')
TriggerClientEvent('lumo-emotes:stop', src)
TriggerClientEvent('lumo-emotes:openMenu', src)7. Layout
config.lua every toggle, key default and category
framework/ the only files that talk to QBCore / Qbox / ESX / targets
shared/
bones.lua attachment bones offered in the creator
registry.lua folds all tables into one normalised registry
animations/ RPEmotes-shaped animation data
creators/ streamed packs, gated by Config.Creators
client/
util.lua NUI bridge, notifications, ped helpers
hud_link.lua optional lumo-ui theme relay
main.lua menu state, commands, NUI callbacks, exports
modules/
player.lua the animation engine (props, particles, watcher)
storage.lua per-character profile
appearance.lua walk / expression / weapon style
preview.lua hover preview clone
place.lua aim-and-place
shared_emotes.lua paired emotes
animpos.lua live prop tuner
creator.lua the two-ped studio
binds.lua quick slots, wheel, speed, effect trigger
gestures.lua pointing, hands up, ragdoll
stance.lua crouch, crawl
tweaks.lua holstering, idles, leaning, combat roll
sitanychair.lua target integration
server/main.lua profile persistence, paired-emote relay
nui/ React + TypeScript source
html/dist/ built UI8. Credits and licence
- Both release editions include
stream/and every creator pack definition.Lumo_AnimPropsis enabled with its matching animations, models, textures and YTYP. Other creator packs remain configurable; enable one only when its matching stream files are present. The open-source edition also leaves streamed models unencrypted. - Streamed assets — including the Bablo / SasDragon pack renamed to the
lumonamespace — retain their original creators' rights. The edition licence covers Lumo's code and UI; it does not replace any streamed asset's licence. - Lumo's work — the emote engine, paired-emote sync, creator studio, placement, previews,
framework/and the React UI — is covered byLICENSE.txt(the escrow or open-source licence of the edition you bought). - Animation data — the tables in
shared/animations/are based on rpemotes-reborn and dpemotes, whose authors and contributors collected and tuned them. They are licensed under the GNU General Public License v3.0 (shared/animations/LICENSE), are never encrypted, and you may use, change and share them under the GPL's terms. - Fonts: Barlow Condensed, Barlow Semi Condensed and Oxanium (SIL Open Font License,
nui/src/fonts/).