### Open77.cyberware.install Example Source: https://open2077.net/docs/api/server/open77-cyberware Example usage of the install method, including revision checking and operation ID generation. ```lua local record = Open77.cyberware.current(playerId) if not record then return end local operationId, err = Open77.cyberware.newOperationId() if not operationId then print(err); return end local result, rejected = Open77.cyberware.install(playerId, "myrp.gorilla", "training", { expectedRevision=record.revision,operationId=operationId }) if not result then print(rejected) else print(result.ticket) end ``` -------------------------------- ### StartResource Lua Example Source: https://open2077.net/docs/api/server/globals Demonstrates how to queue the start of a resource using the StartResource function within a command. ```lua -- Start the event resource when an admin opens the event RegisterCommand("event-open", function(source) local ok, reason = StartResource("summer_event") if not ok then Open77.chat.send(source, reason) end end, true) ``` -------------------------------- ### Client-side voice guide helper Source: https://open2077.net/docs/guided-voice-setup A helper script to manage the voice setup session, including starting, updating, and closing the session, with a thread to keep the session alive. ```lua -- client.lua VoiceGuide = { active = false, snapshot = nil, error = nil } function VoiceGuide.begin() if not (Open77.voice and type(Open77.voice.setup) == 'function') then return nil, 'voice_setup_unavailable' end local snapshot, reason = Open77.voice.setup('begin') if not snapshot then Open77.voice.setup('end') return nil, reason end VoiceGuide.active = true VoiceGuide.snapshot, VoiceGuide.error = snapshot, nil return snapshot end function VoiceGuide.update(operation, payload) if not VoiceGuide.active then return nil, 'voice_setup_closed' end if operation ~= 'set' and operation ~= 'test' and operation ~= 'refresh' and operation ~= 'status' then return nil, 'unknown_voice_operation' end local snapshot, reason = Open77.voice.setup(operation, payload) VoiceGuide.error = reason if snapshot then VoiceGuide.snapshot = snapshot end return snapshot, reason end function VoiceGuide.close(completed) if not VoiceGuide.active then return true end local operation = completed and 'complete' or 'end' local ok, reason = Open77.voice.setup(operation) if not ok and completed then VoiceGuide.error = reason return nil, reason -- Keep the session alive so the UI can retry or skip. end VoiceGuide.active, VoiceGuide.snapshot = false, nil VoiceGuide.error = reason return ok, reason end CreateThread(function() while true do Wait(500) if VoiceGuide.active then local snapshot, reason = VoiceGuide.update('status') if not snapshot then VoiceGuide.close(false) VoiceGuide.error = reason end end end end) AddEventHandler('onClientResourceStop', function(name) if name == GetCurrentResourceName() then VoiceGuide.close(false) end end) ``` -------------------------------- ### Open77.http.request Example Source: https://open2077.net/docs/api/server/open77-http Example of posting to a Discord webhook when the server starts. ```lua -- Post to a Discord webhook when the server starts Open77.http.request("https://discord.com/api/webhooks/...", function(status, body, headers, err) if status == 0 then print("webhook failed: " .. tostring(err)) end end, "POST", { content = "Server is up!" }) ``` -------------------------------- ### Open77.http.routes Example Source: https://open2077.net/docs/api/server/open77-http Example of printing exposed routes at startup. ```lua -- Print what this resource exposes at start, so the operator's log says it for _, route in ipairs(Open77.http.routes()) do print('serving ' .. route) end ``` -------------------------------- ### Open77.weapons.activate Example Source: https://open2077.net/docs/api/server/open77-weapons Example showing how to draw a player's weapon in slot 1 when a round starts. ```lua -- Draw the player's slot 1 when the round starts Open77.weapons.activate(playerId, 1) ``` -------------------------------- ### Start Open77 server on Windows and Linux Source: https://open2077.net/docs/host-a-server Launch the server from the unpacked folder. On Windows, run Open77.Server.exe or use dotnet Open77.Server.dll against an installed .NET 10 runtime. On Linux, run ./Open77.Server. ```shell # Windows, from the unpacked folder Open77.Server.exe # …or, against an installed .NET 10 runtime: dotnet Open77.Server.dll # Linux, from the unpacked folder ./Open77.Server ``` -------------------------------- ### GetPlayersInBucket example using Open77.players.inBucket Source: https://open2077.net/docs/api/server/globals Example showing the preferred Open77.* spelling for GetPlayersInBucket. It starts a race only when the lobby instance has at least two players. ```lua -- GetPlayersInBucket is the low-level form of Open77.players.inBucket (documented alias); -- the example shows the Open77.* spelling resources are told to prefer. -- Start the race only when the lobby instance has at least two players local racers = Open77.players.inBucket(RACE_BUCKET) if #racers >= 2 then startRace(racers) end ``` -------------------------------- ### ready Usage Example Source: https://open2077.net/docs/api/server/open77-database Demonstrates creating a database table once the connection is established. ```lua -- Create the table once the database is reachable Open77.database.ready(function() Open77.database.update.await([[ CREATE TABLE IF NOT EXISTS players ( identifier VARCHAR(64) PRIMARY KEY, money INT NOT NULL DEFAULT 500 ) ]]) end) ``` -------------------------------- ### Get door state example Source: https://open2077.net/docs/api/client/resource-open77-doors Example usage of the get export within a thread. ```lua CreateThread(function() local pending, error = Open77.exports.call("open77_doors", "get", id) if not pending then print(error); return end local result, reason = pending:await() -- Handle the result before continuing; queued is not accepted. end) ``` -------------------------------- ### Startup Commands Configuration Source: https://open2077.net/docs/resource-runtime Example of defining startup commands in the server.jsonc file. ```jsonc "startup": { "commands": [ "weather.time.set 20:30:00", "weather.set lightclouds", "weather.random off" ] } ``` -------------------------------- ### Open77.chat.broadcast Example Source: https://open2077.net/docs/api/server/open77-chat Example of broadcasting a message to all players regarding a round start. ```lua -- The round is starting in 30 seconds Open77.chat.broadcast("Round starts in 30 seconds!") ``` -------------------------------- ### Open77.log.info example Source: https://open2077.net/docs/api/client/open77-log Example of logging informational lifecycle events. ```lua -- Normal lifecycle lines Open77.log.info("HUD started") ``` -------------------------------- ### getEntity example Source: https://open2077.net/docs/api/server/open77-routingbuckets Example showing how to get the routing bucket of a vehicle entity. ```lua -- Which instance is this vehicle in? print("vehicle bucket", Open77.routingBuckets.getEntity(vehicleEntityId)) ``` -------------------------------- ### Open77.runtime.commands Example Source: https://open2077.net/docs/api/client/open77-runtime Iterates through all registered client commands to build a help list. ```lua -- Build a "/help" list from every client command for _, command in ipairs(Open77.runtime.commands()) do print("/" .. command.name, command.help or "") end ``` -------------------------------- ### Open77.io.makeDirectory Example Source: https://open2077.net/docs/api/server/open77-io Example of ensuring a directory exists before saving files. ```lua -- Make sure the folder exists before the first save Open77.io.makeDirectory("houses") ``` -------------------------------- ### Open77.sound.stopAll example - silence everything Source: https://open2077.net/docs/api/server/open77-sound Example showing how to stop all sounds started by this resource. ```lua -- The event ends: silence everything this resource started Open77.sound.stopAll() ``` -------------------------------- ### Open77.equipment.apply Example Source: https://open2077.net/docs/api/client/open77-equipment Example of applying a whole outfit while clearing unspecified slots. ```lua -- Put on a whole outfit at once, clearing anything the outfit does not name Open77.equipment.apply({ Head = "Items.Cap_01_basic_01", OuterChest = false, -- take the jacket off }, { replace = false }) ``` -------------------------------- ### Manage voice setup playback and completion Source: https://open2077.net/docs/guided-voice-setup Use these calls in button handlers to test microphone playback and finalize the setup session. Ensure microphone capture is enabled before starting the test, and always close the session when the UI is dismissed. ```lua -- Run on the matching UI actions while the setup session is open. local started, reason = VoiceGuide.update('test', true) if not started then print('Playback failed: ' .. tostring(reason)) end -- On Stop playback: VoiceGuide.update('test', false) -- On Finish: check the result before advancing onboarding. local completed, completionReason = VoiceGuide.close(true) if not completed then print('Setup could not finish: ' .. tostring(completionReason)) end ``` -------------------------------- ### Basic KVP operations Source: https://open2077.net/docs/client-kvp Examples of setting, getting, checking existence, and incrementing values using the Open77.kvp API. ```lua local ok, reason = Open77.kvp.set("character:lastSlot", 2) assert(ok, reason) local slot = Open77.kvp.get("character:lastSlot", 1) local present = Open77.kvp.has("character:lastSlot") local newCount = Open77.kvp.increment("stats:connections", 1) ``` -------------------------------- ### Get NPC attitude example Source: https://open2077.net/docs/api/server/open77-npcs Example of printing an NPC's default attitude. ```lua -- Debug: print how the guard regards everyone local attitude = Open77.npcs.getAttitude(guardId) if attitude then print("default attitude:", attitude.default) end ``` -------------------------------- ### Example: Handle menu state changes Source: https://open2077.net/docs/api/client/open77-session Shows how to listen for menu state changes and perform an initial check on resource startup. ```lua AddEventHandler("open77:menuStateChanged", function(open, pause, source) if open == "1" then pauseLoop(source) else resumeLoop() end end) local now = Open77.session.menuState() if now and now.open then pauseLoop(now.source) end ``` -------------------------------- ### Get NPC snapshot example Source: https://open2077.net/docs/api/server/open77-npcs Example of checking an NPC's health status. ```lua -- Is the boss still alive? local boss = Open77.npcs.get(bossId) if boss and boss.health <= 0 then Open77.chat.broadcast("The boss is down!") end ``` -------------------------------- ### Open77.database.isReady usage example Source: https://open2077.net/docs/api/server/open77-database An example demonstrating how to gate command execution based on the database readiness status. ```lua -- Refuse the shop until the database answers RegisterCommand("shop", function(source) local ready, reason = Open77.database.isReady() if not ready then return Open77.chat.send(source, "Shop unavailable: " .. reason) end openShop(source) end, false) ``` -------------------------------- ### Get Task Example Source: https://open2077.net/docs/api/server/open77-npcs-tasks Example of waiting for a movement task to complete by polling its state. ```lua -- Wait until the walk is finished CreateThread(function() local task = Open77.npcs.tasks.moveTo(npcId, door) while Open77.npcs.tasks.get(npcId, task) do Wait(250) end print("the NPC has arrived (or gave up)") end) ``` -------------------------------- ### Open77.io.copy Example Source: https://open2077.net/docs/api/server/open77-io Example of creating a backup file before overwriting an existing configuration. ```lua -- Keep a backup before rewriting the config Open77.io.copy("config.json", "config.backup.json", true) ``` -------------------------------- ### Open77.io.exists Example Source: https://open2077.net/docs/api/server/open77-io Example of writing a default configuration file if one does not already exist. ```lua -- First run: write a default config if there is none if not Open77.io.exists("config.json") then Open77.io.writeJson("config.json", { startingMoney = 500 }) end ``` -------------------------------- ### setControlLock Example Source: https://open2077.net/docs/api/client/open77-vehicles Example usage of setControlLock to manage vehicle inputs for a race starting grid. ```lua -- Starting grid: freeze the inputs, then release them on GO RegisterNetEvent("race:grid", function(vehicleId) Open77.vehicles.setControlLock(vehicleId, true) end) RegisterNetEvent("race:go", function(vehicleId) Open77.vehicles.setControlLock(vehicleId, false) end) ``` -------------------------------- ### Open77.database.single Example Source: https://open2077.net/docs/api/server/open77-database Example usage of Open77.database.single.await to fetch a player row. ```lua -- One row, or nil when the player is unknown AddEventHandler("onPlayerReady", function(playerId) local identifier = Open77.players.identifier(playerId) local row = Open77.database.single.await("SELECT * FROM players WHERE identifier = ?", { identifier }) if not row then createPlayer(identifier) end end) ``` -------------------------------- ### VoiceGuide.close(true) Source: https://open2077.net/docs/guided-voice-setup Completes the voice setup session. Returns a boolean indicating success and a reason string if it fails. Should be called when the player finishes setup. ```APIDOC ## VoiceGuide.close(true) ### Description Completes the voice setup session. Returns a boolean indicating success and a reason string if it fails. Should be called when the player finishes setup. ### Method VoiceGuide.close ### Parameters - **completed** (boolean) - Required - Set to true to finish the setup. ### Request Example ```lua local completed, completionReason = VoiceGuide.close(true) if not completed then print('Setup could not finish: ' .. tostring(completionReason)) end ``` ### Response #### Success Response - **completed** (boolean) - Indicates if setup completed successfully. - **completionReason** (string) - Reason for failure if setup could not finish. #### Response Example ```lua local completed, completionReason = VoiceGuide.close(true) ``` ``` -------------------------------- ### Close photo mode example Source: https://open2077.net/docs/api/client/open77-photomode Example showing how to close the photo mode when a round starts. ```lua -- Leave photo mode when the round starts RegisterNetEvent("arena:roundStarted", function() Open77.photoMode.close() end) ``` -------------------------------- ### Example: Using Open77.callbacks.callClient Source: https://open2077.net/docs/api/server/open77-callbacks Demonstrates asking a client to confirm a purchase using a promise. ```lua -- Ask one client to confirm a purchase (alias of Open77.net.callClient) CreateThread(function() local pending = Open77.callbacks.callClient(source, "confirmPurchase", "ammo_box", 50) local confirmed = pending and pending:await() if confirmed then sell(source, "ammo_box") end end) ``` -------------------------------- ### Set perspective mode example Source: https://open2077.net/docs/api/client/open77-perspective Example of requesting third-person perspective when a client resource starts. ```lua -- Third person on foot when the player joins; the arbiter still decides AddEventHandler("onClientResourceStart", function(name) if name == GetCurrentResourceName() then Open77.perspective.set("tps") end end) ``` -------------------------------- ### Get NPC behavior example Source: https://open2077.net/docs/api/server/open77-npcs Example of checking and updating an NPC's combat status. ```lua -- Only re-enable combat if it was actually off local behavior = Open77.npcs.getBehavior(guardId) if behavior and not behavior.combatEnabled then Open77.npcs.setCombatEnabled(guardId, true) end ``` -------------------------------- ### Open77.motion.launch example Source: https://open2077.net/docs/api/client/open77-motion An example showing how to perform a client-side projection launch after server authorization. ```lua -- Client projection only: invoked after the server has granted motion. local request, reason = Open77.motion.launch(1, 1, 0, 12, 10) if request then print(Open77.motion.state(request)) else print(reason) end ``` -------------------------------- ### Registering a Jobs tab with Open77 Source: https://open2077.net/docs/native-map This example demonstrates the full setup for a custom map tab, including the resource manifest, client-side Lua logic, and the associated HTML, CSS, and JavaScript files. ```lua -- open77.lua resource 'city_menu' version '1.0.0' client_scripts { 'client.lua' } web_files { 'web/**' } permissions { 'map.read', 'map.control' } ``` ```lua -- client.lua local jobsTab, jobsPage local function sendJobsState() if jobsPage then jobsPage:emit('jobs:state', { message = 'Choose a job from your resource.' }) end end AddEventHandler('onClientResourceStart', function() if not Open77.map or type(Open77.map.addTab) ~= 'function' then print('This menu requires a client with native map tabs.') return end assert(Open77.map.setTitle('NIGHT CITY ROLEPLAY')) assert(Open77.map.setAccentColor('#FFB347')) jobsTab, jobsPage = Open77.map.addTab({ id = 'jobs', label = 'Jobs', url = 'web/jobs.html', order = 10 }) if not jobsTab then print('Map tab unavailable: ' .. tostring(jobsPage)) jobsPage = nil Open77.map.resetAppearance() return end jobsPage:on('jobs:refresh', sendJobsState) end) AddEventHandler('open77:map:tabEntered', function(event) if event.id == jobsTab then sendJobsState() end end) AddEventHandler('open77:map:tabLeft', function(event) if event.id == jobsTab then print('Jobs tab left: ' .. event.reason) end end) ``` ```html
Loading…
``` ```css /* web/jobs.css */ :root { --accent: #22d8e2; color-scheme: dark; } body { margin: 0; padding: 2rem; background: #101820; color: #fff; } h1 { color: var(--accent); } ``` ```javascript // web/jobs.js let polling; function stopPolling() { clearInterval(polling); polling = undefined; } function refresh() { Open77.emit('jobs:refresh', {}); } function applyTheme(screen) { document.documentElement.style.setProperty('--accent', screen.accentColor); } Open77.on('jobs:state', data => { document.getElementById('status').textContent = data.message; }); Open77.on('open77:map:tabState', event => { applyTheme(event.screen); stopPolling(); if (event.active) { refresh(); polling = setInterval(refresh, 10000); } // Pause resource-owned audio here when event.active is false. }); Open77.on('open77:map:screenChanged', applyTheme); // Register listeners first, then request the current state, including on reload. Open77.emit('open77:map:ready', {}); ``` -------------------------------- ### Open77.kvp.find Example Source: https://open2077.net/docs/api/client/open77-kvp Example showing how to iterate over entries matching a specific prefix. ```lua -- List every saved radio favourite with its value for _, entry in ipairs(Open77.kvp.find("radio:") or {}) do print(entry.key, entry.value, entry.type) end ``` -------------------------------- ### Get current target example Source: https://open2077.net/docs/api/client/open77-inspector Example showing how to retrieve and print information about the current target. ```lua local t = Open77.inspector.target() if t and t.valid then print(t.kind, t.name, t.distance) --> door Door 1.38 end ``` -------------------------------- ### Example: Using Open77.callbacks.callClientAwait Source: https://open2077.net/docs/api/server/open77-callbacks Demonstrates awaiting a client response in a single line. ```lua -- The same question, awaited in one line CreateThread(function() local confirmed = Open77.callbacks.callClientAwait(source, "confirmPurchase", "ammo_box", 50) if confirmed then sell(source, "ammo_box") end end) ``` -------------------------------- ### Open77.weapons.setComponent example - install scope with event handler Source: https://open2077.net/docs/api/client/open77-weapons Example installing a short scope on the rifle in slot 1, checking the returned requestId, and handling the asynchronous completion via the open77:weapons:completed event. ```lua -- A short scope on the rifle in slot 1; the verified outcome arrives later local requestId, reason = Open77.weapons.setComponent(1, "Items.w_att_scope_short_01", { attachmentSlot = "AttachmentSlots.Scope" }) if not requestId then print("refused:", reason) end AddEventHandler("open77:weapons:completed", function(id, operation, accepted, why) if tostring(id) == tostring(requestId) then print(operation, accepted, why) end end) ``` -------------------------------- ### Open77.http.listen example Source: https://open2077.net/docs/api/server/open77-http A practical example of setting up a POST webhook to heal a player, including required permissions and configuration comments. ```lua -- open77.lua: permissions { 'http.serve' }; server.jsonc: "httpHandlers": { "enabled": true } -- A webhook that heals a player by id: POST /my_resource/heal local route, reason = Open77.http.listen('/heal', function(req, res) if req.method ~= 'POST' then return res.json(405, { error = 'method_not_allowed' }) end local payload = json.decode(req.body or '') or {} local ok, why = Open77.players.setHealth(payload.playerId, 100) if not ok then return res.json(404, { error = why }) end res.json({ healed = payload.playerId }) end) if not route then print('cannot serve: ' .. tostring(reason)) else print('listening on ' .. route) end ``` -------------------------------- ### Open77.combat.setFriendlyFire Example Source: https://open2077.net/docs/api/server/open77-combat Example of enabling global PvP. ```lua -- PvP is on everywhere on this server Open77.combat.setFriendlyFire(true) ``` -------------------------------- ### Start workshop resources Source: https://open2077.net/docs/rp-job-techie Manually ensure the required resources or add them to the startup commands in server.jsonc. ```text ensure open77_transactions ensure open77_actions ensure rp_techie ``` ```json "startup": { "commands": [ "ensure open77_transactions", "ensure open77_actions", "ensure rp_techie" ] } ``` -------------------------------- ### Open77.equipment.registry usage example Source: https://open2077.net/docs/api/client/open77-equipment Example showing how to save the current outfit to a KVP for restoration. ```lua -- Save the current outfit so it can be restored after a respawn local outfit = Open77.equipment.registry() if outfit then SetResourceKvp("outfit", json.encode(outfit)) end ``` -------------------------------- ### Stop entity animation example Source: https://open2077.net/docs/api/client/open77-animations Example usage of Open77.animations.stop to terminate an emote started on another body. ```lua -- Stop the emote this resource started on another body local entity = Open77.players.entity(playerId) if entity then Open77.animations.stop(entity) end ``` -------------------------------- ### Get perspective state example Source: https://open2077.net/docs/api/client/open77-perspective Example of checking if the perspective is allowed to determine UI element state. ```lua -- Grey out the "toggle view" button when the server forbids it local state = Open77.perspective.state() toggleButton.enabled = state and state.allowed ``` -------------------------------- ### Open77.equipment.info usage example Source: https://open2077.net/docs/api/client/open77-equipment Example showing how to retrieve and print slot and gender support information for an item. ```lua -- Show which slot an item goes into before offering it local info = Open77.equipment.info("Items.Cap_01_basic_01") if info then print(info.slot, info.supportsMale, info.supportsFemale) end ``` -------------------------------- ### Open77.resource.start example: event-open command Source: https://open2077.net/docs/api/server/open77-resource Queues a resource start for the next tick boundary. Requires resources.control. Returns true when queued, otherwise false and a reason. The example registers an event-open command that starts the summer_event resource. ```lua -- Start the event resource when an admin opens the event RegisterCommand("event-open", function() Open77.resource.start("summer_event") end, true) ``` -------------------------------- ### Open photo mode example Source: https://open2077.net/docs/api/client/open77-photomode Example showing how to bind a key to open photo mode. ```lua -- A key owned by this resource opens photo mode (the stock shortcut is disabled) RegisterKeyMapping("photo", "Photo mode", "F8", function() local ok, reason = Open77.photoMode.open() if not ok then Open77.hud.notify("Photo mode unavailable: " .. reason) end end) ``` -------------------------------- ### Open77.voice.setup(operation, payload?) Source: https://open2077.net/docs/guided-voice-setup Build a microphone setup step inside your server's onboarding or settings interface. It shares device selection, volumes, activation settings and the keyboard/mouse push-to-talk binding with the pause menu. ```APIDOC ## Open77.voice.setup(operation, payload?) ### Description Build a microphone setup step inside your server's onboarding or settings interface. It shares device selection, volumes, activation settings and the keyboard/mouse push-to-talk binding with the pause menu. ### Method Function call ### Endpoint Open77.voice.setup(operation, payload?) ### Parameters - **operation** (string) - Required - The operation to perform on the setup session. - **payload** (table) - Optional - Additional data for the operation. ### Request Example ```lua Open77.voice.setup("open", { ... }) ``` ### Response Returns a snapshot or result depending on the operation. ### Errors and fallback Refer to the source documentation for error handling details. ``` -------------------------------- ### setFrozen Example Source: https://open2077.net/docs/api/client/open77-vehicles Example usage of setFrozen combined with setControlLock to manage vehicle state on a race starting grid. ```lua -- Starting grid: lock the inputs and freeze the chassis until GO RegisterNetEvent("race:grid", function(vehicleId) Open77.vehicles.setControlLock(vehicleId, true) Open77.vehicles.setFrozen(vehicleId, true) end) RegisterNetEvent("race:go", function(vehicleId) Open77.vehicles.setFrozen(vehicleId, false) Open77.vehicles.setControlLock(vehicleId, false) end) ``` -------------------------------- ### SetPropBucket Example Source: https://open2077.net/docs/api/server/globals Demonstrates using the preferred Open77 alias to move props into a specific bucket. ```lua -- SetPropBucket is the low-level form of Open77.props.setBucket (bound to the same native); -- the example shows the Open77.* spelling resources are told to prefer. -- Move the stage props into the concert instance for _, propId in ipairs(stageProps) do Open77.props.setBucket(propId, CONCERT_BUCKET) end ``` -------------------------------- ### Set Prediction Policy Example Source: https://open2077.net/docs/api/client/open77-prediction Example of setting a prediction policy on resource start, requiring the prediction.policy permission. ```lua -- open77.lua: permissions { "prediction.policy" }; normally only open77_prediction does this. AddEventHandler("onClientResourceStart", function(name) if name ~= GetCurrentResourceName() then return end local ok, reason = Open77.prediction.setPolicy({ families = { blast = false }, maxPingMs = 200 }) if not ok then print("prediction policy refused: " .. tostring(reason)) end end) ``` -------------------------------- ### Open77.vfx.catalog Example Source: https://open2077.net/docs/api/client/open77-vfx Example of iterating through and printing all available VFX aliases. ```lua -- Print every alias this client can play for alias, path in pairs(Open77.vfx.catalog() or {}) do print(alias, path) end ``` -------------------------------- ### Get player stats command example Source: https://open2077.net/docs/api/server/open77-players Example command to display a player's health and stamina in the chat. ```lua -- Show health and stamina together on request RegisterCommand("stats", function(source) local stats = Open77.players.getStats(source) if stats then Open77.chat.send(source, ("HP %d / %d Stamina %d / %d"):format( stats.health, stats.maxHealth, stats.stamina, stats.maxStamina)) end end, false) ``` -------------------------------- ### Open77.cyberware.lease Example Source: https://open2077.net/docs/api/server/open77-cyberware Example usage of the lease method with a specified duration. ```lua local result, err = Open77.cyberware.lease(playerId, "myrp.gorilla", "training", {durationMs=60000}) if not result then print(err); return end -- Keep result.lease; wait for its matching active event before PvP. ``` -------------------------------- ### Open77.equipment.records usage example Source: https://open2077.net/docs/api/client/open77-equipment Example demonstrating how to list up to 50 items in the 'Head' slot. ```lua -- Fill the shop's hat list for _, item in ipairs(Open77.equipment.records({ slot = "Head", limit = 50 }) or {}) do print(item.record) end ``` -------------------------------- ### Example: Check Time Scale Source: https://open2077.net/docs/api/server/open77-world Example usage of getTimeScale to defer a round start if another resource is holding the clock. ```lua -- Refuse to start a round while another resource is still holding a beat. local held = Open77.world.getTimeScale(ARENA_BUCKET) if held and held.scale < 1 then print(("round start deferred: %s holds the clock at %.2f"):format(tostring(held.owner), held.scale)) end ``` -------------------------------- ### Open77.kvp.stats example - log store usage at startup Source: https://open2077.net/docs/api/server/open77-kvp Example usage of Open77.kvp.stats to log the store usage at startup. Checks if stats is not nil before formatting and printing the entry and byte counts. ```lua -- Log the store usage at startup local stats = Open77.kvp.stats() if stats then print(("kvp: %d entries, %d bytes"):format(stats.entries, stats.bytes)) end ``` -------------------------------- ### Get wanted level command example Source: https://open2077.net/docs/api/server/open77-players Example command to show a player their current wanted level and maximum level. ```lua -- /wanted: show a player their current heat RegisterCommand("wanted", function(source) local wanted = Open77.players.getWanted(source) if wanted then Open77.chat.send(source, ("Wanted level %d of %d"):format(wanted.level, wanted.maxLevel)) end end, false) ``` -------------------------------- ### Get Current Perspective Example Source: https://open2077.net/docs/api/client/open77-perspective Example showing how to adjust UI elements, such as a crosshair, based on the current active perspective. ```lua -- Adjust the crosshair for the view actually in force SetTick(function() crosshair.big = Open77.perspective.get() == "tps" end) ``` -------------------------------- ### Open77.network.catalog Usage Example Source: https://open2077.net/docs/api/client/open77-network Demonstrates how to refresh the catalog and read the server list after a delay. ```lua -- The server browser reads the catalog a beat after refreshing it CreateThread(function() Open77.network.refresh() Wait(1000) local catalog = Open77.network.catalog() for _, server in ipairs(catalog.servers or {}) do print(server.name) end end) ``` -------------------------------- ### Example usage of open77_doors configure Source: https://open2077.net/docs/api/server/resource-open77-doors Demonstrates how to call the configure export and await the resulting Promise. ```lua CreateThread(function() local pending, error = Open77.exports.call("open77_doors", "configure", id, bucket, patch) if not pending then print(error); return end local result, reason = pending:await() -- Handle the result before continuing; queued is not accepted. end) ``` -------------------------------- ### Get Prediction Stats Example Source: https://open2077.net/docs/api/client/open77-prediction Example of registering a command to print current prediction statistics, including ping and per-family counters. ```lua RegisterCommand("predstats", function() local stats, reason = Open77.prediction.stats() if not stats then print(reason); return end print(("ping %d ms, ceiling %d ms"):format(stats.ping, stats.maxPingMs)) for name, family in pairs(stats.families) do print(name, family.enabled, family.predicted, family.adopted, family.refuted) end end, false) ``` -------------------------------- ### Open77.players.identifier Source: https://open2077.net/docs/server-api Returns the persistent installation identity GUID for a player. ```APIDOC ## Open77.players.identifier ### Description Returns the persistent installation identity GUID (`userId`) for a player, or `nil` if not available. Use `license` from `identifiers` for account-level persistence. ### Function `Open77.players.identifier(playerId)` ### Permission None ### Parameters - **playerId** - Required - The player ID. ### Returns Persistent installation identity GUID (string) or `nil`. ``` -------------------------------- ### Capabilities Example Source: https://open2077.net/docs/api/client/open77-remotecamera Example of retrieving and printing the system capabilities as a JSON string. ```lua local capabilities = Open77.remoteCamera.capabilities() print(Open77.json.encode(capabilities)) ``` -------------------------------- ### TriggerClientEvent example Source: https://open2077.net/docs/api/server/globals Example Lua code showing how to send a balance event to a specific player and broadcast a heist started event to all clients. ```lua -- Tell one player their balance, and everybody that the heist started RegisterCommand("balance", function(source) if tonumber(source) < 1 then print("balance: run in game, not at the console"); return end TriggerClientEvent("bank:balance", source, getBalance(source)) end, false) TriggerClientEvent("heist:started", -1, { vault = "arasaka" }) ``` -------------------------------- ### Open77.vehicles.releaseAdopted Example Source: https://open2077.net/docs/api/client/open77-vehicles Example showing how to release an adopted chassis after server acceptance. ```lua -- The server accepted the proposal: hand the vanilla chassis back RegisterNetEvent("garage:adopted", function(engineEntity, vehicleId) Open77.vehicles.releaseAdopted(engineEntity) Open77.hud.notify(("Vehicle #%d is yours"):format(vehicleId)) end) ``` -------------------------------- ### Example: Forwarding a dash phase Source: https://open2077.net/docs/api/client/open77-dash This example demonstrates how a support resource forwards a server-accepted dash phase to the native projector using Open77.dash.call. ```lua -- The support resource forwards a server-accepted dash phase to the native projector RegisterNetEvent("dash:phase", function(...) Open77.dash.call("present", ...) end) ``` -------------------------------- ### Example: Block FastTravel during a race Source: https://open2077.net/docs/api/client/open77-input Lua example showing how to block FastTravel when a race starts and unblock it when the race finishes. Requires input.actions permission. ```lua -- No fast travel during the race AddEventHandler("race:started", function() Open77.input.setActionBlocked("FastTravel", true) end) AddEventHandler("race:finished", function() Open77.input.setActionBlocked("FastTravel", false) end) ``` -------------------------------- ### setEquipment usage example Source: https://open2077.net/docs/api/server/open77-npcs Example showing how to set an NPC's equipment and handle potential errors. ```lua -- Canonical state, replicated and kept for late joiners. Whether the clerk is -- SEEN in these clothes is decided per client against the live game: a -- `Character.*` record that does not declare the slot refuses it with -- `slot_unavailable`, and measured on 2.31 a Character rig renders none of it. -- Read it back with getEquipment; do not treat a `true` here as a visible outfit. local ok, reason = Open77.npcs.setEquipment(clerkId, { OuterChest = "Items.Jacket_01_basic_01", Legs = "Items.Pants_01_basic_01", Feet = "Items.Shoes_01_basic_01", }) if not ok then print("could not dress the clerk: " .. reason) end ``` -------------------------------- ### StartResource(name) Source: https://open2077.net/docs/api/server/globals FiveM-style alias for Open77.resource.start. Requires resources.control permission. Queued, not immediate. ```APIDOC ## StartResource(name) ### Description FiveM-style alias for `Open77.resource.start`. Requires `resources.control`. Queued, not immediate. ### Signature ```lua StartResource(name) ``` ### Parameters - **name** (string) - Required - The name of the resource to start. ### Returns - **true** when queued, otherwise **false** - **reason** (string) - Failure reason if not queued. ### Example ```lua -- Start the event resource when an admin opens the event RegisterCommand("event-open", function(source) local ok, reason = StartResource("summer_event") if not ok then Open77.chat.send(source, reason) end end, true) ``` ``` -------------------------------- ### Open77.world.setSafeAreas example Source: https://open2077.net/docs/api/client/open77-world Example Lua code that disables safe areas when the resource starts, making a lobby staged in the Afterlife playable. Uses AddEventHandler and GetCurrentResourceName. ```lua -- The deathmatch lobby is staged in the Afterlife: make it playable AddEventHandler("onClientResourceStart", function(name) if name == GetCurrentResourceName() then Open77.world.setSafeAreas(false) end end) ``` -------------------------------- ### Open77.players.getHoloCallEyes example Source: https://open2077.net/docs/api/server/open77-players Example Lua code that checks if the player is already on a call before starting a new one. If not enabled, it sets the holocall eyes with a duration of 30000 ms. ```lua -- Is the player already on a call before starting a new one? local enabled = Open77.players.getHoloCallEyes(playerId) if not enabled then Open77.players.setHoloCallEyes(playerId, true, { durationMs = 30000 }) end ``` -------------------------------- ### Manifest Configuration Example Source: https://open2077.net/docs/resource-runtime A complete open77.lua manifest demonstrating resource metadata, script declarations, file assets, and dependency management. ```lua resource "garage" version "1.0.0" open77_version ">=0.0.1" auto_start true reload_policy "local" shared_script "shared/config.lua" client_script "client/main.lua" client_script "client/hud.lua" server_script "server/main.lua" files { "assets/**/*.png" } web_ui_page "web/index.html" web_ui_auto_create false web_files { "web/**" } dependencies { "inventory >=1.0.0", "open77_notifications" } permissions { "local.events", "network.events" } ``` -------------------------------- ### Open77.equipment.equip Example Source: https://open2077.net/docs/api/client/open77-equipment Example of equipping a record triggered by a network event. ```lua -- The wardrobe menu: put on the selected cap RegisterNetEvent("wardrobe:pick", function(record) local ok, reason = Open77.equipment.equip(record) if not ok then Open77.hud.notify("Cannot wear that: " .. reason) end end) ``` -------------------------------- ### Open77.markers.get() example Source: https://open2077.net/docs/api/client/open77-markers Example usage of get. Checks if a marker has failed to load and prints the error. A valid handle can still be loading; rendered does not certify on-screen visibility. ```lua local state, reason = Open77.markers.get(marker) if state and state.failed then print(state.error) end ``` -------------------------------- ### Open77.hacking.capabilities Usage Example Source: https://open2077.net/docs/api/server/open77-hacking Example showing how to print supported hack kinds at startup. ```lua -- Print the hack kinds this server supports at startup local caps = Open77.hacking.capabilities() if caps then for _, kind in ipairs(caps.kinds or {}) do print(kind) end end ``` -------------------------------- ### Open77.doors.state example - show lock state on HUD Source: https://open2077.net/docs/api/client/open77-doors Example showing how to get the live state of the nearest door and display its lock status on the HUD using Open77.hud.notify. ```lua -- Show the lock state of the nearest door on the HUD local door = Open77.doors.closest(3.0) if door then local live = Open77.doors.state(door.id) if live then Open77.hud.notify(live.locked and "Locked" or "Unlocked", { replace = true }) end end ``` -------------------------------- ### onResourceStart Source: https://open2077.net/docs/server-api Queued event emitted once per start into every running resource. The resource that started receives it from its own VM before any other resource is told; every other resource gets it on the next tick. ```APIDOC ## Event: onResourceStart ### Description Queued event emitted once per start into every running resource. The resource that started receives it from its own VM before any other resource is told; every other resource gets it on the next tick. ### Signature (resourceName) ### Parameters - **resourceName** (string) - The name of the resource that started. ### Example ```lua AddEventHandler("onResourceStart", function(name) if name ~= GetCurrentResourceName() then return end -- this resource is up end) ``` ``` -------------------------------- ### RestorePlayerHealth example: restore health for arena players Source: https://open2077.net/docs/api/server/globals Example Lua code that restores health for all players in a bucket at round start. It uses the Open77.stats.restoreHealth alias, which is preferred over the low-level RestorePlayerHealth. ```lua -- RestorePlayerHealth is the low-level form of Open77.stats.restoreHealth (documented alias); -- the example shows the Open77.* spelling resources are told to prefer. -- Round start: full health for everyone in the arena for _, playerId in ipairs(Open77.players.inBucket(ARENA_BUCKET)) do Open77.stats.restoreHealth(playerId) end ``` -------------------------------- ### configureSlam Usage Example Source: https://open2077.net/docs/api/client/open77-abilities Example showing how to prepare the native ground-slam projector with specific options. ```lua -- The support resource prepares the native ground-slam projector once slamRequest = Open77.abilities.configureSlam({ ground = true, air = true, staminaManaged = true, maxDurationMs = 5000, maxFallSpeed = 30, }) ``` -------------------------------- ### Example: slow final kill in arena instance Source: https://open2077.net/docs/api/server/open77-world Example Lua code that slows the world to quarter speed for 1500ms with 200ms ease when a player is killed. Uses Open77.routingBuckets.getPlayer to get the bucket. ```lua -- The whole arena instance sees the final kill at quarter speed for a moment. AddEventHandler("open77:playerKilled", function(victim, killer) local bucket = Open77.routingBuckets.getPlayer(victim) if bucket == nil then return end Open77.world.setTimeScale(bucket, 0.25, { durationMs = 1500, easeMs = 200 }) end) ``` -------------------------------- ### setPlayer example Source: https://open2077.net/docs/api/server/open77-routingbuckets Example showing how to move a player to a bucket based on a house ID. ```lua -- Each apartment is its own instance: bucket 1000 + house id RegisterNetEvent("house:enter", function(houseId) Open77.routingBuckets.setPlayer(source, 1000 + houseId) end) ``` -------------------------------- ### Open77.players.restoreStamina usage Source: https://open2077.net/docs/api/server/open77-players Example of restoring stamina for all players in a bucket to ensure they start a round without fatigue. ```lua -- Round start: full stamina so nobody starts the sprint tired for _, playerId in ipairs(Open77.players.inBucket(ARENA_BUCKET)) do Open77.players.restoreStamina(playerId) end ``` -------------------------------- ### Open77.chat.addSuggestions Example Source: https://open2077.net/docs/api/server/open77-chat Example of publishing resource commands when a player's chat is ready. ```lua -- Publish this resource's commands when a player's chat comes up RegisterNetEvent("chat:ready", function() Open77.chat.addSuggestions(source, { { command = "/job", help = "Take a delivery job" }, { command = "/park", help = "Store your car in the garage" }, }) end) ``` -------------------------------- ### Open77.io.list Example Source: https://open2077.net/docs/api/server/open77-io Example of iterating through files in a directory to load house data. ```lua -- Load every house file in data/houses/ for _, entry in ipairs(Open77.io.list("houses") or {}) do if entry.type == "file" then loadHouse(json.decode(Open77.io.read("houses/" .. entry.name))) end end ``` -------------------------------- ### ClearTick Usage Example Source: https://open2077.net/docs/api/server/globals Shows how to stop a tick once a specific condition, such as a round start time, is met. ```lua -- Count down on every tick until the round starts, then stop the tick local tick tick = SetTick(function() if GetGameTimer() >= roundStartAt then ClearTick(tick) startRound() end end) ``` -------------------------------- ### Open77.session.launcherContext() Source: https://open2077.net/docs/api/client/open77-session Returns a table with launcher-provided context about how the game was started. Returns nil plus a reason when no game backend is attached. ```APIDOC ## Open77.session.launcherContext() ### Description Returns a table with launcher-provided context about how the game was started. Returns nil plus a reason when no game backend is attached. ### Signature ```lua Open77.session.launcherContext() ``` ### Returns - table, or nil - reason on failure ### Example ```lua -- Was the game started by the launcher, and for which server? local ctx = Open77.session.launcherContext() if ctx and ctx.launched then print("launched for server", ctx.serverId) end ``` ``` -------------------------------- ### Operation Requests Source: https://open2077.net/docs/rcon Examples of various operation requests including GET, command execution, and POST with a body. ```json {"id":2,"op":"request","method":"GET","path":"/api/players"} {"id":3,"op":"command","command":"status"} {"id":4,"op":"request","method":"POST","path":"/api/restart","body":{"delaySeconds":60,"reason":"Maintenance"}} ``` -------------------------------- ### Add a custom map tab Source: https://open2077.net/docs/api/client/open77-map Example of adding a 'Jobs' tab to the map interface upon resource start. ```lua AddEventHandler('onClientResourceStart', function() local id, page = Open77.map.addTab({id='jobs', label='Jobs', url='web/jobs.html', order=10}) if not id then print(page) end end) ```