跳到正文
cccskills
免费在 GitHub 公开

scenario-roblox-luau

Use when writing, reviewing or debugging Luau in a Roblox experience: task.spawn vs task.defer vs task.wait, replacing wait() or spawn(), Deferred events and SignalBehavior, handlers running in the wrong order or not at all, 'attempt to yield across metamethod/C-call boundary', --!strict and the new type solver, typed classes and metatables, Destroy and cleanup, 'server memory keeps growing' or memory leaks, Parallel Luau with Actors and SharedTable, 'not safe to write in parallel', --!native or 'make this script faster', buffers, coroutines.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(16)

  • SKILL.md17.0 KB
  • references/critique.md5.3 KB
  • references/expert-notes.md11.1 KB
  • references/gui-paths.md4.9 KB
  • references/procedures.md28.0 KB
  • references/sources.md13.9 KB
  • scripts/agentkit/luau/Bench.luau1.3 KB
  • scripts/agentkit/luau/BufferCodec.luau6.4 KB
  • scripts/agentkit/luau/Leak.luau2.6 KB
  • scripts/agentkit/luau/LuauAudit.luau14.4 KB
  • scripts/agentkit/luau/lune_luau_audit.luau1.4 KB
  • scripts/agentkit/luau/Parallel.luau2.4 KB
  • scripts/agentkit/luau/Probe.luau6.4 KB
  • scripts/agentkit/luau/templates/Class.luau1.3 KB
  • scripts/agentkit/luau/templates/ParallelWorker.server.luau1.2 KB
  • scripts/rbx_luau.py5.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Roblox Luau Engineering

Roblox Studio (October 2026 build) on macOS, driven through the scenario-roblox-expert toolkit.

Expert Luau here means code that stays correct under Deferred events and the task scheduler, type-checks on both solvers, releases everything it creates, and earns each optimization with a number measured on this build. Prove behavior in a playtest data model instead of reasoning from Immediate-era habits.

If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-roblox-expert (channels, review loop, toolkit, current-Roblox traps).

Stance (the expert delta)

  1. task.spawn is not concurrency. It runs the body up to its first yield before the caller continues (Crusherfire). Use task.defer for "after this step": a queue that keeps call order. task.wait() and task.delay(0) resume at the next Heartbeat: the same frame from PreSimulation, the next frame from Heartbeat (Crusherfire; measured 0.07 ms vs 16.4 ms).
  2. Write Deferred-safe code. Handlers run at the next resumption point, never inside :Fire() or a property set (deferred events docs). Nested fires run in queue order, a listener connected inside a handler misses fires from the same step, and Destroying or CharacterRemoving handlers see Parent nil (Crusherfire; all measured). Read state inside the handler, use :Once(), and capture what cleanup needs before Destroy. Deferred alone cut one game's frame time from 6 to 8 ms to 4 to 5 ms (Drew Hamilton, RDC 2026).
  3. Yield only where it is legal and cheap. Never yield in __index or other metamethods, table.sort comparators or gsub callbacks: "attempt to yield across metamethod/C-call boundary". Never yield in per-frame handlers: task.wait(0.25) in Heartbeat stacked 16 threads in 1 s [added, measured]. pcall is no fix: a failed task.wait under pcall left its thread registered with the scheduler [added, measured].
  4. Type for both solvers. New modules start --!strict. Define methods as function Class.name(self: Class, ...): colon methods let field typos through on both solvers [added, tested]. Prefer composition: typed metatable inheritance raises false errors on both. Narrow with IsA or FindFirstChildOfClass instead of :: any. Gate on the old and the new solver, because strict scripts follow Workspace.UseNewLuauTypeSolver, which scripts cannot read.
  5. Every object owns its cleanup. Destroy is idempotent and disconnects every connection it made (Roblox Learn, OOP). Tables keyed by player are cleared on PlayerRemoving. Old characters are destroyed: at the Default setting a respawned character was unparented but kept its connections (measured). A leak is memory that never comes down; growth alone is not (Roblox Learn, memory leaks).
  6. Parallel Luau computes; serial code writes. One Actor per independent unit, require before the parallel phase, writes after task.synchronize() (docs; Suphi Kaner; Stewiepfing). Each Actor is its own Luau VM, so module state is not shared. Read-modify-write on a SharedTable goes through SharedTable.increment or update: a plain += 1 from 8 Actors lost 79% of updates (measured).
  7. Native code and buffers only after measurement. --!native wins on typed numeric code: 3.3x on a number loop, 4.9x on a typed Vector3 loop, nothing when the Vector3 parameter is untyped (measured; docs say annotate). Native everywhere costs startup and a global memory budget (Roblox Learn, native). Buffers pay past about 50 KB/s sustained (Crusherfire), with range checks because integer writes wrap silently.
  8. The injected chunk is not the game. An execute_luau chunk on the Server has its own module cache: it saw Counter.n = 0 where game Scripts saw 41 [added, measured]. Read game state through attributes or a BindableFunction hook.

Establish first

  • Signal mode: Workspace > SignalBehavior. Scripts cannot read it; check the Properties panel, the Rojo project file, or rbx_luau.audit(place). Default means Immediate. A Rojo-built place without the property is Default.
  • Server Authority: Workspace.AuthorityMode = Server forces Deferred and fixed-step simulation; game logic then belongs to scenario-roblox-gameplay.
  • Type setup: Workspace.LuauTypeCheckMode, UseNewLuauTypeSolver, and whether a Rojo project gives a sourcemap.
  • Where code runs: Server, Client, or under an Actor. Native code helps server scripts only.
  • Baseline numbers before any optimization: ms per frame of the hot path, KB/s on the wire, heap slope per cycle.
  • PlayerCharacterDestroyBehavior (Properties panel; not scriptable).
  • Defaults when unknown: Deferred, --!strict, both solvers gated, no native, no Actors, no buffers.

Procedure

  1. Audit what exists. Goal: find scheduler, yield, deferred, parallel, native and leak mistakes before a playtest. How: offline rbx_luau.audit("place.rbxl" or "src/", "warn") (Lune); in Studio rbx_luau.run(s, chunk, dm="Edit", kit=["LuauAudit"]) with LuauAudit.tree(game); the toolkit's Audit covers legacy APIs. GATE: 0 error findings; every warn fixed or justified in one line.
  2. Fix the idioms. Goal: current scheduler and event idioms. How: task.* only; PreSimulation, PostSimulation, PreRender instead of Stepped and RenderStepped; :Once(); yields out of frame handlers (busy flag, or one spawned worker loop); metamethods that never yield (precompute, or an explicit get that may yield). GATE: audit clean; behavior unchanged under Deferred (step 5).
  3. Type pass. Goal: errors caught at edit time on both solvers. How: --!strict, a Fields type plus typeof(setmetatable({} :: Fields, Class)), dot-typed self, composition, table.create(n, value); then rbx_luau.typecheck(paths, sourcemap=rbx_luau.sourcemap(project)). GATE: 0 errors in old and new.
  4. Ownership and cleanup. Goal: nothing outlives its owner. How: the class template (Destroy wired to Destroying); PlayerRemoving cleanup; character destruction. Prove it in a Server playtest with Leak.retained(make, release, n) and Leak.sample(cycle, 20) plus Leak.slope. GATE: alive 0 after release; heap slope flat over 20 or more cycles; 0 connections left after Destroy.
  5. Probe behavior that depends on order. Goal: facts from this place, not assumptions. How: Probe.scheduler(), Probe.delayTiming(), Probe.signals() through rbx_luau.run(..., dm="Server") and dm="Client" in one playtest (procedures P3). GATE: results recorded; no code depends on an order the probe shows Deferred changes.
  6. Optimize only with a number. Goal: keep only measured wins. How: Bench.run({plain=..., native=...}, 7) in the Server data model (interleaved rounds, warm-up, median); Parallel.workers with 1 vs N Actors and a work module; BufferCodec size vs the table payload. GATE: native ratio 1.2 or more [added threshold], parallel speedup 1.5 or more [added threshold], buffers past the bandwidth gate; otherwise revert.
  7. Hand off with evidence. Goal: a reviewer can trust the result without rerunning it. How: attach typecheck output, audit JSON, probe and bench results with build, data model and date; a playtest capture through rbx_review when the change is visible. GATE: every claim in the handoff has a number or a test name.

Numbers

ValueMeasured or statedRelative to
task.delay(0) resume0.07 ms from PreSimulation, 16.42 ms from HeartbeatStudio 0.743 Server, 60 Hz
Yielding Heartbeat handler16 concurrent threads in 1 stask.wait(0.25) per call
Deferred frame-time gain6 to 8 ms down to 4 to 5 msone shipped game (RDC 2026)
Native speedup, numeric loop3.3xplain Luau, Server, n = 200,000
Native speedup, typed Vector3 loop4.9x; untyped 0.96xsame kernel without --!native
Native size limits64K instructions per block, 32K blocks per function, 1M per scriptdocs; plus a global cap
Parallel speedup7.6x (144.5 ms to 19.0 ms)1 vs 8 Actors, 32 pure-compute jobs, 18-core Mac
SharedTable plain += 1127,107 of 160,000 updates lostSharedTable.increment lost 0
Buffer gateabout 50 KB/s sustained inboundCrusherfire
Number over a remote9 bytes; Color3 13 vs 5 packedCrusherfire
SharedTable keysstrings or integers 0 to 2^32 - 1SharedTable reference
Memory budgetabout 6.25 GB server; about 2 GB phone with 700 MB used by the OSRoblox Learn, memory leaks
Re-entrancy limit10 (docs); a self-refiring handler reached 50 without errorDeferred, BindableEvent

Quality gates

Measurable:

  • rbx_luau.typecheck: 0 errors on both solvers, with the project sourcemap.
  • rbx_luau.audit: 0 errors; warns resolved.
  • Toolkit Audit: no legacy scheduler or deprecated API findings.
  • Leak.retained alive 0 and a flat Leak.slope after every cleanup fix.
  • Probe results for the place's signal mode recorded on Server and Client.
  • Bench and Parallel ratios recorded before keeping native code or Actors.
  • BufferCodec round trip exact (or within f32 precision) and refusals tested.

Visual (when behavior is visible): a playtest capture through rbx_review showing the object moving, cleaned up, or the state you claim; for profiling claims, a MicroProfiler or Script Profiler capture taken by hand (GUI paths).

Common mistakes

MistakeSymptomFix
wait(), spawn(), delay()Throttled, late resumestask.wait, task.spawn, task.delay
Logic after :Fire() that expects the handler ranStale state under DeferredAct inside the handler, or task.defer
Destroying handler reads Parentnil errorsCapture before Destroy
task.wait in a Heartbeat handlerThread pile-up, doubled workBusy flag, or one worker loop
Yield in __index or a sort comparator"attempt to yield across metamethod/C-call boundary"Precompute; explicit getter
function C:m() in strict codeField typos passfunction C.m(self: C)
(x :: any).ChildTypos pass the checkerNarrow with IsA, FindFirstChildOfClass
Typed inheritance chain"does not have key" on valid callsComposition
players[player] = ... without PlayerRemovingServer memory climbs per joinClear on PlayerRemoving
ConnectParallel outside an ActorError; handler never runsParent the script under an Actor
require or Instance writes after desynchronize"not safe to write in parallel"Require first; write after synchronize
task.synchronize() inside pcallPlace crash in one run (cause not isolated)Keep phase switches out of pcall
--!native on untyped Vector3 codeNo speedupAnnotate parameters
buffer.writeu8(b, 0, 300)Stores 44Range-check, or BufferCodec
collectgarbage("collect")Error in Robloxgcinfo()

Handoffs

  • From scenario-roblox-architecture: module layout, cleanup library choice (Trove, Janitor, Maid), signal modules. This skill reviews the Luau inside them.
  • To scenario-roblox-networking: BufferCodec schemas and measured payload sizes; remotes, rate limits and wire formats stay there.
  • To scenario-roblox-performance: Bench and Parallel results, native candidates, leak slopes; frame budgets and profiling sessions stay there.
  • From and to scenario-roblox-gameplay: fixed-step and Server Authority code; this skill supplies scheduler and Deferred rules.
  • From scenario-roblox-data: session state keyed by player; this skill checks PlayerRemoving cleanup.
  • To scenario-roblox-tooling: the type gate and lune_luau_audit.luau for CI.

Current Roblox notes

  • Deferred is the template default; Default still maps to Immediate; Server Authority forces Deferred. SignalBehavior is NotScriptable.
  • New type solver: general release 2025-11-20 for nonstrict and nocheck; strict follows UseNewLuauTypeSolver (NotScriptable). The old solver stays through 2026.
  • wait, spawn, delay are deprecated globals; Stepped and RenderStepped are superseded.
  • Native code generation runs in server scripts; debug.dumpcodesize() works only from the Command Bar (Server view).
  • vector.create returns a Vector3 in Roblox; buffers serialize to JSON as {"m":null,"t":"buffer","base64":...}.
  • collectgarbage accepts only "count" in Roblox scripts.

References

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Handle review comments received on GitHub for the current branch's PR or a given PR number or URL, by triaging each unresolved thread, fixing what is warranted, pushing, and replying in each thread, when asked to address, fix or answer PR comments. Works in any Scenario repository.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

Generate one short Conventional Commits squash message describing only the net diff between the PR's base and head, set its header as the PR title, validate it with the repository's commitlint and both copy its description to the clipboard and display it, when asked for a squash message. Works in any Scenario repository, whatever its default branch.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

Refresh the current pull request description from its net changes, following the repository's PR template, when asked to update or write the PR summary. Works in any Scenario repository, whatever its default branch.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

scenario

免费

Use when connecting an AI agent to Scenario (scenario.com) through MCP, or when a task involves generating images, video, 3D, audio, sprites, textures, or game assets. Also when picking a Scenario model, running a LoRA, refining a generation prompt, uploading reference images, waiting on generation jobs, checking credits or quota, hitting Scenario auth, scope, or Forbidden errors, or setting up mcp.scenario.com in Claude Code, Cursor, VSCode, or another agent.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

Use when generating or handling 3D assets through the Scenario MCP server, including text-to-3D or image-to-3D meshes, GPT-6 Astra 3D or Claude Opus 5.5 3D, GLB, FBX, OBJ, STL, or VOX files, PBR-textured or game-ready models, voxel models, multi-view reconstruction, editing a mesh by prompt, retexture, remesh, UV unwrap, auto-rigging a biped or quadruped, or retargeting an animation, previewing a mesh in the 3D viewer, or downloading a model for import into Unity, Unreal, Godot, or Blender.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

Use when generating navigable 3D worlds or Gaussian splat scenes on Scenario via MCP: text-to-world, image-to-world, a 360 panorama or skybox turned into a walkable splat, multi-view photos or a video walkthrough reconstructed as a splat, or one object photo to splat. Keywords: World Labs Marble 1.1, 1.1 Plus, 1.0 Draft, Hunyuan World, HY World, image-to-skybox, skybox-to-splat, multiview-to-splat, TripoSplat, gaussian splatting, 3DGS, spz, world generation, explorable scene, VR.

中文简介正在准备中。当前显示原文说明。

scenario-labs/skills11012026年10月24日 更新

查看 scenario-labs 的全部技能

报告此技能的问题