Configuration
Overview
shared/config.lua: General settings, mode, item names, limits, post-it colors, book content, discoverables, command namesshared/config.lua: Cover, manual pages, encyclopedia categories, post-it colorsserver/config_server.lua: Logger backend and Discord webhook URLs
General
1Config.Debug = false
2Config.Locale = 'en'
3Config.SaveInterval = 10
4Config.DiaryMode = 'metadata'
5Config.DiaryItemName = 'diary'
6Config.TornPageItemName = 'diary_page'Debug: Console output for troubleshootingLocale: Language code for translations. Falls back toenwhen missingSaveInterval: Auto-save frequency in minutes. Only writes diaries flagged as dirtyDiaryMode: Storage model (see below)DiaryItemName: Inventory item name for the diaryTornPageItemName: Item name for torn/shared pages
Diary Mode
Config.DiaryMode controls how diary data is keyed and shared.
'metadata'(default)
The diary is a transferable physical object. Each diary item carries a unique serial in its metadata; all data is keyed on that serial. Whoever is currently holding the item can read it, write notes, and unlock discoveries, including players who received it as a gift, looted it, or stole it. The original creator is recorded for audit only and does not gate access.
'license'
The diary is bound to the player's identifier. The serial is derived as LICENSE-<identifier>, so any diary item the player picks up opens their personal logbook. Other players cannot read or modify it even if they hold a diary item that previously belonged to that license.
Limits
1Config.PersonalPageLimit = 15
2Config.MaxTextSize = 8192 -- 8 KB per text note
3Config.MaxDataUrlSize = 524288 -- 512 KB per drawing
4Config.MaxDiaryTotalSize = 4194304 -- 4 MB total per diaryPersonalPageLimit: Maximum number of user-written pages. Pages added by other scripts viaaddPersonalNotebypass this limit (see Developer page)MaxTextSize: Maximum byte size of a single text note's contentMaxDataUrlSize: Maximum byte size of a single drawing (base64 data URL)MaxDiaryTotalSize: Hard cap on the total combined size of all notes in a single diary, enforced on every save and external add
Admin Commands
1Config.Commands = {
2 unlockAll = { name = 'diary_unlockall', help = '...' },
3 unlock = { name = 'diary_unlock', help = '...' },
4 unlockCategory = { name = 'diary_unlockcat', help = '...' },
5 resetAll = { name = 'diary_reset', help = '...' },
6}unlockAll: Unlock every entry inConfig.Discoverablesfor the diary the admin is currently holdingunlock: Unlock a single entry by keyunlockCategory: Unlock every entry in a categoryresetAll: Clear every discovery for the diary the admin is currently holding
Permissions are checked via Bridge.HasPermission(source), which reads the ACE group configured in ml_bridge. Renaming a command here also renames the in-game command, useful for avoiding collisions or matching server conventions.
Post-It Colors
1Config.PostItColors = {
2 ['yellow'] = { background = '#fef08a', text = '#3f3931' },
3 ['pink'] = { background = '#fecdd3', text = '#881337' },
4 ['blue'] = { background = '#bfdbfe', text = '#1e3a8a' },
5 ['green'] = { background = '#bbf7d0', text = '#14532d' },
6}background: Background hex colortext: Text hex color
Book System
The diary contains a static manual with pre-written pages and a dynamic encyclopedia with player-unlocked discoveries.
Cover
The front cover is configurable. Texts fall back to the locale file when left nil; colors accept any CSS color; each decorative element toggles independently.
1Config.Book.cover = {
2 title = nil, -- nil = read from locale (cover_* keys)
3 subtitle = nil, -- empty string hides it
4 hint = nil, -- e.g. 'Click to open'
5
6 titleColor = '#c4a675',
7 subtitleColor = '#a08565',
8 ornamentColor = '#c4a675',
9
10 showEmbossedFrame = true,
11 showStitching = true,
12 showCornerOrnaments = true,
13 showSpineHighlight = true,
14 showLeatherStraps = false,
15
16 centerEmblem = '', -- '' = no emblem, e.g. 'fa-skull'
17}title,subtitle,hint: Cover texts.nilreads the matchingcover_*locale key; an empty string hides the elementtitleColor,subtitleColor,ornamentColor: Lettering and gold-ornament colorsshowEmbossedFrame,showStitching,showCornerOrnaments,showSpineHighlight,showLeatherStraps: Toggle each decorative element on or offcenterEmblem: Optional FontAwesome icon above the title (e.g.'fa-skull'). Empty string for no emblem
Manual Pages
1Config.Book = {
2 manual = {
3 title = 'Survival Guide',
4 pages = {
5 {
6 title = 'Welcome',
7 content = {
8 { type = 'polaroid', image = 'https://...', caption = 'Your first shelter' },
9 { type = 'text', value = 'Your text here.' },
10 { type = 'text', value = 'Bold red text.', style = { 'bold', 'red' } },
11 { type = 'post-it', text = 'Tip text', color = 'yellow' },
12 },
13 },
14 },
15 },
16}Each page has a title and a content array of mixed blocks:
text: Plain text. Optionalstylearray:'bold','italic','red', etc.polaroid: Image with captionpost-it: Colored sticky note.colormust match a key inConfig.PostItColors
Encyclopedia Categories
1Config.Book.encyclopedia = {
2 title = 'Encyclopedia',
3 introText = 'Introduction text...',
4 categories = {
5 ['fauna'] = { label = 'cat_fauna', icon = 'fa-dragon' },
6 ['flora'] = { label = 'cat_flora', icon = 'fa-leaf' },
7 ['locations'] = { label = 'cat_locations', icon = 'fa-map-marked-alt' },
8 ['items'] = { label = 'cat_items', icon = 'fa-gem' },
9 ['notes'] = { label = 'cat_notes', icon = 'fa-scroll' },
10 },
11}label: Locale key for the category nameicon: FontAwesome class for the category icon
Add or remove categories as needed. Each category collects discoverables that have a matching collection field.
Discoverables
Entries that players unlock through exploration. Each key in Config.Discoverables is a unique identifier.
1Config.Discoverables = {
2 ['example_animal'] = {
3 type = 'model',
4 model = 'a_c_deer',
5 name = 'White-Tailed Deer',
6 subTitle = 'Forest Herbivore',
7 description = 'A common deer found in forested areas...',
8 collection = 'fauna',
9 icon = 'fa-paw',
10 image = 'https://...',
11 imageStyle = 'sketch',
12 layoutStyle = 'vertical',
13 stats = {
14 ['TYPE'] = 'Herbivore',
15 ['RARITY'] = 'Common',
16 },
17 },
18}type: Detection method (see below)model: GTA model name or hash. Can be a string or array of strings to match multiple modelsname: Display name in the encyclopediasubTitle: Secondary labeldescription: Full description textcollection: Must match a category key inConfig.Book.encyclopedia.categoriesicon: FontAwesome icon classimage: Image URL displayed in the entry pageimageStyle: Visual frame style:'polaroid','taped','sketch','noir','stamp'layoutStyle:'vertical'(portrait) or'horizontal'(landscape)stats: Key-value table displayed as a stats box
Discovery Types
Model detection: Triggers when the player targets a specific prop or ped model:
1{
2 type = 'model',
3 model = 'a_c_deer',
4 -- or multiple: model = { 'a_c_deer', 'a_c_deer_02' },
5}Sphere zone: Triggers when the player enters a sphere zone:
1{
2 type = 'sphere',
3 coords = vec3(100.0, 200.0, 30.0),
4 radius = 15.0,
5}Box zone: Triggers when the player enters a box zone:
1{
2 type = 'box',
3 coords = vec3(100.0, 200.0, 30.0),
4 size = vec3(10.0, 10.0, 5.0),
5 rotation = 45,
6}Inventory item: Triggers when the player holds a specific item. A poller checks every 5 seconds while the diary is in the inventory and stops once all item-type entries are unlocked:
1{
2 type = 'item',
3 item = 'bandage',
4}item: The item name as registered in the inventory system. The check runs throughBridge.HasItem, so it works on every inventory supported byml_bridge(ox, qb, esx, tgiann, and others).
All four types are validated server-side: model and zone unlocks require the player to actually be in range, item unlocks require the player to actually hold the configured item. Forged attempts are rejected and logged to the exploits webhook.
Logger Backend
1Config.Logger = 'discord''discord': Uses Discord webhook URLs'ox_lib': Routes logs to DataDog, FiveManage, or Loki based on your ox_lib config
Discord Webhooks
1Config.DiscordWebhook = {
2 DiaryActions = 'INSERT_WEBHOOK_LINK_HERE',
3 DiscoveryActions = 'INSERT_WEBHOOK_LINK_HERE',
4 PageActions = 'INSERT_WEBHOOK_LINK_HERE',
5 ExploitDetected = 'INSERT_WEBHOOK_LINK_HERE',
6}DiaryActions: Diary open/close events, admin command usageDiscoveryActions: Discovery unlock/remove eventsPageActions: Note creation, deletion, and torn page transfersExploitDetected: Distance spoof attempts, ownership mismatches, malformed payloads
Set any webhook to false to disable that log entirely.