Text UI
The Text UI system provides contextual text displays with optional keybind hints and icons. Perfect for showing interaction prompts, status information, and helpful hints that appear at specific screen positions.

textUI
Display a contextual text UI element with customizable styling and positioning.
-- Client-side
B2Lib.UI.textUI(options)
-- Server-side (via exports)
exports.b2lib:textUI(playerId, options)
Parameters:
playerId
(number, server-side only): Player server ID to show text UI tooptions
(table|string): Text UI configuration object or simple text stringtext
(string, required): Text content to displaykeybind
(string, optional): Keybind to display (e.g., 'E', 'F', 'ENTER', 'SPACE', 'TAB')key
(string, optional): Alternative parameter name for keybind (same as keybind)icon
(string, optional): Lucide icon name to display alongside textposition
(string, optional): Display position on screen (default: from config)showBackground
(boolean, optional): Show background panel (default: from config)fadeTime
(number, optional): Fade animation duration in milliseconds (default: from config)backgroundColor
(string, optional): Custom background color override (CSS color)textColor
(string, optional): Custom text color override (CSS color)borderColor
(string, optional): Custom border color override (CSS color)id
(string, optional): Custom text UI identifier for tracking and management
Returns: boolean - Success status
Example:
-- Basic text UI with simple string
local success = B2Lib.UI.textUI('Press E to interact')
-- Text UI with keybind
B2Lib.UI.textUI({
text = 'Open inventory',
keybind = 'TAB'
})
-- Text UI with icon and keybind
B2Lib.UI.textUI({
text = 'Enter vehicle',
keybind = 'F',
icon = 'car'
})
-- Custom positioned text UI
B2Lib.UI.textUI({
text = 'Checkpoint reached!',
position = 'top-center',
icon = 'check-circle',
showBackground = true
})
-- Text UI with custom styling
B2Lib.UI.textUI({
text = 'Warning: Low health',
keybind = 'H',
icon = 'heart',
position = 'bottom-left',
backgroundColor = 'rgba(220, 38, 38, 0.8)',
textColor = '#ffffff',
fadeTime = 200
})
-- Server-side usage
exports.b2lib:textUI(playerId, {
text = 'Admin message',
icon = 'shield',
position = 'top-center',
showBackground = true
})
hideTextUI
Hide the currently active text UI element with fade animation.
-- Client-side
B2Lib.UI.hideTextUI()
-- Server-side (via exports)
exports.b2lib:hideTextUI(playerId)
Parameters:
playerId
(number, server-side only): Player server ID to hide text UI for
Returns: boolean - Success status
Example:
-- Hide the current text UI
local success = B2Lib.UI.hideTextUI()
-- Hide text UI when player moves away
CreateThread(function()
while true do
Wait(100)
local playerCoords = GetEntityCoords(PlayerPedId())
local distance = #(playerCoords - targetCoords)
if distance > 3.0 and textUIVisible then
B2Lib.UI.hideTextUI()
textUIVisible = false
end
end
end)
-- Server-side hide for specific player
exports.b2lib:hideTextUI(playerId)
-- Server-side hide for multiple players
local players = {1, 2, 3}
for _, id in ipairs(players) do
exports.b2lib:hideTextUI(id)
end
isTextUIVisible
Check if text UI is currently visible and get active text UI information.
B2Lib.UI.isTextUIVisible()
Returns: boolean|table - False if no text UI is active, or table with active text UI data
text
(string): Current text contentkeybind
(string): Current keybindicon
(string): Current iconposition
(string): Current positionid
(string): Text UI identifier
Example:
local textUIState = B2Lib.UI.isTextUIVisible()
if textUIState then
print('Text UI is visible:', textUIState.text)
print('Position:', textUIState.position)
else
print('No text UI is currently visible')
end
Position Options
Text UI supports 9 different screen positions for optimal placement:
'top-left'
- Top left corner of screen'top-center'
- Top center of screen'top-right'
- Top right corner of screen'center-left'
- Middle left of screen'center'
- Center of screen'center-right'
- Middle right of screen'bottom-left'
- Bottom left corner of screen'bottom-center'
- Bottom center of screen (default)'bottom-right'
- Bottom right corner of screen
Example:
-- Test all positions
local positions = {
'top-left', 'top-center', 'top-right',
'center-left', 'center', 'center-right',
'bottom-left', 'bottom-center', 'bottom-right'
}
for i, position in ipairs(positions) do
SetTimeout(i * 2000, function()
B2Lib.UI.textUI({
text = 'Position: ' .. position,
position = position,
icon = 'map-pin'
})
SetTimeout(1500, function()
B2Lib.UI.hideTextUI()
end)
end)
end
Server-Side Usage
The Text UI module provides comprehensive server-side functionality for managing player-specific text displays:
-- Show text UI to specific player
exports.b2lib:textUI(playerId, {
text = 'Welcome to the server!',
icon = 'star',
position = 'top-center',
showBackground = true
})
-- Hide text UI for specific player
exports.b2lib:hideTextUI(playerId)
-- Show text UI to multiple players
local function showTextUIToPlayers(playerIds, options)
for _, playerId in ipairs(playerIds) do
exports.b2lib:textUI(playerId, options)
end
end
-- Show text UI to all players
local function showTextUIToAll(options)
local players = GetPlayers()
for _, playerId in ipairs(players) do
exports.b2lib:textUI(tonumber(playerId), options)
end
end
-- Example: Show text UI to all players in a zone
local function showZoneMessage(coords, radius, message)
local players = GetPlayers()
for _, playerId in ipairs(players) do
local playerPed = GetPlayerPed(playerId)
if playerPed and DoesEntityExist(playerPed) then
local playerCoords = GetEntityCoords(playerPed)
local distance = #(playerCoords - coords)
if distance <= radius then
exports.b2lib:textUI(tonumber(playerId), {
text = message,
icon = 'map-pin',
position = 'top-center',
showBackground = true
})
end
end
end
end
-- Example: Event-based text UI management
RegisterNetEvent('server:showTextUI')
AddEventHandler('server:showTextUI', function(targetId, options)
local source = source
-- Verify permissions (example)
if IsPlayerAceAllowed(source, 'textui.admin') then
exports.b2lib:textUI(targetId, options)
else
print('Player ' .. source .. ' attempted unauthorized text UI command')
end
end)
-- Example: Timed server-side text UI
local function showTimedTextUI(playerId, options, duration)
exports.b2lib:textUI(playerId, options)
SetTimeout(duration, function()
exports.b2lib:hideTextUI(playerId)
end)
end
-- Usage examples
showTimedTextUI(1, {
text = 'Server restart in 5 minutes',
icon = 'clock',
position = 'top-center',
backgroundColor = 'rgba(245, 158, 11, 0.8)'
}, 10000) -- Show for 10 seconds
-- Admin notification system
local function notifyAdmins(message, icon)
local players = GetPlayers()
for _, playerId in ipairs(players) do
if IsPlayerAceAllowed(playerId, 'admin') then
exports.b2lib:textUI(tonumber(playerId), {
text = message,
icon = icon or 'shield',
position = 'top-right',
backgroundColor = 'rgba(59, 130, 246, 0.8)',
textColor = '#ffffff'
})
end
end
end
-- Player-specific interaction system
RegisterNetEvent('server:playerInteraction')
AddEventHandler('server:playerInteraction', function(targetPlayerId, interactionType)
local source = source
local sourceName = GetPlayerName(source)
if interactionType == 'trade' then
exports.b2lib:textUI(targetPlayerId, {
text = sourceName .. ' wants to trade',
keybind = 'Y',
icon = 'handshake',
position = 'center'
})
elseif interactionType == 'help' then
exports.b2lib:textUI(targetPlayerId, {
text = sourceName .. ' is offering help',
keybind = 'H',
icon = 'heart',
position = 'center'
})
end
end)
Configuration
Complete Text UI configuration options in config.lua
:
--- Text UI configuration
--- @type table
Config.TextUI = {
position = 'bottom-center', -- Default position for text UI
showBackground = true, -- Show background for better readability
fadeTime = 400 -- Fade animation duration in milliseconds
}
-- Text UI styling configuration
Config.ComponentStyles.textUI = {
padding = '12px 16px', -- Internal padding
borderRadius = 'lg', -- Border radius (from Config.Theme.borderRadius)
fontSize = 'sm', -- Text font size
fontWeight = 'medium', -- Text font weight
shadow = 'md', -- Shadow style (from Config.Theme.shadows)
borderWidth = '1px', -- Border width
-- Icon styling
icon = {
size = '16px', -- Icon size
margin = '8px', -- Icon margin
opacity = '0.8' -- Icon opacity
},
-- Keybind styling
keybind = {
padding = '4px 8px', -- Keybind padding
borderRadius = 'md', -- Keybind border radius
fontSize = 'xs', -- Keybind font size
fontWeight = 'bold', -- Keybind font weight
margin = '8px', -- Keybind margin
minWidth = '24px' -- Minimum keybind width
},
-- Animation settings
animations = {
fadeIn = 'fadeIn 0.4s ease-out',
fadeOut = 'fadeOut 0.4s ease-in'
},
-- Position-specific styling
positions = {
['top-left'] = { margin = '20px' },
['top-center'] = { margin = '20px auto' },
['top-right'] = { margin = '20px 20px 0 0' },
['center-left'] = { margin = 'auto 0 auto 20px' },
['center'] = { margin = 'auto' },
['center-right'] = { margin = 'auto 20px auto 0' },
['bottom-left'] = { margin = '0 0 20px 20px' },
['bottom-center'] = { margin = '0 auto 20px auto' },
['bottom-right'] = { margin = '0 20px 20px 0' }
}
}
Advanced Examples
Interactive Object System
-- Create a comprehensive interactive object system with text UI
local InteractiveObjects = {}
InteractiveObjects.objects = {}
InteractiveObjects.activeObject = nil
function InteractiveObjects.create(coords, options)
local object = {
id = #InteractiveObjects.objects + 1,
coords = coords,
text = options.text or 'Interact',
keybind = options.keybind or 'E',
icon = options.icon,
range = options.range or 2.0,
callback = options.callback,
condition = options.condition, -- Optional condition function
active = false,
cooldown = 0
}
table.insert(InteractiveObjects.objects, object)
return object
end
function InteractiveObjects.update()
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local currentTime = GetGameTimer()
local closestObject = nil
local closestDistance = math.huge
-- Find closest interactive object
for _, object in ipairs(InteractiveObjects.objects) do
local distance = #(playerCoords - object.coords)
if distance <= object.range then
-- Check condition if provided
local canInteract = true
if object.condition then
canInteract = object.condition()
end
if canInteract and distance < closestDistance then
closestObject = object
closestDistance = distance
end
end
end
-- Update active object
if closestObject ~= InteractiveObjects.activeObject then
if InteractiveObjects.activeObject then
B2Lib.UI.hideTextUI()
InteractiveObjects.activeObject.active = false
end
if closestObject then
B2Lib.UI.textUI({
text = closestObject.text,
keybind = closestObject.keybind,
icon = closestObject.icon,
position = 'bottom-center'
})
closestObject.active = true
end
InteractiveObjects.activeObject = closestObject
end
-- Handle interaction
if InteractiveObjects.activeObject and IsControlJustPressed(0, 38) then -- E key
local object = InteractiveObjects.activeObject
if currentTime >= object.cooldown then
if object.callback then
object.callback(object)
end
object.cooldown = currentTime + 1000 -- 1 second cooldown
end
end
end
-- Create interactive objects
InteractiveObjects.create(vector3(100.0, 200.0, 30.0), {
text = 'Open shop',
keybind = 'E',
icon = 'shopping-bag',
callback = function(object)
B2Lib.UI.notify({
type = 'success',
message = 'Shop opened!'
})
TriggerEvent('shop:open')
end
})
InteractiveObjects.create(vector3(150.0, 250.0, 30.0), {
text = 'Use ATM',
keybind = 'E',
icon = 'credit-card',
condition = function()
-- Only show if player has money
return GetPlayerMoney(PlayerId()) > 0
end,
callback = function(object)
TriggerEvent('banking:openATM')
end
})
-- Update loop
CreateThread(function()
while true do
Wait(100)
InteractiveObjects.update()
end
end)
Vehicle Interaction System
-- Advanced vehicle interaction system with multiple states
local VehicleInteraction = {}
VehicleInteraction.currentVehicle = nil
VehicleInteraction.textUIActive = false
VehicleInteraction.lastUpdate = 0
function VehicleInteraction.getVehicleInfo(vehicle)
local info = {
locked = GetVehicleDoorLockStatus(vehicle) == 2,
engine = GetIsVehicleEngineRunning(vehicle),
fuel = GetVehicleFuelLevel(vehicle),
health = GetEntityHealth(vehicle),
maxHealth = GetEntityMaxHealth(vehicle),
model = GetEntityModel(vehicle),
displayName = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
}
info.healthPercent = (info.health / info.maxHealth) * 100
return info
end
function VehicleInteraction.getInteractionText(vehicle, distance)
local playerPed = PlayerPedId()
local playerInVehicle = GetVehiclePedIsIn(playerPed, false) == vehicle
local info = VehicleInteraction.getVehicleInfo(vehicle)
if playerInVehicle then
if not info.engine then
return {
text = 'Start engine',
keybind = 'F',
icon = 'power',
color = 'success'
}
else
return {
text = 'Turn off engine',
keybind = 'F',
icon = 'power-off',
color = 'warning'
}
end
else
if info.locked then
return {
text = 'Vehicle locked',
keybind = '',
icon = 'lock',
color = 'error'
}
else
return {
text = 'Enter ' .. info.displayName,
keybind = 'F',
icon = 'car',
color = 'default'
}
end
end
end
function VehicleInteraction.update()
local currentTime = GetGameTimer()
if currentTime - VehicleInteraction.lastUpdate < 100 then
return
end
VehicleInteraction.lastUpdate = currentTime
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local vehicle = GetClosestVehicle(playerCoords, 5.0, 0, 71)
if vehicle ~= 0 and DoesEntityExist(vehicle) then
local vehicleCoords = GetEntityCoords(vehicle)
local distance = #(playerCoords - vehicleCoords)
if distance <= 3.0 then
if vehicle ~= VehicleInteraction.currentVehicle then
VehicleInteraction.currentVehicle = vehicle
local interaction = VehicleInteraction.getInteractionText(vehicle, distance)
B2Lib.UI.textUI({
text = interaction.text,
keybind = interaction.keybind,
icon = interaction.icon,
position = 'bottom-center',
backgroundColor = interaction.color == 'error' and 'rgba(220, 38, 38, 0.8)' or
interaction.color == 'success' and 'rgba(34, 197, 94, 0.8)' or nil
})
VehicleInteraction.textUIActive = true
end
-- Handle vehicle interaction
if IsControlJustPressed(0, 23) then -- F key
local playerInVehicle = GetVehiclePedIsIn(playerPed, false) == vehicle
local info = VehicleInteraction.getVehicleInfo(vehicle)
if playerInVehicle then
-- Toggle engine
SetVehicleEngineOn(vehicle, not info.engine, false, true)
B2Lib.UI.notify({
type = info.engine and 'warning' or 'success',
message = info.engine and 'Engine turned off' or 'Engine started'
})
else
-- Enter vehicle
if not info.locked then
TaskEnterVehicle(playerPed, vehicle, -1, -1, 1.0, 1, 0)
B2Lib.UI.hideTextUI()
VehicleInteraction.textUIActive = false
end
end
end
else
VehicleInteraction.cleanup()
end
else
VehicleInteraction.cleanup()
end
end
function VehicleInteraction.cleanup()
if VehicleInteraction.textUIActive then
B2Lib.UI.hideTextUI()
VehicleInteraction.textUIActive = false
VehicleInteraction.currentVehicle = nil
end
end
-- Initialize vehicle interaction system
CreateThread(function()
while true do
Wait(50)
VehicleInteraction.update()
end
end)
Dynamic Status Display System
-- Comprehensive status monitoring and display system
local StatusSystem = {}
StatusSystem.monitors = {}
StatusSystem.activeDisplays = {}
function StatusSystem.addMonitor(name, config)
StatusSystem.monitors[name] = {
name = name,
getValue = config.getValue,
threshold = config.threshold,
message = config.message,
icon = config.icon,
position = config.position or 'top-center',
color = config.color or 'warning',
duration = config.duration or 5000,
cooldown = config.cooldown or 10000,
lastShown = 0,
active = false
}
end
function StatusSystem.checkMonitors()
local currentTime = GetGameTimer()
for name, monitor in pairs(StatusSystem.monitors) do
local value = monitor.getValue()
local shouldShow = value <= monitor.threshold
local canShow = currentTime >= monitor.lastShown + monitor.cooldown
if shouldShow and not monitor.active and canShow then
-- Show warning
local backgroundColor = monitor.color == 'error' and 'rgba(220, 38, 38, 0.8)' or
monitor.color == 'warning' and 'rgba(245, 158, 11, 0.8)' or
'rgba(59, 130, 246, 0.8)'
B2Lib.UI.textUI({
text = monitor.message:format(value),
icon = monitor.icon,
position = monitor.position,
backgroundColor = backgroundColor,
textColor = '#ffffff',
showBackground = true,
id = 'status_' .. name
})
monitor.active = true
monitor.lastShown = currentTime
-- Auto-hide after duration
SetTimeout(monitor.duration, function()
if monitor.active then
B2Lib.UI.hideTextUI()
monitor.active = false
end
end)
elseif not shouldShow and monitor.active then
B2Lib.UI.hideTextUI()
monitor.active = false
end
end
end
-- Add status monitors
StatusSystem.addMonitor('health', {
getValue = function()
return GetEntityHealth(PlayerPedId())
end,
threshold = 50,
message = 'Low health: %d - Find medical assistance',
icon = 'heart',
color = 'error',
position = 'top-center'
})
StatusSystem.addMonitor('armor', {
getValue = function()
return GetPedArmour(PlayerPedId())
end,
threshold = 25,
message = 'Armor damaged: %d - Consider replacement',
icon = 'shield',
color = 'warning',
position = 'top-center'
})
StatusSystem.addMonitor('vehicle_health', {
getValue = function()
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if vehicle ~= 0 then
local health = GetEntityHealth(vehicle)
local maxHealth = GetEntityMaxHealth(vehicle)
return (health / maxHealth) * 100
end
return 100
end,
threshold = 30,
message = 'Vehicle damaged: %.0f%% - Repair needed',
icon = 'wrench',
color = 'warning',
position = 'bottom-left'
})
-- Update status monitors
CreateThread(function()
while true do
Wait(2000)
StatusSystem.checkMonitors()
end
end)
Mission Objective System
-- Advanced mission objective and guidance system
local MissionSystem = {}
MissionSystem.currentObjective = nil
MissionSystem.objectiveHistory = {}
MissionSystem.waypoint = nil
function MissionSystem.setObjective(objective)
-- Hide current objective
if MissionSystem.currentObjective then
B2Lib.UI.hideTextUI()
table.insert(MissionSystem.objectiveHistory, MissionSystem.currentObjective)
end
MissionSystem.currentObjective = {
id = objective.id or 'obj_' .. GetGameTimer(),
text = objective.text,
keybind = objective.keybind,
icon = objective.icon or 'target',
position = objective.position or 'top-center',
waypoint = objective.waypoint,
autoHide = objective.autoHide,
startTime = GetGameTimer()
}
-- Show new objective
B2Lib.UI.textUI({
text = MissionSystem.currentObjective.text,
keybind = MissionSystem.currentObjective.keybind,
icon = MissionSystem.currentObjective.icon,
position = MissionSystem.currentObjective.position,
showBackground = true,
backgroundColor = 'rgba(59, 130, 246, 0.9)',
textColor = '#ffffff'
})
-- Set waypoint if provided
if MissionSystem.currentObjective.waypoint then
SetNewWaypoint(MissionSystem.currentObjective.waypoint.x, MissionSystem.currentObjective.waypoint.y)
MissionSystem.waypoint = MissionSystem.currentObjective.waypoint
end
-- Auto-hide if specified
if MissionSystem.currentObjective.autoHide then
SetTimeout(MissionSystem.currentObjective.autoHide, function()
MissionSystem.clearObjective()
end)
end
-- Trigger event
TriggerEvent('b2lib:mission:objectiveSet', MissionSystem.currentObjective)
end
function MissionSystem.updateObjective(newText, newKeybind, newIcon)
if MissionSystem.currentObjective then
MissionSystem.currentObjective.text = newText
MissionSystem.currentObjective.keybind = newKeybind or MissionSystem.currentObjective.keybind
MissionSystem.currentObjective.icon = newIcon or MissionSystem.currentObjective.icon
B2Lib.UI.textUI({
text = MissionSystem.currentObjective.text,
keybind = MissionSystem.currentObjective.keybind,
icon = MissionSystem.currentObjective.icon,
position = MissionSystem.currentObjective.position,
showBackground = true,
backgroundColor = 'rgba(59, 130, 246, 0.9)',
textColor = '#ffffff'
})
TriggerEvent('b2lib:mission:objectiveUpdated', MissionSystem.currentObjective)
end
end
function MissionSystem.clearObjective()
if MissionSystem.currentObjective then
B2Lib.UI.hideTextUI()
if MissionSystem.waypoint then
RemoveBlip(GetFirstBlipInfoId(8)) -- Remove waypoint
MissionSystem.waypoint = nil
end
TriggerEvent('b2lib:mission:objectiveCleared', MissionSystem.currentObjective)
MissionSystem.currentObjective = nil
end
end
function MissionSystem.completeObjective(completionText)
if MissionSystem.currentObjective then
-- Show completion message
B2Lib.UI.textUI({
text = completionText or 'Objective completed!',
icon = 'check-circle',
position = 'top-center',
showBackground = true,
backgroundColor = 'rgba(34, 197, 94, 0.9)',
textColor = '#ffffff'
})
-- Clear after 3 seconds
SetTimeout(3000, function()
MissionSystem.clearObjective()
end)
TriggerEvent('b2lib:mission:objectiveCompleted', MissionSystem.currentObjective)
end
end
-- Example mission flow
local function startDeliveryMission()
MissionSystem.setObjective({
text = 'Go to the pickup location',
icon = 'map-pin',
waypoint = vector3(100.0, 200.0, 30.0)
})
-- Simulate reaching pickup location
SetTimeout(10000, function()
MissionSystem.updateObjective('Pick up the package', 'E', 'package')
-- Simulate picking up package
SetTimeout(5000, function()
MissionSystem.updateObjective('Deliver to destination', '', 'truck')
-- Simulate delivery
SetTimeout(15000, function()
MissionSystem.completeObjective('Delivery completed successfully!')
end)
end)
end)
end
-- Command to test mission system
RegisterCommand('startdelivery', function()
startDeliveryMission()
end, false)
Dynamic Help System
-- Create a comprehensive context-aware help system
local HelpSystem = {}
HelpSystem.tips = {}
HelpSystem.currentTip = nil
HelpSystem.enabled = true
HelpSystem.lastUpdate = 0
function HelpSystem.addTip(id, config)
HelpSystem.tips[id] = {
id = id,
condition = config.condition,
text = config.text,
keybind = config.keybind or '',
icon = config.icon or 'info',
priority = config.priority or 1,
cooldown = config.cooldown or 0,
lastShown = 0,
category = config.category or 'general'
}
end
function HelpSystem.removeTip(id)
HelpSystem.tips[id] = nil
if HelpSystem.currentTip and HelpSystem.currentTip.id == id then
B2Lib.UI.hideTextUI()
HelpSystem.currentTip = nil
end
end
function HelpSystem.update()
if not HelpSystem.enabled then return end
local currentTime = GetGameTimer()
if currentTime - HelpSystem.lastUpdate < 500 then return end
HelpSystem.lastUpdate = currentTime
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local vehicle = GetVehiclePedIsIn(playerPed, false)
-- Find the highest priority applicable tip
local bestTip = nil
local highestPriority = 0
for _, tip in pairs(HelpSystem.tips) do
local canShow = currentTime >= tip.lastShown + tip.cooldown
if canShow and tip.condition(playerPed, playerCoords, vehicle) and tip.priority > highestPriority then
bestTip = tip
highestPriority = tip.priority
end
end
-- Show or update tip
if bestTip and (not HelpSystem.currentTip or bestTip.id ~= HelpSystem.currentTip.id) then
HelpSystem.currentTip = bestTip
bestTip.lastShown = currentTime
B2Lib.UI.textUI({
text = bestTip.text,
keybind = bestTip.keybind,
icon = bestTip.icon,
position = 'bottom-right',
showBackground = true,
backgroundColor = 'rgba(59, 130, 246, 0.8)',
textColor = '#ffffff',
id = 'help_' .. bestTip.id
})
elseif not bestTip and HelpSystem.currentTip then
B2Lib.UI.hideTextUI()
HelpSystem.currentTip = nil
end
end
function HelpSystem.toggle()
HelpSystem.enabled = not HelpSystem.enabled
if not HelpSystem.enabled then
B2Lib.UI.hideTextUI()
HelpSystem.currentTip = nil
end
B2Lib.UI.notify({
type = 'info',
message = 'Help system ' .. (HelpSystem.enabled and 'enabled' or 'disabled')
})
end
-- Add contextual help tips
HelpSystem.addTip('sprint', {
condition = function(ped, coords, vehicle)
return vehicle == 0 and IsPedOnFoot(ped) and not IsPedRunning(ped)
end,
text = 'Hold SHIFT to run faster',
keybind = 'SHIFT',
icon = 'zap',
priority = 1,
cooldown = 30000,
category = 'movement'
})
HelpSystem.addTip('vehicle_handbrake', {
condition = function(ped, coords, vehicle)
return vehicle ~= 0 and GetEntitySpeed(vehicle) > 10.0
end,
text = 'Use handbrake for sharp turns',
keybind = 'SPACE',
icon = 'rotate-ccw',
priority = 2,
cooldown = 45000,
category = 'driving'
})
HelpSystem.addTip('weapon_aim', {
condition = function(ped, coords, vehicle)
return IsPedArmed(ped, 7) and not IsPedAiming(ped)
end,
text = 'Right-click to aim weapon',
keybind = 'RMB',
icon = 'crosshair',
priority = 3,
cooldown = 60000,
category = 'combat'
})
HelpSystem.addTip('low_health', {
condition = function(ped, coords, vehicle)
return GetEntityHealth(ped) < 50
end,
text = 'Find medical assistance - Low health!',
icon = 'heart',
priority = 5,
cooldown = 20000,
category = 'survival'
})
-- Update help system
CreateThread(function()
while true do
Wait(500)
HelpSystem.update()
end
end)
-- Commands for help system
RegisterCommand('togglehelp', function()
HelpSystem.toggle()
end, false)
RegisterCommand('helpstatus', function()
print('Help System Status:')
print('Enabled:', HelpSystem.enabled)
print('Current tip:', HelpSystem.currentTip and HelpSystem.currentTip.id or 'none')
print('Total tips:', #HelpSystem.tips)
end, false)
Events
The Text UI module provides comprehensive event handling for monitoring and responding to text UI interactions:
Client Events
-- Text UI shown event
AddEventHandler('b2lib:textui:shown', function(options)
print('Text UI shown with text:', options.text)
print('Position:', options.position)
print('Icon:', options.icon or 'none')
print('Keybind:', options.keybind or 'none')
end)
-- Text UI hidden event
AddEventHandler('b2lib:textui:hidden', function()
print('Text UI was hidden')
end)
-- Text UI interaction event (when keybind is pressed)
AddEventHandler('b2lib:textui:interaction', function(keybind)
print('Text UI keybind pressed:', keybind)
end)
-- Text UI position changed event
AddEventHandler('b2lib:textui:position-changed', function(newPosition)
print('Text UI position changed to:', newPosition)
end)
-- Text UI style updated event
AddEventHandler('b2lib:textui:style-updated', function(styleData)
print('Text UI style updated:', json.encode(styleData))
end)
Server Events
-- Player text UI shown event
AddEventHandler('b2lib:textui:player-shown', function(playerId, options)
print('Text UI shown to player', playerId, 'with text:', options.text)
-- Log admin text UI usage
if options.backgroundColor and options.backgroundColor:find('59, 130, 246') then
print('Admin text UI shown to player', playerId)
end
end)
-- Player text UI hidden event
AddEventHandler('b2lib:textui:player-hidden', function(playerId)
print('Text UI hidden for player', playerId)
end)
-- Player text UI interaction event
AddEventHandler('b2lib:textui:player-interaction', function(playerId, keybind)
print('Player', playerId, 'pressed keybind:', keybind)
end)
Event Usage Examples
-- Comprehensive text UI analytics system
local TextUIAnalytics = {
stats = {
shown = 0,
hidden = 0,
interactions = 0,
positions = {},
icons = {},
keybinds = {}
},
sessions = {}
}
function TextUIAnalytics.trackEvent(eventType, data)
TextUIAnalytics.stats[eventType] = (TextUIAnalytics.stats[eventType] or 0) + 1
if eventType == 'shown' and data then
-- Track position usage
local pos = data.position or 'unknown'
TextUIAnalytics.stats.positions[pos] = (TextUIAnalytics.stats.positions[pos] or 0) + 1
-- Track icon usage
if data.icon then
TextUIAnalytics.stats.icons[data.icon] = (TextUIAnalytics.stats.icons[data.icon] or 0) + 1
end
-- Track keybind usage
if data.keybind then
TextUIAnalytics.stats.keybinds[data.keybind] = (TextUIAnalytics.stats.keybinds[data.keybind] or 0) + 1
end
end
end
-- Event handlers
AddEventHandler('b2lib:textui:shown', function(options)
TextUIAnalytics.trackEvent('shown', options)
-- Log important text UI displays
if options.icon == 'alert-triangle' or options.icon == 'alert-circle' then
print('Warning text UI shown:', options.text)
end
-- Auto-hide certain types of text UI
if options.text:find('Low health') or options.text:find('Warning') then
SetTimeout(8000, function()
B2Lib.UI.hideTextUI()
end)
end
end)
AddEventHandler('b2lib:textui:hidden', function()
TextUIAnalytics.trackEvent('hidden')
end)
AddEventHandler('b2lib:textui:interaction', function(keybind)
TextUIAnalytics.trackEvent('interactions')
-- Handle specific keybind interactions
if keybind == 'E' then
TriggerEvent('player:interaction')
elseif keybind == 'F' then
TriggerEvent('player:vehicle-interaction')
elseif keybind == 'H' then
TriggerEvent('player:help-request')
end
end)
-- Command to view analytics
RegisterCommand('textui-stats', function()
print('=== Text UI Analytics ===')
print('Total shown:', TextUIAnalytics.stats.shown)
print('Total hidden:', TextUIAnalytics.stats.hidden)
print('Total interactions:', TextUIAnalytics.stats.interactions)
print('Most used position:', 'bottom-center') -- Example
print('Most used icon:', 'car') -- Example
print('Most used keybind:', 'E') -- Example
end, false)
-- Context-aware text UI management
local ContextManager = {
activeContexts = {},
priorities = {
emergency = 10,
warning = 8,
interaction = 5,
info = 3,
help = 1
}
}
function ContextManager.showContextualTextUI(context, options)
local priority = ContextManager.priorities[context] or 1
-- Check if we should override current text UI
local currentContext = ContextManager.activeContexts[1]
if not currentContext or priority > currentContext.priority then
-- Store current context
if currentContext then
table.insert(ContextManager.activeContexts, 2, currentContext)
end
-- Show new text UI
ContextManager.activeContexts[1] = {
context = context,
priority = priority,
options = options
}
B2Lib.UI.textUI(options)
end
end
function ContextManager.hideContextualTextUI(context)
-- Remove context from active list
for i, activeContext in ipairs(ContextManager.activeContexts) do
if activeContext.context == context then
table.remove(ContextManager.activeContexts, i)
break
end
end
-- Show next highest priority context or hide
if #ContextManager.activeContexts > 0 then
local nextContext = ContextManager.activeContexts[1]
B2Lib.UI.textUI(nextContext.options)
else
B2Lib.UI.hideTextUI()
end
end
-- Example usage of context manager
AddEventHandler('player:low-health', function()
ContextManager.showContextualTextUI('emergency', {
text = 'Critical health - Seek medical attention!',
icon = 'heart',
position = 'top-center',
backgroundColor = 'rgba(220, 38, 38, 0.9)',
textColor = '#ffffff'
})
end)
AddEventHandler('player:near-vehicle', function()
ContextManager.showContextualTextUI('interaction', {
text = 'Enter vehicle',
keybind = 'F',
icon = 'car',
position = 'bottom-center'
})
end)
Best Practices
Use Strategic Positioning - Choose positions that complement gameplay flow and don't obstruct critical UI elements like minimap, health bars, or chat
Keep Text Concise and Clear - Use short, actionable messages that players can quickly understand at a glance
Implement Meaningful Keybinds - Display the actual keys players need to press, using consistent keybind conventions across your resource
Leverage Visual Hierarchy - Use icons, colors, and positioning to create clear visual hierarchy and importance levels
Handle State Management Properly - Always hide text UI when conditions change to prevent UI pollution and confusion
Test Across Resolutions - Ensure text UI displays correctly on different screen sizes and aspect ratios
Maintain Visual Consistency - Use consistent styling, colors, and positioning patterns throughout your resource
Implement Context Awareness - Show relevant information based on player state, location, and current activities
Optimize Update Frequency - Use appropriate update intervals to balance responsiveness with performance
Use Server-Side Strategically - Leverage server-side text UI for administrative tools, events, and player-specific content
Implement Priority Systems - Use priority-based systems to manage multiple text UI contexts and prevent conflicts
Provide Accessibility Options - Consider colorblind users and provide high contrast options when needed
Troubleshooting
Text UI Not Showing
Check that the text parameter is provided and not empty
Verify B2Lib is properly initialized
Check console for error messages from B2Lib.Debug
Ensure no other modal dialogs are blocking the display
Text UI Not Hiding
Verify hideTextUI() is being called correctly
Check that the text UI was successfully shown first
Ensure no other scripts are showing text UI simultaneously
Test with manual hideTextUI() calls
Positioning Issues
Check that position values are valid strings
Test with default position first
Verify screen resolution compatibility
Check for CSS conflicts in custom styling
Performance Issues
Avoid showing/hiding text UI too frequently
Use reasonable update intervals in loops
Clean up event handlers when no longer needed
Limit the number of active text UI elements
Last updated