Developer

2 min readUpdated Today

Overview

ML Board provides server exports for querying board state and handler hooks in the open/ folder for custom logic.

Server Exports

lua
1local boards = exports['ml_board']:GetActiveBoards()
2local count = exports['ml_board']:GetPlayerBoardCount(identifier)
  • GetActiveBoards(): Returns a table of all active dynamic (player-placed) boards
  • GetPlayerBoardCount(identifier): Returns the number of boards owned by a player

Server Handlers

Defined in open/server.lua.

open/server.lua
1function OpenServer.CanEditBoard(src, boardId)
2    return true -- return false to block editing
3end
4
5function OpenServer.OnContentSaved(src, boardId)
6    -- Triggered after a note is placed or removed
7end
  • CanEditBoard(src, boardId): Called before any edit action. Return false to block.
  • OnContentSaved(src, boardId): Fired after board content changes. Use for logging or syncing.
open/server.lua
1function OpenServer.CanEditBoard(src, boardId)
2    local job = Bridge.GetJob(src)
3    if job and job.name == 'police' then
4        return true
5    end
6    return false
7end

Client Handlers

Defined in open/client.lua.

open/client.lua
1function OpenClient.OnBoardOpen(boardId)
2    -- Triggered when a player opens a board UI
3end
4
5function OpenClient.OnBoardClose(boardId)
6    -- Triggered when the board UI is closed
7end
  • OnBoardOpen(boardId): Use for sounds, effects, or analytics
  • OnBoardClose(boardId): Cleanup or post-view logic

Permissions

Board access is controlled per-location in shared/config_locations.lua, not through handlers:

  • jobView: Jobs that can read the board (nil = everyone)
  • jobWrite: Jobs that can post notes
  • jobClear: Jobs that can clear all notes
  • allowedVariants: Restrict which note types are available (by id)

Each board also carries a permissions table with one rule per action, so pinning, moving, deleting, clearing, wiring, drawing and stamping are gated separately. Static boards take it in shared/config_locations.lua, player-placed boards take it on their entry in Config.BoardTypes. Values are 'all', 'own', 'none' or a job list, and the admin permission bypasses all of them.

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},