Skip to main content

Requirements

  • RedM with VORP or RSG, detected through the bundled framework bridge
  • oxmysql and a configured MySQL / MariaDB database with JSON column support
  • The built release package, including ui/dist/
No separate interaction framework is required. Keep the resource folder named dd_pinboard; the bundled image URLs and UI callbacks use that name.

Installation

1

Install the resource

Extract the release’s dd_pinboard folder into your server’s resources directory.
2

Set the start order

Start your framework and oxmysql before dd_pinboard in server.cfg.
3

Configure locations

Edit config/config.lua. Keep each board’s key unique and stable: changing it points to a different board. Set coordinates, labels, edit jobs and optional background or size restrictions.
4

Grant admin access

Add this permission for the server’s admin group if it should clear or seed boards:
5

Start and check

Start the resource and walk to a configured location. Database tables are created automatically; a board row is created on first open or when seeded. Keep Config.Debug = false on a production server.

Configuration

The following is the shipped config/config.lua for version 1.3.0. Restart the resource after changing Lua configuration.

Board locations

key identifies persistent content; label names the board; coords sets the interaction point. radius overrides the default interaction distance.
  • Omit editJobs to let everyone edit, or list the job names allowed to edit. Reading remains open to everyone.
  • Set bgStyle to cork, parchment, dark (wood), slate or linen to fix the surface and hide its selector.
  • Set size with w and h in board pixels to create a bounded board; omit it for an endless board.
  • Moving coordinates while retaining the key keeps the board’s content.
A fixed background overrides stored and preset backgrounds. Both the editor and server enforce board bounds.

Permissions and collaboration

Config.Permissions.edit is a server-side callback and can replace the default job check. Config.Permissions.admin gates admin commands with dd_pinboard.admin by default. Each editor sends changes after autosaveDebounceMs (2,000 ms by default). Card reservations expire after cardClaimTimeoutSeconds (30 seconds by default). There is no board-wide editing lock. showRemoteCursors controls pointer visibility and traffic; cursorUpdateHz sets its rate. No cursor traffic is sent while a player is alone. playerColors identifies participants. anonymizeCollaborators replaces character names with numbered visitors in the collaboration UI. cardColors supplies the note, pin, thread and pencil palette.

Limits and image hosts

Defaults allow 200 cards and 400 threads per board, 32 KiB of JSON per card, a maximum card side of 10,000 pixels and image URLs up to 1,024 characters. The server validates edits before accepting a batch. An empty allowedImageHosts permits any HTTP or HTTPS host. Entries permit the named host and its subdomains. Images still need to be reachable from every player’s client.
If you restrict image hosts and use the bundled investigation preset, include cfx-nui-dd_pinboard in the allow-list. Its pictures load from the resource itself.

Language

English and German are included in config/language.lua. Set DDLanguage there. To use the server-wide setr dd:language de setting instead, set DDLanguage to an empty string or nil; a non-empty per-resource value takes precedence. Add a translation table in that file for another language.

Commands and presets

Clear and seed also work in the server console without the leading slash. Command names are configurable. To load the bundled investigation board at the supplied showcase location:
Prepare your own layouts in config/showcase.lua. Presets contain cards, thread references, an optional background and viewport. Use the shipped crime_board data as the reference. The server applies the same card, image, payload and bounds validation used for player edits.
Successful seeding replaces the target board’s existing cards and threads and resets viewers to the new state. Clearing also resets viewers. Neither operation can be reversed with session Undo; back up database content you want to keep.
A rejected preset keeps existing content. Validation counts existing content while adding the preset, so a nearly full board can hit the card or thread cap. Prefer a fresh demonstration location, or back up and clear an existing board before seeding it. Unknown preset names are rejected. A location’s fixed surface takes precedence over the preset’s background.

Troubleshooting

Confirm the resource, framework and oxmysql started successfully. Check the configured coordinates and radius, the interaction key, and that the release includes ui/dist. The remote-open command requires both debug mode and admin permission.
Check the character’s job against editJobs or your custom permission callback. A card another player is using is reserved only for them; wait for release or its inactivity timeout.
Check that its URL points directly to an image accessible from the client. Review allowedImageHosts. For bundled preset images, keep the resource name dd_pinboard and permit cfx-nui-dd_pinboard when an allow-list is enabled.
The location may have a fixed bgStyle or bounded size. These restrictions apply to players and showcase presets.
Undo is local to the open session. Closing or a full resync clears it; edits by other players invalidate conflicting steps. A rejected batch, admin clear or seed can cause a full resync.
Check whether its key changed. Restore the original key or migrate the stored location_key as described in the developer reference. Merely changing coordinates does not create a new board.
See the developer reference for exports and database details.