Configuration

8 min readUpdated 2 weeks ago

Overview

Config is split into files:

  • shared/config.lua: General settings, board types, dynamic boards, camera
  • shared/config_notes.lua: Note variants and item requirements
  • shared/config_locations.lua: Static board placements
  • server/config_server.lua: Discord webhook URLs

General

shared/config.lua
1Config.Locale = 'en'
2Config.Theme  = 'default'
3Config.Debug  = false
  • Locale: Language code for translations
  • Theme: theme of the board and note editor. 'default', 'wasteland', 'cyberpunk', 'noir' or 'fantasy'
  • Debug: Console output. Keep off in production.
  • BoardRenderScale: Board surface sharpness, documented under Board Toolbar

UI Theme

shared/config.lua
1Config.UITheme = {
2    preset = nil,
3    colors = {
4        primary = nil,
5        accent = nil,
6        background = nil,
7        surface = nil,
8        text = nil,
9    },
10}
  • preset: theme preset for this resource. nil follows the shared theme set in ml_bridge
  • colors: CSS hex values for single colors. Any nil value follows the shared theme

Defaults

Global defaults applied to all boards unless overridden per-location.

shared/config.lua
1Config.Defaults = {
2    RenderDistance    = 30.0,
3    ViewDistance      = 4.0,
4    EditDistance      = 2.0,
5    MaxItems         = 15,
6    MaxNotesPerPlayer = 3,
7    CleanupInterval  = 30,
8}
  • RenderDistance: Prop spawn distance (meters)
  • ViewDistance: Distance to read notes
  • EditDistance: Distance to add/remove notes
  • MaxItems: Max notes on a board
  • MaxNotesPerPlayer: Per-player note limit
  • CleanupInterval: Auto-cleanup for expired notes (minutes)

Note Duration

shared/config.lua
1Config.Duration = {
2    Min     = 1,
3    Max     = 72,
4    Default = 24,
5}

Notes expire automatically after the configured duration (in hours).

Items

shared/config.lua
1Config.UseItems          = false
2Config.UseMLCamera       = false
3Config.MLCameraPhotoItem = 'photo'
  • UseItems: true makes players use up the item of the note style to place a note. Off by default
  • UseMLCamera: Enables photo capture integration
  • MLCameraPhotoItem: Item name for photo notes

Note Editor

Styles offered while a note is being written.

shared/config.lua
1Config.AllowTape   = true
2Config.EditorFonts  = { 'hand1', 'hand2', 'marker' }
3Config.EditorColors = { '#d32f2f', '#222222', '#1565c0', '#2e7d32', '#f9a825', '#6a1b9a' }
  • AllowTape: Offers tape as an alternative to the pushpin when a note is placed
  • EditorFonts: Handwriting styles in the editor. Available: 'hand1' (Caveat), 'hand2' (Shadows Into Light), 'marker' (Permanent Marker), 'hand3' (Patrick Hand)
  • EditorColors: Ink colours in the editor. Any list of hex colours

Board Toolbar

Tools available while looking at a board: move, wire, pen, pen eraser, stamp and eraser.

shared/config.lua
1Config.ToolbarKey       = { control = 29, label = 'B' }
2Config.WireColors       = { '#c62828', '#141414', '#1565c0', '#2e7d32' }
3Config.MaxConnections   = 30
4Config.PenColors        = { '#141414', '#c62828', '#1565c0', '#2e7d32' }
5Config.AllowNoteDrawing = true
6Config.BoardRenderScale = 1.5
  • ToolbarKey: Control id that opens the toolbar and the label shown in the on-screen hint
  • WireColors: Wire colours offered by the wire tool. The first entry is pre-selected
  • MaxConnections: Maximum wires strung on a single board
  • PenColors: Pen colours offered by the drawing tool. The first entry is pre-selected
  • AllowNoteDrawing: Lets anyone who may pin a note also draw on a note. Drawing on the board surface itself follows the 'draw' permission
  • BoardRenderScale: Board surface sharpness, 1.0 to 1.5. Higher is crisper and costs VRAM while a board is open

Stamps

Stamps are pressed onto a note from the toolbar.

shared/config.lua
1Config.Stamps = {
2    { id = 'evidence', label = 'EVIDENCE', color = '#c62828', size = 'medium' },
3    { id = 'urgent',   label = 'URGENT',   color = '#c62828', size = 'medium' },
4    { id = 'verified', label = 'VERIFIED', color = '#2e7d32', size = 'medium' },
5    { id = 'closed',   label = 'CLOSED',   color = '#37474f', size = 'medium' },
6}
7
8Config.StampsRequireItem = false
9Config.EvidenceTags      = true
  • id: Internal key, also stored on the placed stamp
  • label: Text printed on the stamp
  • color: Ink colour
  • image: Optional image URL. Replaces the inked text when set
  • size: Starting size: 'small', 'medium' or 'large'. Resized in game with Shift and the mouse wheel
  • StampsRequireItem: Requires an inventory item to press a stamp
  • EvidenceTags: Numbers every 'evidence' stamp in placement order

Command

shared/config.lua
1Config.Command = {
2    Enabled       = false,
3    Name          = 'postit',
4    SkipItemCheck = true,
5}
  • Enabled: Turns the chat command on
  • Name: Chat command to place a note without targeting a board
  • SkipItemCheck: If true, the command bypasses item requirements

Dynamic Boards

Players can place boards from inventory items.

shared/config.lua
1Config.EnableDynamicBoards      = true
2Config.MaxBoardsPerPlayer       = 30
3Config.BoardPickupPolicy        = 'owner'
4Config.PlacementRaycastDistance  = 8.0
  • EnableDynamicBoards: Lets players place boards from inventory items
  • MaxBoardsPerPlayer: Max boards a player can place
  • BoardPickupPolicy: 'owner' (only the placer) or 'anyone'
  • PlacementRaycastDistance: Max placement distance (anti-abuse)

Board Types

Each board type maps an inventory item to a prop model.

shared/config.lua
1Config.BoardTypes = {
2    ['whiteboard_large'] = {
3        item                = 'whiteboard_large',
4        prop                = 'hei_prop_hei_muster_01',
5        label               = 'Large Board',
6        texture             = 'trucciolato',
7        replaceTexture      = { dict = 'script_rt_planning', name = 'hei_prop_hei_muster_01' },
8        maxItems            = 20,
9        spawnDistance       = 75.0,
10        interactionDistance = 3.0,
11        zOffset             = -0.5,
12    },
13    ['corkboard'] = {
14        item                = 'corkboard',
15        prop                = 'bkr_prop_clubhouse_blackboard_01a',
16        label               = 'Small Board',
17        texture             = 'cork',
18        replaceTexture      = { dict = 'prop_blackboard_01', name = 'bkr_prop_clubhouse_blackboard_01a' },
19        maxItems            = 12,
20        spawnDistance       = 75.0,
21        interactionDistance = 3.0,
22        zOffset             = 0.0,
23    },
24}
  • prop: model spawned when a player places the item
  • texture: background key from Config.BoardTextures, so the same prop can read as cork or as a whiteboard
  • replaceTexture: the texture of the prop the board is drawn on. Copy the pair shipped for a model. A prop only works as a board if it has such a texture

Board Textures

Selectable backgrounds for board surfaces.

shared/config.lua
1Config.BoardTextures = {
2    { label = 'Cork',        value = 'cork',        url = '...' },
3    { label = 'Trucciolato', value = 'trucciolato', url = '...' },
4}

Note Variants

Defined in shared/config_notes.lua. Each variant specifies a type, required items, and background image.

shared/config_notes.lua
1Config.NoteVariants = {
2    {
3        id    = 1,
4        type  = 'postit',
5        label = 'Standard Yellow',
6        items = { 'sticky_note', 'sticky_note_yellow' },
7        image = { 'url1', 'url2' },
8    },
9    {
10        id    = 2,
11        type  = 'photo',
12        label = 'Evidence Photo',
13        items = { 'photo' },
14        image = 'url',
15    },
16    {
17        id      = 3,
18        type    = 'photo',
19        label   = 'Wanted Poster',
20        items   = { 'photo' },
21        frame   = 'poster_url',
22        ratio   = 1.4,
23        window  = { x = 18, y = 26, w = 64, h = 42 },
24        caption = { x = 14, y = 74, w = 72, h = 14 },
25    },
26}
  • type: 'postit' for text notes, 'photo' for image notes
  • items: Player needs ANY ONE of these items to place (consumed)
  • image: Background texture. String or array (random selection)
  • frame: Poster artwork drawn around the photo
  • window: Where the photo shows through the artwork, in percent
  • caption: Where the caption is written on the artwork, in percent

Static Locations

Boards placed permanently in the world via shared/config_locations.lua.

shared/config_locations.lua
1Config.Locations = {
2    {
3        id                = 'police_main_board',
4        model             = 'hei_prop_hei_muster_01',
5        coords            = vec4(450.30, -979.7, 30.4, 90.0),
6        currentBackground = 'cork',
7        replaceTexture    = { dict = 'script_rt_planning', name = 'hei_prop_hei_muster_01' },
8        -- jobView        = nil,
9        -- jobWrite       = { 'police', 'sheriff' },
10        -- jobClear       = { 'police' },
11        -- permissions    = { place = { 'police' }, draw = { 'police' }, clear = { 'police' } },
12        maxItems          = 30,
13        maxPerPlayer      = 5,
14        allowedVariants   = { 1, 2 },
15    },
16}
  • jobView: nil = everyone can read. Table of job names to restrict.
  • jobWrite: Jobs allowed to post notes
  • jobClear: Jobs allowed to clear the board
  • allowedVariants: Restrict which note types are available (by id from config_notes)
  • renderDistance: meters at which the board is drawn. Without it, Config.Defaults.RenderDistance is used

Board Permissions

Each board sets its own rule per action. Staff with the admin permission bypass every rule.

shared/config_locations.lua
1permissions = {
2    place         = 'all',
3    move          = 'own',
4    delete        = 'own',
5    clear         = { 'police' },
6    connect       = 'all',
7    erase_connect = 'own',
8    draw          = 'none',
9    erase_draw    = 'own',
10    stamp         = 'all',
11},
  • all: Anyone who can reach the board
  • own: Only the player who put that note, wire or drawing there. On clear, only the board owner
  • none: Staff only
  • { }: A job list, for example { 'police', 'sheriff' }

Actions left out of the table fall back to: place, connect and stamp open to everyone; move, delete, erase_connect and erase_draw limited to your own work; clear reserved to the board owner; draw staff only.

The same table is accepted on a board type in Config.BoardTypes, so player-placed boards can be gated the same way.

Camera

Camera framing applied when a player opens a board. CameraOverrides is keyed by prop model for per-model adjustments.

shared/config.lua
1Config.CameraDefaults = {
2    offset    = vec3(0.0, -1.8, 0.0),
3    yawOffset = 0.0,
4}
5
6Config.CameraOverrides = {
7    ['bkr_prop_clubhouse_blackboard_01a'] = {
8        offset    = vec3(0.0, -1.1, 0.0),
9        yawOffset = 0.0,
10        boardAxis = 'x',
11    },
12}
  • offset: camera position relative to the board face
  • yawOffset: extra rotation of the camera
  • CameraOverrides: per-model camera, keyed by prop model name. The file ships entries for the small board and the wooden board
  • boardAxis: local axis the board face lies on, 'x' or 'y'

Discord Webhooks

server/config_server.lua
1Config.Log = {
2    NotePlaced   = 'INSERT_WEBHOOK_LINK_HERE',
3    NoteDeleted  = 'INSERT_WEBHOOK_LINK_HERE',
4    BoardCleared = 'INSERT_WEBHOOK_LINK_HERE',
5    Exploits     = 'INSERT_WEBHOOK_LINK_HERE',
6}

Replace each placeholder with a Discord webhook URL. Set to false to disable that log entirely.

server/config_server.lua
1Exploits = false,   -- disabled, no log sent