VORP Menu System Documentation
VORP Menu is a library that allows you to create menus in-game with an RDR2 style interface. This documentation covers the complete menu system for developers.
Table of Contents
- Getting Started
- Menu Elements
- Menu Configuration
- Menu Functions
- Runtime Menu Management
- Complete Menu Example
Getting Started > Get Menu Data
Add this to the top of your client scripts to get the menu data setters and getters:
local Menu = exports.vorp_menu:GetMenuData()
Returns: The menu data object containing all menu functions and properties.
Getting Started > Close All Menus
Close all currently open menus:
MenuData.CloseAll()
Menu Elements
Menu elements are the components that will be displayed in the menu. Different element types provide various interaction methods.
Menu Elements > Basic Element Structure
local MenuElements = {
{
label = "name", -- Display name
value = "value", -- Element value
desc = "description" -- Element description
}
}
Menu Elements > Slider Element
Create slider elements for numeric input with min/max values:
local MenuElements = {
{
label = "name",
value = 0, -- Current slider value
desc = "description",
type = "slider", -- Element type
min = 0, -- Minimum value (can be float)
max = 10, -- Maximum value (can be float)
hop = 1 -- Step/increment value
}
}
Properties:
type- Must be "slider" for slider elementsmin- Minimum value (supports floats)max- Maximum value (supports floats)hop- Step value for increments
Menu Elements > Advanced Element with Custom Properties
local MenuElements = {
{
label = "name",
value = "value",
desc = "description",
itemHeight = "4vh", -- Custom height for this element
any = any, -- Custom property (any value type)
table = { -- Nested table data
string = "string",
number = 111,
table = table,
}
}
}
Custom Properties:
itemHeight- Override default element heightany- Any custom value (string, number, table, array, etc.)table- Nested table within element for complex data
Menu Configuration > Menu Information Object
local MenuInfo = {
title = "menu title", -- Menu title
subtext = "menu sub text", -- Menu subtitle
align = "top-right", -- Menu alignment
elements = MenuElements, -- Menu elements array
lastmenu = "function", -- Previous menu function name (optional)
itemHeight = "4vh" -- Default height for all elements (optional)
}
Configuration Properties:
title- The title displayed at the top of the menusubtext- Subtitle text below the titlealign- Menu position: "top-right", "top-center", "top-left"elements- Array of menu elementslastmenu- Function name for returning to previous menu (optional)itemHeight- Default height applied to all elements if not defined individually (optional)
Menu Functions > Opening a Menu
Menu.Open("default", GetCurrentResourceName(), "OpenMenu", MenuInfo,
function(data, menu)
-- Selection callback
end,
function(data, menu)
-- Close/back callback
end
)
Parameters:
"default"- Menu typeGetCurrentResourceName()- Resource name"OpenMenu"- Unique namespace (allows menu to remember position)MenuInfo- Menu configuration objectfunction(data, menu)- Selection callback functionfunction(data, menu)- Close/back callback function
Menu Functions > Selection Callback Data
function(data, menu)
print("current key of MenuElements is " .. data.current.index)
print("current value of MenuElements is " .. data.current.value)
-- Access custom element properties
if data.current.any then
print("Custom property:", data.current.any)
end
-- Handle back button
if (data.current == "backup") then
return _G[data.trigger](any, any) -- Call previous menu function
end
-- Handle specific values
if data.current.value == "value" then
return
end
if data.current.info == "param" then
return menu.close()
end
end
Runtime Menu Management > Add New Element
Add elements to the current menu during runtime:
menu.addNewElement({
label = "label",
value = "open",
desc = "description"
})
-- Refresh menu to show new element
menu.refresh()
Parameters:
label- The display label of the elementvalue- The value of the elementdesc- The description of the element
Runtime Menu Management > Find Elements
Retrieve elements by value or index:
local element = menu.getElementByValue(value)
local element = menu.getElementByIndex(index)
Parameters:
value- Element value to search forindex- Element index to retrieve
Returns: Element object if found
Runtime Menu Management > Update Element
Update specific element properties:
menu.setElement(index, variable, newValue)
-- Refresh menu to show changes
menu.refresh()
Parameters:
index- The index of the menu element to updatevariable- The property to update (label, value, desc, or any custom property)newValue- The new value for the property
Runtime Menu Management > Remove Elements
Remove elements by index or value:
menu.removeElementByIndex(index, loop)
menu.removeElementByValue(value, loop)
-- Refresh menu to show changes
menu.refresh()
Parameters:
index- Element index to removevalue- Element value to removeloop- Stop at first match (false) or continue searching (true)
Runtime Menu Management > Menu Control Functions
menu.close() -- Close current menu
menu.setTitle("title") -- Set menu title
menu.refresh() -- Refresh menu display
Complete Menu Example
function OpenMenu()
Menu.CloseAll()
local MenuElements = {
{
label = "Basic Item",
value = "basic",
desc = "A basic menu item"
},
{
label = "Volume Slider",
value = 50,
desc = "Adjust volume level",
type = "slider",
min = 0,
max = 100,
hop = 5
},
{
label = "Custom Height Item",
value = "custom",
desc = "Item with custom height",
itemHeight = "6vh"
},
{
label = "Advanced Item",
value = "advanced",
desc = "Item with custom data",
customData = "example",
settings = {
enabled = true,
priority = 1,
options = {"option1", "option2"}
}
}
}
Menu.Open("default", GetCurrentResourceName(), "OpenMenu",
{
title = "Example Menu",
subtext = "Choose an option",
align = "top-right",
elements = MenuElements,
lastmenu = nil,
itemHeight = "4vh"
},
function(data, menu)
print("Selected index: " .. data.current.index)
print("Selected value: " .. data.current.value)
-- Handle back button
if (data.current == "backup") then
return menu.close()
end
-- Handle different menu items
if data.current.value == "basic" then
print("Basic item selected")
-- Add new element dynamically
menu.addNewElement({
label = "New Item",
value = "new",
desc = "Dynamically added item"
})
menu.refresh()
elseif data.current.value == "custom" then
print("Custom item selected")
-- Update menu title
menu.setTitle("Updated Menu")
menu.refresh()
elseif data.current.value == "advanced" then
print("Advanced item selected")
print("Custom data: " .. data.current.customData)
print("Settings: " .. json.encode(data.current.settings))
elseif data.current.value == "new" then
print("New item selected")
-- Remove this element
menu.removeElementByValue("new")
menu.refresh()
elseif data.current.type == "slider" then
print("Slider value: " .. data.current.value)
-- Handle slider value change
end
end,
function(data, menu)
-- Handle menu close/back
print("Menu closed or back pressed")
menu.close()
end
)
end
-- Example usage
RegisterCommand("openmenu", function()
OpenMenu()
end)
Complete Menu Example > Dynamic Menu Management Example
function CreateDynamicMenu()
Menu.CloseAll()
local MenuElements = {
{
label = "Add Item",
value = "add",
desc = "Add a new menu item"
},
{
label = "Remove Item",
value = "remove",
desc = "Remove the last item"
}
}
Menu.Open("default", GetCurrentResourceName(), "DynamicMenu",
{
title = "Dynamic Menu",
subtext = "Manage menu items",
align = "top-center",
elements = MenuElements
},
function(data, menu)
if data.current.value == "add" then
local itemCount = #menu.getElements() + 1
menu.addNewElement({
label = "Dynamic Item " .. itemCount,
value = "dynamic_" .. itemCount,
desc = "Dynamically created item"
})
menu.refresh()
elseif data.current.value == "remove" then
local elements = menu.getElements()
if #elements > 2 then -- Keep original add/remove buttons
menu.removeElementByIndex(#elements)
menu.refresh()
end
elseif string.match(data.current.value, "dynamic_") then
print("Selected dynamic item: " .. data.current.label)
end
end,
function(data, menu)
menu.close()
end
)
end
Best Practices > Menu Organization
- Use Descriptive Labels: Make menu items clear and understandable
- Logical Grouping: Group related items together
- Consistent Naming: Use consistent value naming conventions
Best Practices > Performance Considerations
- Refresh Sparingly: Only call
menu.refresh()when necessary - Clean Up: Always close menus when done
- Memory Management: Remove unused elements to free memory
Best Practices > User Experience
- Provide Feedback: Use descriptions to explain what items do
- Logical Flow: Design menu navigation that makes sense
- Error Handling: Always check if elements exist before operations
Best Practices > Example Error Handling
-- Safe element retrieval
local element = menu.getElementByValue("somevalue")
if element then
-- Process element
else
print("Element not found")
end
-- Safe element update
if menu.getElementByIndex(index) then
menu.setElement(index, "label", "New Label")
menu.refresh()
end
Notes
- Menus use RDR2-style interface design
- All menu operations are client-side
- Refresh menu after runtime modifications
- Use unique namespaces to prevent conflicts
- Element properties can be extended with custom data
- Slider elements support float values for precision
- Menu alignment affects where the menu appears on screen
- Always handle both selection and close callbacks for complete functionality