Merge branch 'main' into gitlocalize-40746

This commit is contained in:
Tixx
2026-05-20 11:39:29 +02:00
committed by GitHub
6 changed files with 719 additions and 608 deletions
-30
View File
@@ -1,30 +0,0 @@
# March 28, 2026 BeamMP Outage FAQ
Temporary FAQ for the (currently) ongoing BeamMP outage that started on March 28th, 2026.
**Last updated April 1st, 2026.**
=== Help! My BeamMP launcher doesn't work!
Try reinstalling the BeamMP launcher. To do so, follow the instructions below:
1. Go to [beammp.com](https://beammp.com/)
2. Click *Download Now*
3. Run the installer and follow instructions
!!! note
As of April 1st, 2026, the MSI installer is an "unrecognized app" according to Windows Defender SmartScreen.
To bypass this warning, click *More info*, then click *Run anyway*.
=== Help! My authkey(s) don't work anymore!
As of April 1st, 2026, keymaster and auth systems are offline. This means that your authkeys won't work. To get around this, follow the instructions below:
1. Open your `ServerConfig.toml`, or wherever your server config is modified
2. Set `Private` to `true`. It should look like this: `Private = true`
3. This should fix the authkey issue.
!!! note
As of April 1st, 2026, BeamMP's auth systems are offline. Only guest accounts are available.
Make sure your server allows guests.
+241 -145
View File
@@ -10,170 +10,266 @@
## Common variables
=== BeamNG Orange
=== "BeamNG CEF Orange"
```css
var(--bng-orange) /*Common orange*/
var(--bng-orange-shade1) /*70% opacity*/
var(--bng-orange-shade2) /*40% opacity*/
var(--bng-orange-shade1opaque)
var(--bng-orange-shade2opaque)
```
```css
var(--bng-orange) /*Common orange*/
var(--bng-orange-shade1) /*70% opacity*/
var(--bng-orange-shade2) /*40% opacity*/
var(--bng-orange-shade1opaque)
var(--bng-orange-shade2opaque)
```
=== Monochrome
=== "Monochrome"
```css
--- Monochrome
var(--bng-black-8) /*80% opacity (duplicate --bng-black-o8)*/
var(--bng-black-6) /*60% opacity (duplicate --bng-black-o6)*/
var(--bng-black-4) /*40% opacity (duplicate --bng-black-o4)*/
var(--bng-black-2) /*20% opacity (duplicate --bng-black-o2)*/
```css
--- Monochrome
var(--bng-black-8) /*80% opacity (duplicate --bng-black-o8)*/
var(--bng-black-6) /*60% opacity (duplicate --bng-black-o6)*/
var(--bng-black-4) /*40% opacity (duplicate --bng-black-o4)*/
var(--bng-black-2) /*20% opacity (duplicate --bng-black-o2)*/
var(--dark-neutral-grey)
var(--neutral-grey)
var(--light-neutral-grey)
var(--dark-grey)
var(--dark-grey-alpha) /*80% opacity*/
var(--dark-neutral-grey)
var(--neutral-grey)
var(--light-neutral-grey)
var(--dark-grey)
var(--dark-grey-alpha) /*80% opacity*/
var(--black-1) /*70% opacity*/
var(--black-2) /*40% opacity (duplicate --bng-black-o4)*/
var(--black-1) /*70% opacity*/
var(--black-2) /*40% opacity (duplicate --bng-black-o4)*/
var(--white-1) /*80% opacity*/
var(--white-2) /*40% opacity*/
var(--white-3) /*20% opacity*/
```
var(--white-1) /*80% opacity*/
var(--white-2) /*40% opacity*/
var(--white-3) /*20% opacity*/
```
=== BeamNG UI Color Palette
=== "BeamNG Vue UI Color Palette"
=== Orange
All of these support adding `-rgb` to the end of the variable name to convert them to raw red, green, blue values. Use -rgb like so: `rgba(var(--bng-orange-500-rgb), 0.5)` for 50% opacity bng-orange-500.
```css
var(--bng-orange-50)
var(--bng-orange-100)
var(--bng-orange-200)
var(--bng-orange-300)
var(--bng-orange-b400)
var(--bng-orange-500)
var(--bng-orange-600)
var(--bng-orange-700)
var(--bng-orange-800)
var(--bng-orange-900)
```
=== "Add Red"
=== Cool Gray
```css
var(--bng-add-red-50)
var(--bng-add-red-100)
var(--bng-add-red-200)
var(--bng-add-red-300)
var(--bng-add-red-400)
var(--bng-add-red-500)
var(--bng-add-red-550)
var(--bng-add-red-600)
var(--bng-add-red-650)
var(--bng-add-red-700)
var(--bng-add-red-750)
var(--bng-add-red-800)
var(--bng-add-red-850)
var(--bng-add-red-900)
```
```css
var(--bng-cool-gray-50)
var(--bng-cool-gray-100)
var(--bng-cool-gray-200)
var(--bng-cool-gray-300)
var(--bng-cool-gray-400)
var(--bng-cool-gray-500)
var(--bng-cool-gray-600)
var(--bng-cool-gray-700)
var(--bng-cool-gray-800)
var(--bng-cool-gray-900)
```
=== "Orange"
=== Ter Blue
```css
var(--bng-ter-blue-50)
var(--bng-ter-blue-100)
var(--bng-ter-blue-200)
var(--bng-ter-blue-300)
var(--bng-ter-blue-400)
var(--bng-ter-blue-500)
var(--bng-ter-blue-600)
var(--bng-ter-blue-700)
var(--bng-ter-blue-800)
var(--bng-ter-blue-900)
```
```css
var(--bng-orange-50)
var(--bng-orange-100)
var(--bng-orange-200)
var(--bng-orange-300)
var(--bng-orange-400)
var(--bng-orange-500)
var(--bng-orange-550)
var(--bng-orange-600)
var(--bng-orange-650)
var(--bng-orange-700)
var(--bng-orange-750)
var(--bng-orange-800)
var(--bng-orange-850)
var(--bng-orange-900)
```
=== Add Blue
```css
var(--bng-add-blue-50)
var(--bng-add-blue-100)
var(--bng-add-blue-200)
var(--bng-add-blue-300)
var(--bng-add-blue-400)
var(--bng-add-blue-500)
var(--bng-add-blue-600)
var(--bng-add-blue-700)
var(--bng-add-blue-800)
var(--bng-add-blue-900)
```
=== "Ter Peach"
=== Add Green
```css
var(--bng-add-green-50)
var(--bng-add-green-100)
var(--bng-add-green-200)
var(--bng-add-green-300)
var(--bng-add-green-400)
var(--bng-add-green-500)
var(--bng-add-green-600)
var(--bng-add-green-700)
var(--bng-add-green-800)
var(--bng-add-green-900)
```
```css
var(--bng-ter-peach-50)
var(--bng-ter-peach-100)
var(--bng-ter-peach-200)
var(--bng-ter-peach-300)
var(--bng-ter-peach-400)
var(--bng-ter-peach-500)
var(--bng-ter-peach-550)
var(--bng-ter-peach-600)
var(--bng-ter-peach-650)
var(--bng-ter-peach-700)
var(--bng-ter-peach-750)
var(--bng-ter-peach-800)
var(--bng-ter-peach-850)
var(--bng-ter-peach-900)
```
=== Add Yellow
```css
var(--bng-add-yellow-50)
var(--bng-add-yellow-100)
var(--bng-add-yellow-200)
var(--bng-add-yellow-300)
var(--bng-add-yellow-400)
var(--bng-add-yellow-500)
var(--bng-add-yellow-600)
var(--bng-add-yellow-700)
var(--bng-add-yellow-800)
var(--bng-add-yellow-900)
```
=== "Ter Yellow"
=== Add Peach
```css
var(--bng-add-peach-50)
var(--bng-add-peach-100)
var(--bng-add-peach-200)
var(--bng-add-peach-300)
var(--bng-add-peach-400)
var(--bng-add-peach-500)
var(--bng-add-peach-600)
var(--bng-add-peach-700)
var(--bng-add-peach-800)
var(--bng-add-peach-900)
```
```css
var(--bng-ter-yellow-50)
var(--bng-ter-yellow-100)
var(--bng-ter-yellow-200)
var(--bng-ter-yellow-300)
var(--bng-ter-yellow-400)
var(--bng-ter-yellow-500)
var(--bng-ter-yellow-550)
var(--bng-ter-yellow-600)
var(--bng-ter-yellow-650)
var(--bng-ter-yellow-700)
var(--bng-ter-yellow-750)
var(--bng-ter-yellow-800)
var(--bng-ter-yellow-850)
var(--bng-ter-yellow-900)
```
=== Add Red
```css
var(--bng-add-red-50)
var(--bng-add-red-100)
var(--bng-add-red-200)
var(--bng-add-red-300)
var(--bng-add-red-400)
var(--bng-add-red-500)
var(--bng-add-red-600)
var(--bng-add-red-700)
var(--bng-add-red-800)
var(--bng-add-red-900)
```
=== "Add Green"
```css
var(--bng-add-green-50)
var(--bng-add-green-100)
var(--bng-add-green-200)
var(--bng-add-green-300)
var(--bng-add-green-400)
var(--bng-add-green-500)
var(--bng-add-green-600)
var(--bng-add-green-700)
var(--bng-add-green-800)
var(--bng-add-green-900)
```
=== Extra color presets
=== "Baby Blue"
```css
var(--bng-filter-orange) /*Filter preset to force SVGs to use bng-orange*/
var(--bng-black-o8) /*80% opacity*/
var(--bng-black-o6) /*60% opacity*/
var(--bng-black-o4) /*40% opacity*/
var(--bng-black-o2) /*20% opacity*/
```
```css
var(--bng-add-babyblue-50)
var(--bng-add-babyblue-100)
var(--bng-add-babyblue-200)
var(--bng-add-babyblue-300)
var(--bng-add-babyblue-400)
var(--bng-add-babyblue-500)
var(--bng-add-babyblue-550)
var(--bng-add-babyblue-600)
var(--bng-add-babyblue-650)
var(--bng-add-babyblue-700)
var(--bng-add-babyblue-750)
var(--bng-add-babyblue-800)
var(--bng-add-babyblue-850)
var(--bng-add-babyblue-900)
```
=== Corner rounding presets
=== "Add Blue"
```css
var(--bng-corners-1) /*0.25rem*/
var(--bng-corners-2) /*0.50rem*/
var(--bng-corners-3) /*1.00rem*/
```
```css
var(--bng-add-blue-50)
var(--bng-add-blue-100)
var(--bng-add-blue-200)
var(--bng-add-blue-300)
var(--bng-add-blue-400)
var(--bng-add-blue-500)
var(--bng-add-blue-600)
var(--bng-add-blue-700)
var(--bng-add-blue-800)
var(--bng-add-blue-900)
```
=== "Indigo Blue"
```css
var(--bng-add-indigoblue-50)
var(--bng-add-indigoblue-100)
var(--bng-add-indigoblue-200)
var(--bng-add-indigoblue-300)
var(--bng-add-indigoblue-400)
var(--bng-add-indigoblue-500)
var(--bng-add-indigoblue-550)
var(--bng-add-indigoblue-600)
var(--bng-add-indigoblue-650)
var(--bng-add-indigoblue-700)
var(--bng-add-indigoblue-750)
var(--bng-add-indigoblue-800)
var(--bng-add-indigoblue-850)
var(--bng-add-indigoblue-900)
```
=== "Add Magenta"
```css
var(--bng-add-magenta-50)
var(--bng-add-magenta-100)
var(--bng-add-magenta-200)
var(--bng-add-magenta-300)
var(--bng-add-magenta-400)
var(--bng-add-magenta-500)
var(--bng-add-magenta-550)
var(--bng-add-magenta-600)
var(--bng-add-magenta-650)
var(--bng-add-magenta-700)
var(--bng-add-magenta-750)
var(--bng-add-magenta-800)
var(--bng-add-magenta-850)
var(--bng-add-magenta-900)
```
=== "Ter Blue Gray"
```css
var(--bng-ter-blue-gray-50)
var(--bng-ter-blue-gray-100)
var(--bng-ter-blue-gray-200)
var(--bng-ter-blue-gray-300)
var(--bng-ter-blue-gray-400)
var(--bng-ter-blue-gray-500)
var(--bng-ter-blue-gray-550)
var(--bng-ter-blue-gray-600)
var(--bng-ter-blue-gray-650)
var(--bng-ter-blue-gray-700)
var(--bng-ter-blue-gray-750)
var(--bng-ter-blue-gray-800)
var(--bng-ter-blue-gray-850)
var(--bng-ter-blue-gray-900)
```
=== "Cool Gray"
```css
var(--bng-cool-gray-50)
var(--bng-cool-gray-100)
var(--bng-cool-gray-200)
var(--bng-cool-gray-300)
var(--bng-cool-gray-400)
var(--bng-cool-gray-500)
var(--bng-cool-gray-550)
var(--bng-cool-gray-600)
var(--bng-cool-gray-650)
var(--bng-cool-gray-700)
var(--bng-cool-gray-750)
var(--bng-cool-gray-800)
var(--bng-cool-gray-850)
var(--bng-cool-gray-900)
```
=== "Other"
```css
var(--bng-off-black) /*Used in Vue for buttons and some headers*/
var(--bng-off-white) /*Used in Vue for interactable elements*/
var(--bng-off-white-brighter) /*Used in Vue for headers*/
```
=== "Extra color presets"
```css
var(--bng-filter-orange) /*Filter preset to force SVGs to use bng-orange*/
var(--bng-black-o8) /*80% opacity*/
var(--bng-black-o6) /*60% opacity*/
var(--bng-black-o4) /*40% opacity*/
var(--bng-black-o2) /*20% opacity*/
```
=== "Corner rounding presets"
```css
var(--bng-corners-1) /*0.25rem*/
var(--bng-corners-2) /*0.50rem*/
var(--bng-corners-3) /*1.00rem*/
```
+32 -32
View File
@@ -31,47 +31,47 @@ im.End()
## General
=== Basic Formatting
=== "Basic Formatting"
```lua
im.Text("")
im.TextWrapped("") -- automatic word wrap
im.TextColored(im.ImVec4(0,1,0,1), "") -- R,G,B,A
im.TextDisabled("") -- predefined style for disabled text
```lua
im.Text("")
im.TextWrapped("") -- automatic word wrap
im.TextColored(im.ImVec4(0,1,0,1), "") -- R,G,B,A
im.TextDisabled("") -- predefined style for disabled text
im.LabelText("", "")
im.BulletText("") -- Bullet point with text
im.SeparatorText("") -- Separator with centered text
im.LabelText("", "")
im.BulletText("") -- Bullet point with text
im.SeparatorText("") -- Separator with centered text
im.Separator() -- might want a NewLine before these
im.SameLine() -- horizontally append the following element to the previous element
im.NewLine()
im.Separator() -- might want a NewLine before these
im.SameLine() -- horizontally append the following element to the previous element
im.NewLine()
im.Spacing() -- small padding
im.Indent()
im.Unindent()
```
im.Spacing() -- small padding
im.Indent()
im.Unindent()
```
=== Inputs
=== "Inputs"
```lua
im.Button("", im.ImVec2(0,0)) -- 0 = fit to content
im.SmallButton("") -- Fit to content and slightly less padding
im.ArrowButton("", 0) -- arg 1: string is not actually used? arg 2: 0 = left, 1 = right, 2 = up, 3 = down
im.InvisibleButton("", im.ImVec2(0,0), ...) -- used for imgui cursor positioning?
```lua
im.Button("", im.ImVec2(0,0)) -- 0 = fit to content
im.SmallButton("") -- Fit to content and slightly less padding
im.ArrowButton("", 0) -- arg 1: string is not actually used? arg 2: 0 = left, 1 = right, 2 = up, 3 = down
im.InvisibleButton("", im.ImVec2(0,0), ...) -- used for imgui cursor positioning?
im.Checkbox("", im.BoolPtr(false))
im.Checkbox("", im.BoolPtr(false))
im.RadioButton1("", im.BoolPtr(false))
im.RadioButton2("", im.IntPtr(), 0) -- arg. 3: 0 or 1 for disabled or enabled
```
im.RadioButton1("", im.BoolPtr(false))
im.RadioButton2("", im.IntPtr(), 0) -- arg. 3: 0 or 1 for disabled or enabled
```
=== Other
=== "Other"
```lua
im.Bullet()
```lua
im.Bullet()
im.ProgressBar(0.5, im.ImVec2(0,0), "") -- arg 2: 0 for default width and/or height
im.ProgressBar(0.5, im.ImVec2(0,0), "") -- arg 2: 0 for default width and/or height
im.TextUnformatted("", "") -- Second argument seems to crash the game
```
im.TextUnformatted("", "") -- Second argument seems to crash the game
```
+32 -1
View File
@@ -347,4 +347,35 @@ If multiple pages are provided, or the hook is triggered multiple times, then th
### Dialogue
todo
Dialogue is used in the *A Rocky Start* campaign to display information about a mission. It is a centered, vertically aligned popup with a specific layout. It does not support embedding HTML.
```lua
ui_missionInfo.openDialogue({
title = "Dialogue title",
type = "Custom", -- isn't actually displayed
typeName = "typeName",
data = {
{label = "objective", value = "reward"}
-- add more...
},
buttons = {
{action = "accept", text = "Accept", cmd = ""},
{action = 'decline',text = "Decline", cmd = ""}
-- add more...
}
})
ui_missionInfo.closeDialogue()
```
<figure class="image image_resized" style="width:75%" markdown>
![The Dialogue snippet displayed in BeamNG.drive](../../assets/content/Dialogue.png)
</figure>
Only one Dialogue can be displayed at once. Any existing Dialogue is overridden.
!!! info
`#!lua ui_missionInfo.closeDialogue()` must be used to close a dialogue.
Make sure you call this function when any button is pressed.
-391
View File
@@ -1,391 +0,0 @@
!!! warning "This site is under construction!"
This site is being actively worked on.
Feel you could help? Please do by clicking on the page with a pencil on the right!
This can be done any page too.
# BeamNG.drive Code Snippets
## Lua Code Snippets
### World
#### Drawing a marker & Vehicle detection
Drawing markers in the map can be one of the best ways to indicate to the user that there is some form of interaction that they can do there.
Drawing a marker is fairly easy. Here is an example of how the bus route marker is drawn:
```lua
local function createBusMarker(markerName)
local marker = createObject('TSStatic')
marker:setField('shapeName', 0, "art/shapes/interface/position_marker.dae")
marker:setPosition(vec3(0, 0, 0))
marker.scale = vec3(1, 1, 1)
marker:setField('rotation', 0, '1 0 0 0')
marker.useInstanceRenderData = true
marker:setField('instanceColor', 0, '1 1 1 0')
marker:setField('collisionType', 0, "Collision Mesh")
marker:setField('decalType', 0, "Collision Mesh")
marker:setField('playAmbient', 0, "1")
marker:setField('allowPlayerStep', 0, "1")
marker:setField('canSave', 0, "0")
marker:setField('canSaveDynamicFields', 0, "1")
marker:setField('renderNormals', 0, "0")
marker:setField('meshCulling', 0, "0")
marker:setField('originSort', 0, "0")
marker:setField('forceDetail', 0, "-1")
marker.canSave = false
marker:registerObject(markerName)
scenetree.MissionGroup:addObject(marker)
return marker
end
-- this can then be called in a loop to setup your markers.
-- NOTE: You should only do this once as part of your setup and not called on each frame.
if #markers == 0 then
for k,v in pairs(nameMarkers) do
local mk = scenetree.findObject(v)
if mk == nil then
log('I', logTag,'Creating marker '..tostring(v))
mk = createBusMarker(v)
ScenarioObjectsGroup:addObject(mk.obj)
end
table.insert(markers, mk)
end
end
```
Here is a custom marker example from [BeamNG-FuelStations](https://github.com/BeamMP/BeamNG-FuelStations/tree/master):
```lua
local stations = [
{ "location": [ -778.813, 485.973, 23.46 ], "type":"gas" },
{ "location": [ 617.164, -192.107, 53.2 ], "type":"ev" },
]
local function IsEntityInsideArea(pos1, pos2, radius)
return pos1:distance(pos2) < radius
end
local onUpdate = function (dt)
for k, spot in pairs(stations) do -- loop through all spots on the current map
local bottomPos = vec3(spot.location[1], spot.location[2], spot.location[3])
local topPos = bottomPos + vec3(0,0,2) -- offset vec to get top position (2m tall)
local spotInRange = false -- is this spot in range? used for color
local spotCompatible = false -- is this spot compatible?
if activeVeh then -- we have a car and its ours (if in mp)
local vehPos = activeVeh:getPosition()
spotInRange = IsEntityInsideArea(vec3(vehPos.x, vehPos.y,vehPos.z), bottomPos, 1.5)
spotCompatible = activeFuelType == "any" or spot.type == "any" or activeFuelType == spot.type
end
local spotColor = (spotInRange and spotCompatible) and activeColorMap[spot.type] or inactiveColorMap[spot.type] or ColorF(1,1,1,0.5)
debugDrawer:drawCylinder(bottomPos:toPoint3F(), topPos:toPoint3F(), 1, spotColor) --bottom, top, radius, color
end
end
```
### UI snippets
#### Toast Notifications, Top right of screen
<figure class="image image_resized" style="width:75%" markdown>
![image](https://github.com/StanleyDudek/Docs/assets/49531350/c8a87842-b95a-4eca-84dc-93072ecc9158)
</figure>
```lua
--guihooks.trigger('toastrMsg', {type, title, msg, config = {timeOut}})
guihooks.trigger('toastrMsg', {type = "info", title = "Info Message:", msg = "Info Message Text Here", config = {timeOut = 5000}})
guihooks.trigger('toastrMsg', {type = "warning", title = "Warning Message:", msg = "Warning Message Text Here", config = {timeOut = 5000}})
guihooks.trigger('toastrMsg', {type = "error", title = "Error Message:", msg = "Error Message Text Here", config = {timeOut = 5000}})
```
#### Message notifications, top left of screen by default in Messages app
This requires the 'Messages' or 'Messages & Tasks' UI app. Icons can be found at `ui\ui-vue\src\assets\fonts\bngIcons\svg\`
<figure class="image image_resized" style="width:75%" markdown>
![image](https://github.com/StanleyDudek/Docs/assets/49531350/6baef813-50cb-43c3-9c59-0de550b014b6)
</figure>
```lua
--guihooks.trigger('Message', {msg, ttl, category, icon})
--ui_message(msg, ttl, category, icon)
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_upward", icon = "arrow_upward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_downward", icon = "arrow_downward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "flag", icon = "flag"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "check", icon = "check"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "check_circle", icon = "check_circle"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "warning", icon = "warning"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "error", icon = "error"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "directions_car", icon = "directions_car"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "star", icon = "star"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "timeline", icon = "timeline"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "save", icon = "save"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "settings", icon = "settings"})
```
#### Center large or small display flash
<figure class="image image_resized" style="width:75%" markdown>
![image](https://github.com/StanleyDudek/Docs/assets/49531350/d0cf754f-83f8-4d15-9159-27350da127de)
</figure>
<figure class="image image_resized" style="width:75%" markdown>
![image](https://github.com/StanleyDudek/Docs/assets/49531350/1df6fc9b-756f-484e-b8d9-5df346dc4c26)
</figure>
```lua
--guihooks.trigger('ScenarioFlashMessage', {{msg, ttl, sound, big}} ) -- requires RaceCountdown ui app
guihooks.trigger('ScenarioFlashMessage', {{"Message", 5.0, 0, true}} )
guihooks.trigger('ScenarioFlashMessage', {{"Message Text Here", 5.0, 0, false}} )
--countdown example, when all executed at once, the items are queued and will follow eachother after the previous ttl expires
guihooks.trigger('ScenarioFlashMessage', {{"3", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown1')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"2", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown2')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"1", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown3')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"GO!", 3.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_CountdownGo')", true}})
--another sound example
guihooks.trigger('ScenarioFlashMessage', {{"Teleported!", 3.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Checkpoint')", false}})
```
#### Center mid-size persistent display
This requires the 'Race Realtime Display' UI app.
<figure class="image image_resized" style="width:75%" markdown>
![image](https://github.com/StanleyDudek/Docs/assets/49531350/6290e018-6b3d-4674-98f2-34282a723258)
</figure>
```lua
--guihooks.trigger('ScenarioRealtimeDisplay', {msg = msg} ) -- requires Race Realtime Display ui app
guihooks.trigger('ScenarioRealtimeDisplay', {msg = "Message Text Here"} )
--these messages persist, clear with a blank string
--if you are running live data, this is a good one to update rapidly (think timers, distance calcs, et cetera)
guihooks.trigger('ScenarioRealtimeDisplay', {msg = ""} )
```
#### Confirmation Dialog
ConfirmationDialog is a simplistic popup with up to two buttons.
```lua
-- Open a ConfirmationDialog with a title, body text, and up to two buttons
guihooks.trigger("ConfirmationDialogOpen",
"Example Title",
"Example Body Text",
"Okay",
"", --gelua. empty string
"Cancel",
"" --gelua
)
-- Close any open ConfirmationDialog with the provided title
guihooks.trigger("ConfirmationDialogClose", "Example Title")
```
<figure class="image image_resized" style="width:75%" markdown>
![Example of a ConfirmationDialog](../../assets/content/ConfirmationDialog.png)
</figure>
Both fields of a button must be strings in order for the button to appear.
If the Okay button is provided, pressing the *OK / Primary action* action is equivalent to pressing the Okay button.
If the Cancel button is provided, pressing the *Menu* action is equivalent to pressing the Cancel button.
HTML is supported and can be used to add images/icons, for example.
Multiple can be displayed at once, displayed sequentially.
!!! bug
Providing no buttons prevents the player from escaping the dialog without using the console.
!!! bug
The SDF parts of the Minimap UI app remain visible while a ConfirmationDialog is active.
`#!lua guihooks.trigger('ShowApps', false)` to hide UI apps can be used as a hacky workaround.
<figure class="image image_resized" style="width:75%" markdown>
![ConfirmationDialog being used for an inactivity kick system](../../assets/content/ConfirmationDialog_Example.png)
</figure>
#### introPopupTutorial
introPopupTutorial is a highly customizable popup that is largely defined with embedded HTML. It is standard to load from a standalone HTML file located in `/gameplay/tutorials/pages/*/content.html`.
```lua
guihooks.trigger("introPopupTutorial", {
{
content = readFile("/gameplay/tutorials/pages/template/content.html"):gsub("\r\n",""),
flavour = "onlyOk"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown>
![The introPopupTutorial snippet displayed in BeamNG.drive](../../assets/content/introPopupTutorial.png)
</figure>
Flavours controls which buttons are displayed. Four flavours exist:
* `withLogbook`
* Buttons: Career Logbook, Okay
* `onlyOk`
* Buttons: Okay
* `onlyLogbook`
* Buttons: Career Logbook
* `noButtons`
* Provides no buttons
!!! warning
When using the noButtons flavour on the page, providing no extra JavaScript in the page content to close the popup causes a softlock. Pages are not combined into one popup in this flavour. It is not recommended to use this flavour.
If multiple pages are provided, or the hook is triggered multiple times, then the pages are combined into the same popup. If the hook is triggered while a introPopup is active, or when a different introPopup type has already been triggered, then it is displayed in a separate popup after the existing popup is closed.
#### introPopupCareer
introPopupCareer is an easy to use, but open ended popup that supports embedding HTML, if needed.
Flavours control which buttons are displayed and the default image aspect ratio. Four flavours exist:
* `default`
* Default image aspect ratio: 16x9
* Buttons: Later, Okay
* `welcome`
* Default image aspect ratio: 16x9
* Buttons: Career Logbook, Okay
* `branch-info`
* Default image aspect ratio: 16x9
* Buttons: Career Logbook, Okay
* `garage`
* Buttons: Later, Okay
```lua
guihooks.trigger("introPopupCareer", {
{
title = "Example title",
text = "Example text",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
flavour = "default"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown>
![The introPopupCareer snippet displayed in BeamNG.drive](../../assets/content/introPopupCareer.png)
</figure>
If multiple pages are provided, or the hook is triggered multiple times, then the pages are combined into the same popup. If the hook is triggered while a introPopup is active, or when a different introPopup type has already been triggered, then it is displayed in a separate popup after the existing popup is closed.
!!! bug
The background blur has a minimum height, causing popups with short content to have excess blur below its window. Two main workarounds exist:
* Repeat `\n` and end with `#!html <div />` until the window covers the blur
* Use an empty or missing `image` path and adjust the aspect ratio until the window covers the blur
#### introPopupMission
introPopupMission is almost identical to introPopupCareer, but needs buttons to be defined rather than picking a preset for buttons.
Button styles are combined as *bng-button-*`style`. Built-in button styles are:
* `main` - orange
* `secondary` - cyan
* `attention` - red
* `white` - white
* `link` - translucent
* `outline` - orange outline
```lua
guihooks.trigger('introPopupMission', {
title = "introPopupMission title",
text = "introPopupMission description",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
buttons = {
{ default=true, class="main", label="main button", clickLua="" },
{ default=false, class="secondary", label="secondary button", clickLua="" },
{ default=false, class="attention", label="attention button", clickLua="" },
{ default=false, class="white", label="white button", clickLua="" },
{ default=false, class="link", label="link button", clickLua="" },
{ default=false, class="outline", label="outline button", clickLua="" }
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown>
![The introPopupMission snippet displayed in BeamNG.drive](../../assets/content/introPopupMission.png)
</figure>
If multiple pages are provided, or the hook is triggered multiple times, then the pages are combined into the same popup. If the hook is triggered while a introPopup is active, or when a different introPopup type has already been triggered, then it is displayed in a separate popup after the existing popup is closed.
!!! bug
The background blur has a minimum height, causing popups with short content to have excess blur below its window. Two main workarounds exist:
* Repeat `\n` and end with `#!html <div />` until the window covers the blur
* Use an empty or missing `image` path and adjust the aspect ratio until the window covers the blur
#### Dialogue
Dialogue is used in the *A Rocky Start* campaign to display information about a mission. It is a centered, vertically aligned popup with a specific layout. It does not support embedding HTML.
```lua
ui_missionInfo.openDialogue({
title = "Dialogue title",
type = "Custom", -- isn't actually displayed
typeName = "typeName",
data = {
{label = "objective", value = "reward"}
-- add more...
},
buttons = {
{action = "accept", text = "Accept", cmd = ""},
{action = 'decline',text = "Decline", cmd = ""}
-- add more...
}
})
ui_missionInfo.closeDialogue()
```
<figure class="image image_resized" style="width:75%" markdown>
![The Dialogue snippet displayed in BeamNG.drive](../../assets/content/Dialogue.png)
</figure>
Only one Dialogue can be displayed at once. Any existing Dialogue is overridden.
!!! info
`#!lua ui_missionInfo.closeDialogue()` must be used to close a dialogue.
Make sure you call this function when any button is pressed.
## IMGUI Code Snippets
todo
## CEF UI Code Snippets
todo
@@ -1171,14 +1171,419 @@ Triggered when a player sends a chat message. When cancelled, it will not show t
Arguments: `player_id: number`, `vehicle_id: number`, `data: string`
Cancellable: YES
Triggered when a player spawns a new vehicle. The `data` argument contains the car's configuration and positional/rotational data for the vehicle as a json string.
Triggered when a player spawns a new vehicle. Note that vehicle swaps/replacements instead fire [`onVehicleEdited`](#onvehicleedited). The `data` argument contains the car's configuration and positional/rotational data for the vehicle as a json string.
<details>
<summary>Example <code>data</code> value</summary>
The data string begins with a unique vehicle identifier, which is the player's ID, a hyphen, and then the vehicle ID. This is followed by a JSON object containing information about the vehicles configuration and positioning.
```
0-0: {
"abs": "realistic",
"ign": 3,
"jbm": "van",
"pid": 0,
"pos": [
907.93902587891,
773.50201416016,
238.87800598145
],
"pro": "0",
"rot": [
0,
0,
0.99999994039536,
0
],
"vcf": {
"licenseName": "H30 9VV",
"mainPartName": "van",
"mainPartPath": "/van",
"model": "van",
"paints": [
{
"baseColor": [
0.21999999880791,
0.37000000476837003,
0.33000001311302,
1.2000000476837
],
"clearcoat": 0,
"clearcoatRoughness": 0,
"metallic": 0,
"roughness": 0.070000000298023
},
{
"baseColor": [
0.62300002574921,
0.62300002574921,
0.62300002574921,
1.2000000476837
],
"clearcoat": 0.80000001192093,
"clearcoatRoughness": 0.070000000298023,
"metallic": 0.80000001192093,
"roughness": 0.64999997615814
},
{
"baseColor": [
0.21999999880791,
0.37000000476837003,
0.33000001311302,
1.2000000476837
],
"clearcoat": 0,
"clearcoatRoughness": 0,
"metallic": 0,
"roughness": 0.070000000298023
}
],
"partConfigFilename": "vehicles/van/h15_xt_passenger.pc",
"parts": {
"brakepad_F": "brakepad_F_premium",
"brakepad_R": "brakepad_R_premium",
"gps": "",
"licenseplate_design_2_1": "",
"linelock": "",
"load_seat_FR": "",
"n2o_system": "",
"paint_design": "van_skin_twotone",
"pickup_engine_v8_ecu": "pickup_engine_v8_ecu",
"pickup_engine_v8_internals": "pickup_engine_v8_internals",
"pickup_enginemounts": "pickup_enginemounts",
"pickup_oilpan_v8": "pickup_oilpan_v8",
"pickup_reversewarn": "",
"pickup_sparetire": "pickup_sparetire_5l",
"pickup_towhitch": "",
"skin_glass": "van_skin_glass_tint",
"skin_interior": "van_skin_interior_black",
"soundscape_horn": "soundscape_horn_115",
"tire_F_16x7_alt": "tire_F_225_75_16_alt_standard",
"tire_R_16x7_alt": "tire_R_225_75_16_alt_standard",
"van_ABS": "van_ABS",
"van_ESC": "",
"van_ac": "van_ac",
"van_body": "van_body_passenger",
"van_brake_F": "van_brake_F",
"van_brake_R": "van_brake_R_drum",
"van_bumper_F": "van_bumper_F_altb",
"van_bumper_F_lip": "",
"van_bumper_R": "van_bumper_R_altb",
"van_bumper_accessory_F": "",
"van_bumpersignal_FL": "van_bumpersignal_FL",
"van_bumpersignal_FR": "van_bumpersignal_FR",
"van_coilover_IFS": "van_coilover_IFS",
"van_converter": "van_converter",
"van_differential_F": "",
"van_differential_R": "van_differential_R",
"van_door_FL": "van_door_FL",
"van_door_FR": "van_door_FR",
"van_doordetent_FL": "van_doordetent_FL",
"van_doordetent_FR": "van_doordetent_FR",
"van_doordetent_RL": "van_doordetent_RL",
"van_doordetent_RR": "van_doordetent_RR",
"van_doorglass_L": "van_doorglass_L",
"van_doorglass_R": "van_doorglass_R",
"van_doorpanel_FL": "van_doorpanel_FL",
"van_doorpanel_FR": "van_doorpanel_FR",
"van_driveshaft_R": "van_driveshaft_R",
"van_engine": "van_engine_v8_4.5",
"van_exhaust_v8": "van_exhaust_v8",
"van_fascia_F": "van_fascia_F_high",
"van_fender_L": "van_fender_L",
"van_fender_R": "van_fender_R",
"van_fenderflare_FL": "",
"van_fenderflare_FR": "",
"van_fenderflare_RL": "",
"van_fenderflare_RR_sidedoor": "",
"van_finaldrive_R": "van_finaldrive_R_355",
"van_frame": "van_frame",
"van_fueltank": "van_fueltank",
"van_header": "van_exhmanifold",
"van_headlight_L_high": "van_headlight_L_high",
"van_headlight_R_high": "van_headlight_R_high",
"van_hood": "van_hood",
"van_hub_F": "van_hub_F_5",
"van_hub_R": "van_hub_R_5",
"van_intake_v8": "van_intake_v8",
"van_intcarpet_roof": "van_intcarpet_roof",
"van_interior": "van_interior",
"van_lettering_doors_F": "van_lettering_doors_F_h15",
"van_lettering_reardoor_L": "van_lettering_gavril_reardoor_L",
"van_lettering_reardoor_R": "van_lettering_h15_xt_reardoor_R",
"van_licenseplate_F": "van_licenseplate_F",
"van_licenseplate_R": "van_licenseplate_R",
"van_lightbar": "",
"van_mirror_L": "van_mirror_L",
"van_mirror_R": "van_mirror_R",
"van_mod": "",
"van_muffler": "van_muffler",
"van_power_steering": "",
"van_radiator": "van_radiator",
"van_radio": "van_radio",
"van_reardoor_L": "van_reardoor_L",
"van_reardoor_R": "van_reardoor_R",
"van_reardoorglass_L": "van_reardoorglass_L",
"van_reardoorglass_R": "van_reardoorglass_R",
"van_reardoorpanel_L": "van_reardoorpanel_L",
"van_reardoorpanel_R": "van_reardoorpanel_R",
"van_rollcage": "",
"van_roof": "van_roof",
"van_roof_accessory": "",
"van_runningboard": "",
"van_seat_1R": "van_seat_1R",
"van_seat_2R": "van_seat_2R",
"van_seat_3R": "van_seat_3R",
"van_seat_FL": "van_seat_FL",
"van_seat_FR": "van_seat_FR",
"van_shifter": "van_shifter_A",
"van_shock_R": "van_shock_R",
"van_sidedoor_FR": "van_sidedoor_FR_alt",
"van_sidedoor_RR": "van_sidedoor_RR_alt",
"van_sidedoorglass_FR": "van_sidedoorglass_FR",
"van_sidedoorglass_RR": "van_sidedoorglass_RR",
"van_sidedoorpanel_FR": "van_sidedoorpanel_FR",
"van_sidedoorpanel_RR": "van_sidedoorpanel_RR",
"van_sideglass_FL": "van_sideglass_FL",
"van_sideglass_ML": "van_sideglass_ML",
"van_sideglass_RL": "van_sideglass_RL",
"van_sideglass_RR": "van_sideglass_RR",
"van_snorkel": "",
"van_spring_R": "van_spring_R",
"van_steer": "van_steer",
"van_steering": "van_steering",
"van_suspension_F": "van_IFS",
"van_suspension_R": "van_axle_R",
"van_swaybar_F": "van_swaybar_F",
"van_swaybar_R": "",
"van_taillight_L": "van_taillight_L",
"van_taillight_R": "van_taillight_R",
"van_taillightguard_L": "",
"van_taillightguard_R": "",
"van_transfer_case": "van_transfer_case_RWD",
"van_transmission": "van_transmission_4A",
"van_tubs": "van_tubs",
"van_valance_F": "van_valance_F",
"van_wheeldata_F": "van_wheeldata_F",
"van_wheeldata_R": "van_wheeldata_R",
"van_windshield": "van_windshield",
"wheel_F_5": "wheel_25a_16x7_5_F",
"wheel_R_5": "wheel_25a_16x7_5_R"
},
"vars": {}
},
"vid": 29339
}
```
</details>
##### `onVehicleEdited`
Arguments: `player_id: number`, `vehicle_id: number`, `data: string`
Cancellable: YES
Triggered when a player edits their vehicle and applies the edit. The `data` argument contains the car's updated configuration as a json string but does **not** include positional or rotational data. You can use [MP.GetPositionRaw](#mpgetpositionrawpid-number-vid-number-tablestring) to get positional and rotational data.
Triggered when a player edits or replaces their vehicle. The `data` argument contains the car's updated configuration as a json string but does **not** include positional or rotational data. You can use [MP.GetPositionRaw](#mpgetpositionrawpid-number-vid-number-tablestring) to get positional and rotational data.
<details>
<summary>Example <code>data</code> value</summary>
The data string begins with a unique vehicle identifier, which is the player's ID, a hyphen, and then the vehicle ID. This is followed by a JSON object containing information about the vehicles configuration.
```
0-0: {
"abs": "realistic",
"ign": 3,
"jbm": "van",
"pid": 0,
"pro": "0",
"vcf": {
"licenseName": "P60 1EP",
"mainPartName": "van",
"mainPartPath": "/van",
"model": "van",
"paints": [
{
"baseColor": [
0.40000000596046,
0.050000000745058,
0.050000000745058,
1.2000000476837
],
"clearcoat": 0,
"clearcoatRoughness": 0,
"metallic": 0,
"roughness": 0.070000000298023
},
{
"baseColor": [
0.40000000596046,
0.050000000745058,
0.050000000745058,
1.2000000476837
],
"clearcoat": 0,
"clearcoatRoughness": 0,
"metallic": 0,
"roughness": 0.070000000298023
},
{
"baseColor": [
0.40000000596046,
0.050000000745058,
0.050000000745058,
1.2000000476837
],
"clearcoat": 0,
"clearcoatRoughness": 0,
"metallic": 0,
"roughness": 0.070000000298023
}
],
"partConfigFilename": "vehicles/van/h15_passenger.pc",
"parts": {
"brakepad_F": "brakepad_F_premium",
"brakepad_R": "brakepad_R_premium",
"gps": "",
"hubcap_F_16": "hubcap_09c_F_altd",
"hubcap_R_16": "hubcap_09c_R_altd",
"licenseplate_design_2_1": "",
"linelock": "",
"load_seat_FR": "",
"n2o_system": "",
"paint_design": "",
"pickup_engine_v8_ecu": "pickup_engine_v8_ecu_late",
"pickup_engine_v8_internals": "pickup_engine_v8_internals",
"pickup_enginemounts": "pickup_enginemounts",
"pickup_oilpan_v8": "pickup_oilpan_v8",
"pickup_reversewarn": "",
"pickup_sparetire": "pickup_sparetire_6l",
"pickup_towhitch": "",
"skin_glass": "",
"skin_interior": "van_skin_interior_ivory",
"soundscape_horn": "soundscape_horn_115",
"tire_F_16x7_alt": "tire_F_225_75_16_alt_standard",
"tire_R_16x7_alt": "tire_R_225_75_16_alt_standard",
"trimring_F_16x7": "",
"trimring_R_16x7": "",
"van_ABS": "van_ABS",
"van_ac": "van_ac",
"van_body": "van_body_passenger",
"van_brake_F": "van_brake_F",
"van_brake_R": "van_brake_R",
"van_bumper_accessory_F_late": "",
"van_bumper_F": "van_bumper_F_late_alt",
"van_bumper_F_lip_late": "",
"van_bumper_R": "van_bumper_R_late_alt",
"van_coilover_IFS": "van_coilover_IFS",
"van_converter": "van_converter",
"van_differential_F": "",
"van_differential_R": "van_differential_R",
"van_door_FL": "van_door_FL",
"van_door_FR": "van_door_FR",
"van_doordetent_FL": "van_doordetent_FL",
"van_doordetent_FR": "van_doordetent_FR",
"van_doordetent_RL": "van_doordetent_RL",
"van_doordetent_RR": "van_doordetent_RR",
"van_doorglass_L": "van_doorglass_L",
"van_doorglass_R": "van_doorglass_R",
"van_doorpanel_FL": "van_doorpanel_FL",
"van_doorpanel_FR": "van_doorpanel_FR",
"van_driveshaft_R": "van_driveshaft_R",
"van_engine": "van_engine_v8_4.5",
"van_ESC": "van_ESC",
"van_exhaust_v8": "van_exhaust_v8",
"van_fascia_F": "van_fascia_F_late",
"van_fender_L": "van_fender_L",
"van_fender_R": "van_fender_R",
"van_fenderflare_FL": "",
"van_fenderflare_FR": "",
"van_fenderflare_RL": "",
"van_fenderflare_RR_sidedoor": "",
"van_finaldrive_R": "van_finaldrive_R_355",
"van_frame": "van_frame",
"van_fueltank": "van_fueltank",
"van_grille_F_late": "van_grille_F_late",
"van_header": "van_exhmanifold",
"van_headlight_L_late": "van_headlight_L_late",
"van_headlight_R_late": "van_headlight_R_late",
"van_hood": "van_hood_late",
"van_hub_F": "van_hub_F_6",
"van_hub_R": "van_hub_R_6",
"van_intake_v8": "van_intake_v8_late",
"van_intcarpet_roof": "van_intcarpet_roof",
"van_interior": "van_interior",
"van_lettering_doors_F": "van_lettering_doors_F_h15",
"van_lettering_reardoor_L": "van_lettering_gavril_reardoor_L",
"van_lettering_reardoor_R": "van_lettering_h15_reardoor_R",
"van_licenseplate_F_late": "van_licenseplate_F_late",
"van_licenseplate_R_late": "van_licenseplate_R_late",
"van_lightbar": "",
"van_mirror_L": "van_mirror_L",
"van_mirror_R": "van_mirror_R",
"van_mod": "",
"van_muffler": "van_muffler",
"van_power_steering": "",
"van_radiator": "van_radiator",
"van_radio": "van_radio",
"van_reardoor_L": "van_reardoor_L",
"van_reardoor_R": "van_reardoor_R",
"van_reardoorglass_L": "van_reardoorglass_L",
"van_reardoorglass_R": "van_reardoorglass_R",
"van_reardoorpanel_L": "van_reardoorpanel_L",
"van_reardoorpanel_R": "van_reardoorpanel_R",
"van_rollcage": "",
"van_roof": "van_roof",
"van_roof_accessory": "",
"van_runningboard": "",
"van_seat_1R": "van_seat_1R",
"van_seat_2R": "van_seat_2R",
"van_seat_3R": "van_seat_3R",
"van_seat_FL": "van_seat_FL",
"van_seat_FR": "van_seat_FR",
"van_shifter": "van_shifter_A",
"van_shock_R": "van_shock_R",
"van_sidedoor_FR": "van_sidedoor_FR_alt",
"van_sidedoor_RR": "van_sidedoor_RR_alt",
"van_sidedoorglass_FR": "van_sidedoorglass_FR",
"van_sidedoorglass_RR": "van_sidedoorglass_RR",
"van_sidedoorpanel_FR": "van_sidedoorpanel_FR",
"van_sidedoorpanel_RR": "van_sidedoorpanel_RR",
"van_sideglass_FL": "van_sideglass_FL",
"van_sideglass_ML": "van_sideglass_ML",
"van_sideglass_RL": "van_sideglass_RL",
"van_sideglass_RR": "van_sideglass_RR",
"van_snorkel": "",
"van_spring_R": "van_spring_R",
"van_steer": "van_steer_facelift",
"van_steering": "van_steering",
"van_suspension_F": "van_IFS",
"van_suspension_R": "van_axle_R",
"van_swaybar_F": "van_swaybar_F",
"van_swaybar_R": "",
"van_taillight_L": "van_taillight_L",
"van_taillight_R": "van_taillight_R",
"van_taillightguard_L": "",
"van_taillightguard_R": "",
"van_transfer_case": "van_transfer_case_RWD",
"van_transmission": "van_transmission_4A",
"van_tubs": "van_tubs",
"van_valance_F": "van_valance_F_late",
"van_wheeldata_F": "van_wheeldata_F",
"van_wheeldata_R": "van_wheeldata_R",
"van_windshield": "van_windshield",
"wheel_F_6": "steelwheel_02b_16x7_F",
"wheel_R_6": "steelwheel_02b_16x7_R"
},
"vars": {}
}
}
```
</details>
##### `onVehicleDeleted`