CommunityCoding & Developmentgithub.com

ali-ali18/agent-skills

Desenvolve jogos Roblox em Luau com Rojo dentro da VM e publica por Open Cloud em um lugar de TESTE informado pelo usuário.

What is agent-skills?

agent-skills is a Claude Code agent skill that desenvolve jogos Roblox em Luau com Rojo dentro da VM e publica por Open Cloud em um lugar de TESTE informado pelo usuário.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ali-ali18/agent-skills/tree/HEAD/skills/roblox

Installed? Explore more Coding & Development skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Roblox development with Rojo (Luau)

You build Roblox experiences as plain files inside the VM, compile them to a place file with Rojo and, only when asked, upload that file to a TEST place through Roblox Open Cloud. Answer the user in their language (pt-BR by default).

0. Ground rules

  • Never print, echo, log or write an API key. Use only the vault marker {{secret:<name>}} inside a shell call; the runtime swaps the value in and hides it in the output.
  • Publish ONLY to the test place the user gave you (universeId + placeId). Never guess ids and never reuse ids from another conversation. If the user gives a live/production place, stop and confirm that on purpose.
  • Default versionType is Saved (a new version in the version history, not live). Use Published only when the user explicitly asks to go live.
  • Missing universeId, placeId or secret name? Ask with propose_questionnaire (one short form). Missing secret entirely? Call secret_request (suggested name: ROBLOX_API_KEY). Never ask for the key in chat.

1. Install Rojo (once per VM)

Pinned release: Rojo 7.7.1 (check https://github.com/rojo-rbx/rojo/releases for newer 7.x and tell the user before changing the pin). Install the prebuilt Linux x86_64 binary into the home folder, no root needed:

mkdir -p "$HOME/.local/bin" && cd "$(mktemp -d)"
curl -fsSL -o rojo.zip https://github.com/rojo-rbx/rojo/releases/download/v7.7.1/rojo-7.7.1-linux-x86_64.zip
unzip -o rojo.zip && install -m 0755 rojo "$HOME/.local/bin/rojo"
export PATH="$HOME/.local/bin:$PATH"
rojo --version   # expect: rojo 7.7.1

Check first with command -v rojo; skip the install if it already prints 7.x. On an ARM VM use the linux-aarch64 asset. Alternative when a toolchain manager is already present: rokit add rojo-rbx/rojo && rokit install. Do not run installers from any other URL.

2. Project layout

my-game/
  default.project.json
  src/
    server/     -> ServerScriptService.Server   (server-only code)
    client/     -> StarterPlayer.StarterPlayerScripts.Client
    shared/     -> ReplicatedStorage.Shared      (modules both sides may require)

default.project.json:

{
  "name": "my-game",
  "tree": {
    "$className": "DataModel",
    "ServerScriptService": { "Server": { "$path": "src/server" } },
    "ReplicatedStorage": { "Shared": { "$path": "src/shared" } },
    "StarterPlayer": {
      "$className": "StarterPlayer",
      "StarterPlayerScripts": { "Client": { "$path": "src/client" } }
    }
  }
}

File naming Rojo understands: init.server.luau (a Script for the folder), *.server.luau (Script), *.client.luau (LocalScript), plain *.luau (ModuleScript), init.luau (folder becomes a ModuleScript). Add a .gitignore with *.rbxl, *.rbxlx, Packages/. Create the project only when the folder has no default.project.json; never overwrite an existing layout, adapt to it.

3. Coding conventions

  • Luau with --!strict at the top of every file. Type function signatures and exported tables.
  • One responsibility per ModuleScript, returning a table. No globals, no _G, no shared. Use require with direct references (script.Parent.Module or ReplicatedStorage.Shared.Module).
  • Keep entry points tiny: one init.server.luau and one client entry that require services/controllers and start them in order.
  • Fetch services at the top: local Players = game:GetService("Players"). Prefer task.wait, task.spawn, task.delay over wait/spawn/delay. Disconnect per-player connections on Players.PlayerRemoving.
  • Never trust the client. The server owns game state (currency, inventory, damage, teleports, progression). The client only sends intent and renders results.

Remotes security checklist

  • Create RemoteEvent/RemoteFunction instances under ReplicatedStorage from the server with a fixed name; never create them from the client.
  • On every OnServerEvent/OnServerInvoke: validate argument count and types (typeof), clamp ranges, reject NaN/inf, bound string length, check the player is allowed (cooldown, ownership, distance, alive).
  • Rate-limit per player (token bucket or last-call timestamp). A remote must never carry a price, damage amount or any value the client could choose to its advantage.
  • RemoteFunction: never InvokeClient (a malicious client can hang the server thread).
  • DataStore: wrap in pcall, retry with backoff, save on PlayerRemoving and game:BindToClose; session-lock valuable data.
  • Secrets and tuning knobs live in ServerScriptService/ServerStorage only, never in ReplicatedStorage.

4. Build

rojo build default.project.json -o place.rbxl
ls -l place.rbxl

Fix build errors first (missing $path, bad JSON, duplicate names). Do not commit place.rbxl. selene / stylua --check are optional; do not install them unless asked. A place built from files only is a script skeleton: assets, terrain and UI made in Studio live in the place that already exists, so uploading REPLACES the content of the target version. This is exactly why the target must be a test place.

5. Publish via Open Cloud (test place)

Endpoint (Roblox Open Cloud Place Publishing, universes v1):

POST https://apis.roblox.com/universes/v1/{universeId}/places/{placeId}/versions?versionType=Saved|Published

  • Header x-api-key: <key>; Content-Type: application/octet-stream for .rbxl (binary), application/xml for .rbxlx.
  • Body: the raw place file. Success response: { "versionNumber": 7 }.
  • The API key needs the universe-places permission with Write on the target experience (created in the Creator Dashboard).
  • HTTPS only. The API does not update some instance types (EditableImage, EditableMesh, PartOperation, SurfaceAppearance, BaseWrap): tell the user to publish those from Studio.
  • Docs: https://create.roblox.com/docs/en-us/cloud/guides/usage-place-publishing

Run it with the vault marker (the marker goes inside the shell command, never in your message text):

curl -sS -X POST \
  "https://apis.roblox.com/universes/v1/$UNIVERSE_ID/places/$PLACE_ID/versions?versionType=Saved" \
  -H "x-api-key: {{secret:ROBLOX_API_KEY}}" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @place.rbxl

Replace $UNIVERSE_ID and $PLACE_ID with the numbers the user gave, and the secret name with the real vault name (secret_list shows names only). Handle errors without exposing the key: 401/403 = key invalid or missing the permission/experience; 404 = wrong universe/place pair; 400 = bad file (rebuild); 429 = wait and retry once. Quote only the HTTP status and the response body, which never contains the key.

6. Report

End every task with a short report in the user's language:

  1. What changed (files and behavior), in plain words.
  2. The rojo build result and, if published, the versionNumber, the versionType used and that it went to the test place <placeId>.
  3. How to test in Studio: open the test place, open Version History to load the new Saved version, press Play (F5), and the exact things to try with the expected Output messages.
  4. What you did NOT do (live publish, assets or terrain that need Studio).

7. Local sync option

For live editing the user can run rojo serve on their own computer with the Rojo Studio plugin (https://rojo.space/docs/v7/getting-started/installation/). The VM cannot be reached from their Studio, so inside the VM stay with build plus Open Cloud upload.

Related Skills