OPEN//77 · guide

Sell on OPEN//77, step by step.

Two ways to earn: sell a script to server operators, or sell bonuses to the players of your own server.

BetaCode escrowPerks: Partial

Checkout opens on Tebex approval.

Every step here can be set up and tested today; payments through Tebex start once Tebex approves them.

Track 1

Sell a script.

A studio sells a script to the people who run OPEN//77 servers. Example: Kestrel Works sells Inventory Pro.

  1. Step 1: Create your account and creator profile.

    Sign up, then open Dashboard → Settings → Creator profile. Its username names your packages: kestrel//inventory-pro.

    Create an account

    The Creator profile section of Dashboard Settings: namespace kestrel//, display name Kestrel Works, a one-line bio.
  2. Step 2: Make an access token.

    Dashboard → Settings → Access tokens. It starts with sg_pat_ and is shown once: copy it then.

    • Keep it out of resource folders and repositories.

    Your access tokens

    The Access tokens section: a token named laptop-cli has just been created and its value, blurred here, is shown once with a Copy button.
  3. Step 3: Install the CLI.

    It needs Node.js 22 or later. Then sign it in with your token.

    npm install -g https://github.com/scriptgo-hq/scriptgo-sdk/releases/download/v0.1.6/scriptgo-cli-0.1.6.tgz
    scriptgo login --token <your token>

    The CLI

    An open tool case on a mountain ledge at dusk.
  4. Step 4: Write the resource.

    A folder with a scriptgo.lua manifest and your shared, server and client scripts. scriptgo init inventory_pro writes one to start from.

    inventory_pro/scriptgo.lua
    resource "inventory_pro"
    version "1.0.0"
    scriptgo_version ">=0.1.0"
    title "Inventory Pro"
    license "LicenseRef-Proprietary"
    licensed true
    
    lua { "5.1", "5.4", "luajit" }
    environments { "standalone", "open77" }
    capabilities { "events", "storage", "licensing" }
    
    shared_script "shared/core.lua"
    server_script "server/main.lua"
    server_script "server/license.lua"
    client_script "client/main.lua"
    test_script "tests/core_test.lua"
    inventory_pro/server/license.lua
    CreateThread(function()
      local result, code = ScriptGo.licensing.verify({
        -- on OPEN//77: the convar inventory_pro:license_key
        licenseKey = ScriptGo.config.get("license_key"),
        package = "kestrel//inventory-pro",
      })
      if not result or not result.valid then
        local why = result and result.reason or code
        ScriptGo.log.error("licence: " .. tostring(why))
      end
    end)
    • OPEN//77 sends shared and client scripts to players' game clients: keep valuable logic in server scripts.
    • OPEN//77's sandbox has no os, io, debug, package or load; scriptgo validate checks it.

    Quickstart

    A workbench under a canvas awning, with gears, a toolbox and a rolled plan.
  5. Step 5: Test it.

    scriptgo test runs your test scripts on Lua 5.4, 5.1 and LuaJIT. verify starts a real OPEN//77 dedicated server with your resource and reads its log.

    scriptgo test inventory_pro
    scriptgo verify inventory_pro --env open77 --open77-server <path to Open77.Server.exe>
    • Only the server half runs in verify: no game client joins.

    How a status is earned

    A stone tower going up inside wooden scaffolding.
  6. Step 6: Publish it, and protect it if you like.

    --owns-code declares your rights. With --escrow your server scripts are encrypted before they leave your machine, and run only on the server their licence is bound to.

    scriptgo publish --owns-code
    scriptgo publish --escrow --owns-code
    • Only server scripts are encrypted: shared and client scripts go to game clients, so they stay readable.
    • A licence can be revoked and a leaked copy traced. It does not make copying impossible: an operator can still inspect their own server.
    • A published version never changes: to fix 1.0.0, publish 1.0.1.

    How protection works

    The Upload a release page with “Protect this release (escrow)” ticked, a box for files left readable, and the same two commands for the CLI.
    Or upload a zip on the site, with the same option.
  7. Step 7: Connect your own Tebex store.

    Create a package for the script in your Tebex store. Then, in Dashboard → Stores, paste its webhook secret and public token, and add the webhook URL the page shows in Tebex → Developers → Webhooks.

    • Both values are stored sealed and never shown again. No staff approves your store.

    Your stores

    The Connect a store form with Tebex selected: a webhook secret field (Tebex → Developers → Webhooks) and a public token field (Tebex → Integrations → Headless API).
    The connected Tebex store card: checkout off while Tebex approval is awaited, no staff approval needed, and the webhook URL to copy (blurred here).
  8. Step 8: Set the offer and its price.

    On your package's page: New offer. Pick the billing, the price, Tebex and its package id, how many servers one licence covers, and OPEN//77 under Runs on.

    • With your rights declared on a published release, the offer is on sale. Nobody reviews it first.

    Your packages

    The New offer form: Server licence, monthly, 9.99 EUR, Tebex, Tebex package id 6012345, one deployment, OPEN//77 ticked under Runs on.
    The Offers table of the package: Server licence, €9.99 monthly via Tebex, runs on OPEN//77, checkout off until Tebex approves.

Then your buyer, on their OPEN//77 server

  1. Step 9: The buyer adds a deployment.

    After a verified payment the licence is in their Dashboard → Licences. They add a deployment for OPEN//77; its token is shown once.

    Licences

    A licence page: covered environment OPEN//77, one of one deployment in use, and the deployment harbor-eu-1 waiting for its first check.
  2. Step 10: They install it on the server.

    pack turns the package into a folder OPEN//77 loads as is. A protected release installs still encrypted, with its own steps.

    scriptgo add kestrel//inventory-pro
    scriptgo pack resources/inventory_pro --target open77 --out dist

    Set up on OPEN//77, in full

    A plug about to meet its socket on a rocky slope.
  3. Step 11: They allow the API and set the key.

    OPEN//77 keeps outbound HTTP off until the operator lists a host. The licence key goes in a convar, never in the resource folder.

    server.jsonc
    "http": { "enabled": true, "allowedHosts": ["api.scriptgo.dev"] },
    "convars": {
      "scriptgo_api": "https://api.scriptgo.dev",
      "inventory_pro:license_key": "<your licence key>"
    }

    Licensing API

    A striped barrier gate beside a guard hut, closed across a mountain road.

Track 2

Sell bonuses to your players.

A server operator sells a perk, such as a monthly VIP, to the players of their own servers. Example: Harbor City RP sells “vip”.

  • You need a creator profile and a connected store, as in Track 1.
  • Perks need players authenticated by the OPEN//77 master: a masterless (devLocalAuth) server gives its players no identifier, so they have no perk there.
  1. Step 1: Create the perk.

    Dashboard → Perks → New perk: the key your script asks for, the name players see, monthly or one-time, the price, your store and its product id, and your declaration.

    • The key cannot be changed later. What you sell is a feature of your own script, on your own server.

    Your perks

    The New perk form: key vip, name VIP, a one-line description, monthly billing, 4.99 EUR, Tebex with product id 6098765, and both declaration boxes ticked.
    The Perk offers table: vip, €4.99 per month through Tebex, sold on the seller's declaration, checkout off until Tebex approves.
  2. Step 3: Give the token to your OPEN//77 server.

    Allow the API host and set two convars. Nothing about payments is in OPEN//77: the server only asks SCRIPT//GO.

    server.jsonc
    "http": { "enabled": true, "allowedHosts": ["api.scriptgo.dev"] },
    "convars": {
      "scriptgo_api": "https://api.scriptgo.dev",
      "scriptgo_server_token": "sg_srv_..."
    }

    Player perks

    A server cabinet on a mountain ridge, with a key hanging from its lock.
  3. Step 4: Ask in your script.

    ScriptGo.perks.has tells you if a player holds the perk; on hears purchases and refunds; purchaseLink gives a player their own link to buy it.

    server/vip.lua
    AddEventHandler("playerJoining", function()
      local player = source
      CreateThread(function()   -- has() waits for the API
        local has = ScriptGo.perks.has(player, "vip")
        if has then --[[ the VIP garage slot ]] end
      end)
    end)
    
    ScriptGo.perks.on("granted", function(player, key, info)
      -- a purchase
    end)
    ScriptGo.perks.on("removed", function(player, key, info)
      -- a refund, a chargeback, the end of the period
    end)
    
    RegisterCommand("vip", function(player)
      local url = ScriptGo.perks.purchaseLink(player, "vip")
      -- send url to that player: it is signed for them
    end)
    • Add perks to the manifest’s capabilities.
    • While Tebex checkout is off, purchaseLink answers nil, "not_purchasable" for a Tebex perk.

    The script API

    A lit beacon tower above a small cabin, signalling over the sea.
  4. Step 5: The player buys it.

    The link opens a page with the perk, the price, the seller and the player's identifier, and a button to your store. No account needed.

    The purchase page a player opens: VIP, €4.99 per month, sold by Harbor City RP, for the player demo-player-0042, with a button to continue to the store.
    Shown with the test store. With Tebex, the button opens your Tebex store once checkout is live.
  5. Step 6: It holds on every server you linked.

    Granted when your store confirms the payment, renewed with the subscription, removed on a refund, a chargeback or the end of the period.

    • A server that loses the API keeps what it knew until the period ends or its offline grace runs out, whichever is first.
    A gold pass hanging at the open door of a cabin, behind a velvet rope.

Read more

Each step, in detail.