-- ============================================================================ -- M-Minigames — standalone minigame library for FiveM -- -- Dependency: ox_lib only. No ESX, no inventory, no framework. -- Player-facing text: Slovenian, with an English fallback (see LOCALES). -- -- Public API (client): -- exports['M-Minigames']:Start(name, difficultyOrOpts [, callback]) -- exports['M-Minigames']:StartAny({ 'a', 'b' }, difficultyOrOpts) -- exports['M-Minigames']:StartForTool('drill', difficultyOrOpts) -- exports['M-Minigames']:StartVerified(name, opts) -- exports['M-Minigames']:IsActive() / :Cancel() / :GetGames() -- -- Public API (server): -- exports['M-Minigames']:VerifyToken(source, token [, game]) -- exports['M-Minigames']:GetFlags(source) / :GetAllFlags() / :ClearFlags(source) -- ============================================================================ Config = {} Config.Debug = false -- prints the result table after every run Config.Language = 'sl' -- 'sl' or 'en' -- ============================================================================ -- THEME -- Identical tokens to M-Addon so the two resources look like one product. -- A consuming script can override the accent per call with opts.accent. -- ============================================================================ Config.Theme = { accent = '#C8863C', inheritFrom = 'M-Addon' -- adopt this resource's accent if it exposes GetAccent() } -- ============================================================================ -- SAFETY -- These exist so a player can never be left holding NUI focus. -- ============================================================================ Config.Safety = { hardTimeout = 60000, -- absolute ceiling per run, whatever the game wants timeoutGrace = 5000, -- added to the game's own duration before that trips failOnDeath = true } -- ============================================================================ -- DIFFICULTY -- Presets map to a 0.0-1.0 scalar; a raw number is also accepted. -- ============================================================================ Config.Difficulty = { easy = 0.25, medium = 0.55, hard = 0.85 } Config.DefaultDifficulty = 'medium' -- ============================================================================ -- ANTI-CHEAT -- The client decides the outcome — unavoidable with NUI. This limits what a -- faked result is worth and makes it visible; it is not absolute. -- ============================================================================ Config.AntiCheat = { tokenLifetime = 120, -- seconds a StartVerified token stays redeemable rateLimit = 20, -- starts per player per minute minTimeFraction = 0.25, -- faster than this fraction of the expected time is logged perfectStreak = 15, -- consecutive perfect results before logging logToConsole = true } Config.AdminAce = 'minigames.admin' -- ============================================================================ -- GAME TUNING -- Every value is either a fixed number or an { easy, hard } pair that is -- interpolated with the difficulty scalar. Games only ever see the resolved -- block, so tuning never means opening the HTML. -- ============================================================================ Config.Games = { oreStrike = { input = 'keyboard', params = { zoneWidth = { 26, 8 }, -- % of the bar speed = { 0.55, 1.4 }, -- bar traversals per second rounds = { 1, 3 }, timeLimit = { 9000, 6000 } } }, drillStability = { input = 'keyboard', params = { -- All motion values are per SECOND, and the needle is integrated -- with dt, so they mean the same thing at any framerate. bandWidth = { 46, 26 }, -- % of the track counted as in-band drift = { 18, 44 }, -- resistance, %/s^2 control = { 40, 78 }, -- player authority, %/s^2 settle = { 3.6, 3.0 }, -- drag; higher = the needle stops sooner maxSpeed = { 16, 26 }, -- hard cap on needle speed, %/s holdTime = { 2000, 3800 }, -- ms in-band needed to fill the meter decay = { 0.35, 0.7 }, -- how fast the meter drains out of band timeLimit = { 12000, 12000 } } }, jackRhythm = { input = 'keyboard', params = { tempo = { 780, 440 }, -- ms between beats tolerance = { 230, 100 }, -- ms window around the beat beats = { 5, 10 }, timeLimit = { 14000, 12000 } } }, fracturePoints = { input = 'mouse', params = { points = { 3, 6 }, decoys = { 0, 4 }, timeLimit = { 10000, 6500 } } }, heatControl = { input = 'keyboard', params = { heatRate = { 24, 42 }, -- % per second while held coolRate = { 34, 22 }, -- % per second while released redline = { 94, 80 }, -- % at which it fails depthRate = { 30, 24 }, -- % per second while held -- Drilling inside the sweet band multiplies depth gain, so the -- skilful play is riding just under the redline rather than -- tapping E safely forever. sweetLow = { 0.50, 0.60 }, -- fraction of the redline sweetHigh = { 0.94, 0.90 }, sweetBonus = { 2.1, 1.8 }, -- Rock layers: each one changes how fast heat builds. layers = { 3, 5 }, coolant = { 2, 1 }, -- SPACE charges, each dumps heat coolantHit = { 42, 30 }, -- % of heat removed per charge timeLimit = { 15000, 13000 } } }, keypad = { input = 'both', params = { digits = { 4, 8 }, showTime = { 2600, 1400 }, -- ms the code stays visible timeLimit = { 12000, 8000 } } }, sequenceMemory = { input = 'mouse', params = { length = { 3, 7 }, gridSize = { 3, 4 }, flashTime = { 620, 340 }, timeLimit = { 14000, 12000 } } }, circuitTrace = { input = 'mouse', params = { gridSize = { 3, 5 }, moveLimit = { 24, 16 }, timeLimit = { 20000, 14000 } } }, holdRelease = { input = 'keyboard', params = { arcSize = { 70, 26 }, -- degrees of the target arc fillSpeed = { 62, 108 }, -- degrees per second timeLimit = { 6000, 5000 } } }, sortingBins = { input = 'keyboard', params = { fallSpeed = { 26, 46 }, -- % of the track per second, at the start rampUp = { 0.10, 0.22 }, -- speed added per correct sort needed = { 5, 10 }, -- correct in a row to pass queue = { 2, 3 }, -- items visible on the belt at once swapAfter = { 0, 3 }, -- bins swap sides after N sorts (0 = never) timeLimit = { 16000, 15000 } } } } -- Convenience map for job scripts: "give me whatever suits a drill". Config.ToolGames = { ['pickaxe'] = { 'oreStrike', 'fracturePoints' }, ['jackham'] = { 'jackRhythm' }, ['drill'] = { 'heatControl', 'drillStability' }, ['hands'] = { 'sortingBins' } }