vMenu Docs
Plugins

Lua setup

Setting up a vMenu Enhanced plugin in Lua: the vmenu.lua file, the manifest and what differs from C#.

The Lua plugin API is one file, vmenu.lua. The rest of the API is on Making a plugin. The Lua example is a complete resource to copy.

Getting the file

Every vMenu Enhanced zip on the releases page has a plugin-api folder with vmenu.lua in it. Take the one from the vMenu version your server runs and copy it into your resource. Its first line says which vMenu version it was built for.

Your resource ships its own copy, so it never loads anything from vMenu's folder, and start order does not matter. Replace the file when you update vMenu.

Manifest

Load it as a shared script, before your own scripts. It gives both halves a global vMenu table.

fx_version 'cerulean'
games { 'gta5' }

shared_script 'vmenu.lua'
client_script 'client.lua'
server_script 'server.lua'

Things specific to Lua

TopicDetail
Entry pointsvMenu.CreatePlugin(name) on the client. vMenu.ServerPluginDeclaration(name) and vMenu.Server.Register(declaration) on the server.
PropertiesThings that never change are fields, such as row.Id, submenu.Menu and plugin.RootMenu. Everything else is a pair of Get and Set methods, such as row:GetText() and row:SetText(x).
OptionsOptional arguments go in a table with the C# names: menu:AddCheckbox('Music', { Id = 'music', Checked = true, Persist = true, Description = '...' }).
Eventsrow:OnSelected(fn), menu:OnOpened(fn) and so on. Each returns a function that unsubscribes. A handler that errors is logged and the others still run.
PositionsCounted from 1, everywhere: list indexes, InsertAt, Move and OnIndexChanged.
TextA plain string is a literal. vMenu.Text.Key('greet', { name = 'world' }) for a translation key.
GatesvMenu.Gate.Permission and vMenu.Gate.Setting, combined with & and |, or vMenu.Gate.All and vMenu.Gate.Any. A plain string is a permission gate.
Settingssetting:GetValue() reads the convar.
Batchesplugin:Batch(function() ... end)
Inserting rowsmenu:InsertAt(3, function() ... end)
Notificationsplugin:Notify('success', text), with info, success, warning or error.
PlayersA player action hands your handler { ServerId, Name }.

Waiting for vMenu

plugin:Connect(), plugin:GetText(), plugin:GetTexts(), menu:RequestOpen(), menu:RequestOpenWithPriority() and vMenu.Server.Register() wait for vMenu to answer, so they have to run inside a thread:

CreateThread(function()
    local result = plugin:Connect()
    print(result.Accepted)
end)

Menu event handlers such as OnSelected already run in a thread of their own, so you can call GetText in one directly. If you would rather not wait at all, pass a callback as the last argument and the call returns straight away:

plugin:Connect(function(result)
    print(result.Accepted)
end)

Calling one of these outside a thread without a callback is an error that tells you exactly that.

Requirements

Lua 5.4, which FiveM runs by default. The & and | on gates are Lua 5.4 operators.

On this page