Configuration

8 min readUpdated Today

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: UI theme
  • Debug: Console output. Keep off in production.
  • BoardRenderScale: Board surface sharpness, documented under Board Toolbar

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          = true
2Config.UseMLCamera       = false
3Config.MLCameraPhotoItem = 'photo'
  • UseItems: If true, players need the correct item to place a note (consumed on use)
  • 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        permissions         = { place = 'all', draw = 'own' },
13    },
14    ['corkboard'] = {
15        item                = 'corkboard',
16        prop                = 'prop_cork_board',
17        label               = 'Cork Board',
18        texture             = 'cork',
19        replaceTexture      = { dict = 'prop_cork_01', name = 'prop_cork_board' },
20        maxItems            = 20,
21        spawnDistance       = 75.0,
22        interactionDistance = 3.0,
23        zOffset             = -0.5,
24    },
25}
  • 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 surface the board is drawn on. name is the texture dictionary, which on a stock prop matches the model, and dict is the texture inside it. A prop only works as a board if it has one of its own

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)

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 = {}
  • offset: vec3 camera position relative to the board face
  • yawOffset: extra rotation applied to the camera
  • CameraOverrides: per-model overrides keyed by prop model name (empty by default)

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