# Configuration > Configuration reference for ML Terminal System Category: TERMINAL SYSTEM · Source: https://miciomods.it/docs/ml-terminal-system-configuration · Last updated: 2026-07-28 ## Overview - `shared/config.lua`: Global settings, vehicle defaults, commands - `server/config_questions.lua`: Server-only quiz questions and profiles (clients never receive them) - `server/config_sv.lua`: Discord webhooks and log toggles - `shared/data/terminals/*.lua`: Individual terminal definitions (one file per terminal) ## General **shared/config.lua** ```lua Config.Debug = false Config.Locale = 'en' Config.Interaction = 'target' ``` - `Debug`: Console output. Keep off in production. - `Locale`: Language code. See the `locales/` folder. - `Interaction`: `'target'` for auto-detected target system, `'textui'` to force 3D Text UI ### Vehicle Defaults **shared/config.lua** ```lua Config.Vehicles = { garage = '', plateFormat = 'LLNNNN', defaults = { fuel = 50, engine = 1000, body = 1000, tank = 1000, }, } ``` Used when a quiz profile awards a vehicle as a reward. ### Commands **shared/config.lua** ```lua Config.Commands = { theme = 'mltheme', setup = 'mlterminalsetup', props = 'mltoggleprops', } ``` ## Discord Webhooks **server/config_sv.lua** ```lua Config.DiscordWebhook = { Default = 'YOUR_WEBHOOK', Test = 'YOUR_WEBHOOK', Minigame = 'YOUR_WEBHOOK', Actions = 'YOUR_WEBHOOK', Doors = 'YOUR_WEBHOOK', } ``` Set any webhook to `false` to disable that log channel entirely. **server/config_sv.lua** ```lua Config.DiscordWebhook = { Default = 'YOUR_WEBHOOK', Test = false, -- Disables all quiz-related logs Minigame = false, -- Disables all minigame logs Actions = 'YOUR_WEBHOOK', Doors = 'YOUR_WEBHOOK', } ``` ### Log Toggles Each log event can be individually routed to a channel or disabled: **server/config_sv.lua** ```lua Config.Log = { TestResult = Config.DiscordWebhook.Test, TestConfirmedFailure = Config.DiscordWebhook.Test, ForceConfirm = Config.DiscordWebhook.Test, ExecuteAction = Config.DiscordWebhook.Actions, MinigameSuccess = Config.DiscordWebhook.Minigame, PasswordFailed = Config.DiscordWebhook.Minigame, DoorToggle = Config.DiscordWebhook.Doors, } ``` Set any individual log to `nil` to disable it while keeping its channel active for other logs. ### Log Batching **server/config_sv.lua** ```lua Config.LogSettings = { Color = 3066993, Interval = 60000, -- Sends logs every 60 seconds } ``` > **TIP:** Rate Limiting > > Do not set `Interval` below 60000 ms. Discord will rate-limit your webhook and logs will be dropped. ## Terminal Configuration Each terminal is defined as a separate Lua file in `shared/data/terminals/`. Copy a bundled example such as `example_full.lua` and configure only the sections you need. ### Section 1: Base (Required) **shared/data/terminals/my_terminal.lua** ```lua Config.Terminals['my_terminal'] = { label = 'Use Terminal', model = 'ba_prop_battle_club_computer_01', coords = vector4(100.0, 200.0, 30.0, 180.0), theme = 'theme-default', } ``` - `label`: Text shown on the target/textui interaction - `model`: GTA prop model hash - `coords`: Position and heading as `vector4` - `theme`: UI theme (see below) **Multi-Location**: Replace `coords` with `locations` to spawn the same terminal at multiple positions: ```lua locations = { vector4(100.0, 200.0, 30.0, 180.0), vector4(110.0, 200.0, 30.0, 90.0), }, ``` ### Available Themes - `theme-default`: Industrial Orange - `theme-wasteland`: Rust / Post-Apocalyptic - `theme-cyberpunk`: Neon Magenta - `theme-noir`: Blood Red - `theme-fantasy`: Gold - `theme-fruit`: Fresh Green - `theme-vintage-yellow`: Retro Yellow - `theme-vintage-blue`: Retro Blue - `theme-facade98-teal`: Windows 98 Teal ### Section 2: Spawn ```lua spawn = { distance = 15.0, texture = 'prop_computer_screen', } ``` - `distance`: Prop create/destroy streaming distance - `texture`: DUI replacement texture name (depends on the prop model) ### Section 3: Camera ```lua camera = { enabled = true, distance = 0.5, height = 0.35, offset = 0.3, fov = { start = 70, final = 50 }, transition = 1500, } ``` - `enabled`: Toggle cinematic camera when using the terminal - `distance`: How close the camera sits to the prop face - `height`: Camera height offset relative to the prop center - `offset`: Z offset for screen center - `fov`: Field of view transition (start → final) - `transition`: Camera movement duration in ms ### Section 4: Access Control ```lua access = { exclusive = true, showClose = true, job = 'police', item = 'keycard', } ``` - `exclusive`: Only one player at a time - `showClose`: Show X button in UI - `job`: Restrict to a specific job. Set `nil` for no restriction - `item`: Require an item in inventory. Set `nil` for no restriction ### Section 5: UI Customization ```lua ui = { header = 'SYSTEM v2.0', bootLines = { '> Initializing system...', '> Loading modules...', '> System ready.', }, logo = { text = 'MICIO OS', duration = 3000, }, } ``` - `header`: Text shown in the terminal header bar - `bootLines`: Array of strings displayed with typewriter effect during boot - `logo.text`: Text-based logo during boot (or use `logo.image` for an image file) - `logo.duration`: How long the logo screen is shown (ms) ## App Types Apps are the interactive modules on the terminal desktop. Each app has a `type` that determines its behavior. ### quiz Psychometric test with randomized questions, skill-based scoring, profile assignment, and rewards. ```lua { name = 'Psychometric Test', icon = 'fa-solid fa-brain', type = 'quiz', } ``` Requires a `quiz` section in the terminal config (see below). ### folder File browser with text-based files. ```lua { name = 'Documents', icon = 'fa-solid fa-folder-open', type = 'folder', files = { { name = 'readme.txt', content = 'File content here.' }, { name = 'log.dat', content = 'Entry 01: all clear.' }, }, } ``` ### doors Door control panel. Requires a `doors` section. ```lua { name = 'Door Control', icon = 'fa-solid fa-door-open', type = 'doors', } ``` ### actions Action panel with cooldown-based buttons that trigger events. Requires an `actions` section. ```lua { name = 'Operations', icon = 'fa-solid fa-bolt', type = 'actions', } ``` ### minigame Standalone minigame from the desktop. ```lua { name = 'Decrypt', icon = 'fa-solid fa-lock', type = 'minigame', minigame = 'password', difficulty = 5, } ``` ### locked_folder Folder locked behind a minigame. Can also be gated behind a quiz result. ```lua { name = 'Classified Files', icon = 'fa-solid fa-file-shield', type = 'locked_folder', unlock = 'password', unlockDifficulty = 5, files = { { name = 'secret.dat', content = 'CLASSIFIED CONTENT' }, }, requireQuiz = true, requiredProfile = 'tactician', } ``` ## Doors Section ```lua doors = { title = 'DOOR PANEL', list = { { id = 1, label = 'Main Entrance' }, { id = 2, label = 'Server Room' }, }, } ``` - `id`: Must match the door ID in your door lock system - `label`: Display name in the UI ## Actions Section ```lua actions = { title = 'OPERATIONS PANEL', list = { { id = 'alarm', label = 'Activate Alarm', icon = 'fa-solid fa-bell', desc = 'Activate the alarm system.', cooldown = 30, trigger = { type = 'client', event = 'myScript:triggerAlarm', args = { zone = 'main' }, }, }, }, } ``` - `id`: Unique action identifier - `cooldown`: Seconds before the player can re-use - `trigger.type`: `'client'` or `'server'` - `trigger.event`: Event name to fire - `trigger.args`: Arguments passed to the event handler ## Minigames Section ```lua -- These two live at the terminal root, NOT inside minigames: passwordLockoutDuration = 30, -- Lockout seconds after a failed attempt lockoutType = 'personal', -- 'global' locks everyone, 'personal' only the player minigames = { onBoot = 'password', -- 'password' | 'memory' | 'pipePuzzle' | 'simonSays' | nil password = { difficulty = 5, -- Word length (3-10) attempts = 4, brackets = true, bonusClicks = 2, words = { 'NEXUS', 'VIPER', 'GHOST', 'RAVEN' }, }, memory = { difficulty = 2, -- 1=easy, 2=medium, 3=hard gridSize = 4, -- 4=4x4, 6=6x6 timeLimit = 60, }, pipePuzzle = { difficulty = '4x4', -- '3x3' easy, '4x4' medium, '5x5' hard timeLimit = 60, }, simonSays = { sequenceLength = 6, -- 4=easy, 6=medium, 8=hard timeLimit = 30, }, } ``` - `onBoot`: Require a minigame before reaching the desktop. The four minigames are password, memory, pipePuzzle, simonSays. Set `nil` for no boot minigame. - `passwordLockoutDuration`: Seconds before the player can retry after a failure (set at the terminal root, not inside `minigames`) - `lockoutType`: `'global'` locks all players, `'personal'` locks only the failing player. ## Quiz Section ```lua -- Terminal root, client-safe quiz controls: showRewards = true, reopenifcompleted = false, allowRetakeOnSuccess = false, allowRetakeOnFailure = true, quiz = { title = 'PSYCHOMETRIC ANALYSIS', startButton = 'Start Analysis', questionCount = 3, -- Random questions pulled from the server pool fingerprint = true, -- Require a fingerprint scan before starting } ``` - `questionCount`: Number of random questions picked from the server pool - `showRewards` / `reopenifcompleted`: terminal-root flags: show the reward summary; allow reopening after completion - `fingerprint`: Require a fingerprint scan before starting - `allowRetakeOnSuccess`: terminal-root flag: allow retake after receiving a profile - `allowRetakeOnFailure`: terminal-root flag: allow retake after failing to meet any threshold - Questions and profiles are defined server-side (anti-cheat). Profile rewards can include `money`, `items`, `vehicle` and `job` (`{ name, grade }`) ### Questions & Profiles (Server-Only) Questions and profiles never reach the client. Define them in `server/config_questions.lua` under `TerminalQuestions['terminal_id']`, using the SAME terminal ID: **server/config_questions.lua** ```lua TerminalQuestions['my_terminal'] = { questions = { { question_key = 'How do you handle pressure?', answers = { { text_key = 'I analyze and plan', value = { skill = 'tactical', points = 15 } }, { text_key = 'I act on instinct', value = { skill = 'combat', points = 15 } }, }, }, }, profiles = { { id = 'tactician', name = 'PROFILE: TACTICIAN', description = 'Strategic mind, born leader.', points_required = { skill = 'tactical', amount = 11 }, rewards = { money = 5000, items = { { name = 'radio', amount = 1 } }, job = { name = 'police', grade = 0 }, vehicle = { name = 'police' }, }, }, { id = 'recruit', name = 'PROFILE: RECRUIT', description = 'Fallback, always matchable (no points_required).', rewards = { money = 0 }, }, }, } ``` - `question_key` / `text_key`: question and answer text shown in the UI - `value`: score for an answer: `{ skill, points }` - `points_required`: profile threshold: `{ skill, amount }`. First matching profile wins (order = priority); a profile with no `points_required` is the fallback. - `rewards`: `money`, `items` (`{ name, amount }`), `job` (`{ name, grade }`), `vehicle` (`{ name = "model" }`) ## Kiosk Mode Transforms the terminal into a single-app experience with no desktop. ```lua kiosk = { mode = 'simple', app = 'doors', } ``` - `mode = 'simple'`: Opens the app directly, no boot or minigame - `mode = 'locked'`: Requires a minigame to unlock, access expires after `unlockDuration` seconds ```lua kiosk = { mode = 'locked', app = 'doors', unlockGame = 'password', unlockDuration = 300, } ```