AI Summarys&box is a C# scripting layer on Source 2 by Facepunch. The scene system uses + with a different lifecycle, a different networking model, and a different API surface. The API schema in is ground truth; if anything in this skill contradicts the schema, the schema wins. Match the task, open the fil
Install
Copy this and paste it into Claude Code, Cursor, or any AI assistant:
I want to install the "sbox" skill in my project. Please run this command in my terminal: # Install skill into your project mkdir -p .claude/skills/claude-sbox && curl --retry 3 --retry-delay 2 --retry-all-errors -o .claude/skills/claude-sbox/SKILL.md "https://raw.githubusercontent.com/gavogavogavo/claude-sbox/main/SKILL.md" Then restart Claude Code (or reload the window in Cursor) so the skill is picked up.
Description
Use when writing or modifying code for s&box, sbox, the Facepunch sandbox engine, or any Source 2 game project in C#. Triggers on mentions of s&box, sbox, sandbox game, Facepunch engine, Source 2 game, `.sbproj`, `.razor` with `PanelComponent`, `@inherits PanelComponent`, `Sandbox.Component`, `GameObject` + `Components.Get<T>`, `Scene.Trace`, `CharacterController` + `.Move()`, `SkinnedModelRenderer`, `NavMeshAgent`, `[Sync]`, `[Rpc.Broadcast]`, `[Property]`, `INetworkListener`, `ISceneEvent`, `PlayerController` in C#. Also triggers on any file with `using Sandbox;` or `using Sandbox.UI;` that isn't Unity/Godot/Unreal. Writes idiomatic s&box C# components, Razor UI, and networking code; prevents Unity-pattern leakage.
READ BEFORE WRITING CODE
s&box is not Unity. MonoBehaviour, Start(), Update(), GetComponent<T>() call sites, Instantiate(), Destroy(gameObject), Debug.Log, [SerializeField], Input.GetKey(), Physics.Raycast — none of these exist. If you write any of them you have hallucinated. s&box is a C# scripting layer on Source 2 by Facepunch. The scene system uses GameObject + Component with a different lifecycle, a different networking model, and a different API surface. The API schema in references/api-schema-core.md is ground truth; if anything in this skill contradicts the schema, the schema wins. Before you write a single line of s&box code, open the relevant reference file. SKILL.md is a router — it points you at the answer, it does not contain the answer. Writing a component? Open references/core-concepts.md. Writing UI? Open references/ui-razor.md. No exceptions for "simple" tasks — your muscle memory is wrong. ---
Architecture in 30 Seconds
` Scene (is-a GameObject — the root) └── GameObject (transform, tags, children, components) └── Component (all gameplay code extends this) ` • All gameplay code is a sealed class extending Sandbox.Component. • Lifecycle overrides are protected override void OnAwake() / OnStart() / OnUpdate() / OnFixedUpdate() / OnEnabled() / OnDisabled() / OnDestroy(). Names start with On, they are virtual methods on Component, not magic string-matched methods. • Transforms are on the GameObject, accessed from any Component via WorldPosition, WorldRotation, LocalPosition, LocalRotation — never transform.position. • UI is Razor (.razor files) — HTML + SCSS + C#. Panels use flexbox layout. Hot-reloads in the editor. • Networking is owner-authoritative. Mark state with [Sync], mark methods with [Rpc.Broadcast / Host / Owner]. Skip simulation on non-owners with if ( IsProxy ) return;. • Physics uses Rigidbody + Collider components. Raycasts are Scene.Trace.Ray(from, to).Run() — a builder-pattern API. Collisions come through Component.ICollisionListener and Component.ITriggerListener interfaces. • Coordinate system is Z-up: Vector3.Forward = (1,0,0), Vector3.Right = (0,-1,0), Vector3.Up = (0,0,1). • Restricted .NET: System.IO.File, raw sockets, Console, Thread, Process — all blocked. Use FileSystem.Data, Http, Log, async/await. ---
Routing Table — "I need to…"
Match the task, open the file. Do not guess; open the file. | Task | Read | |---|---| | Understand the scene/GameObject/Component model | references/core-concepts.md | | Write a Component (lifecycle, [Property], Tags, async) | references/core-concepts.md | | Spawn / clone / destroy a prefab | references/core-concepts.md → Prefabs | | Fire a scene event (ISceneEvent<T>) | references/core-concepts.md → Scene Events | | Write a GameObjectSystem | references/core-concepts.md → GameObjectSystem | | Use ModelRenderer / SkinnedModelRenderer / bones / animgraph | references/components-builtin.md → Rendering | | Use Rigidbody, any Collider, joints | references/components-builtin.md → Physics | | Use CharacterController for movement | references/components-builtin.md → CharacterController | | Use the full PlayerController (built-in FPS/TPS) | references/components-builtin.md → Gameplay | | Set up a camera, HUD painter, post-processing | references/components-builtin.md → Camera, Post-Processing | | Use lights, fog, envmap probes, skybox | references/components-builtin.md → Lighting, Environment | | Add audio (SoundPointComponent, Sound.Play) | references/components-builtin.md → Audio | | Use NavMeshAgent, NavMeshLink, query NavMesh | references/components-builtin.md → Navigation | | Create particles, decals, trails, beams | references/components-builtin.md → Effects, Rendering | | Write a Razor UI panel (.razor, PanelComponent, BuildHash) | references/ui-razor.md | | Style with SCSS — flexbox, transitions, :intro / :outro, :bind | references/ui-razor.md → Styling, Layout System, Transitions | | Use built-in controls (Button, TextEntry, DropDown, VirtualList) | references/ui-razor.md → Built-in Controls | | Build a world-space panel or a NavigationHost app | references/ui-razor.md → WorldPanel, Navigation | | Set up a lobby, connect/disconnect, query Connection | references/networking.md → Lobby & Connection | | Network an object (NetworkMode, NetworkSpawn, ownership) | references/networking.md → Networked Objects, Ownership | | Use [Sync] / [Sync(SyncFlags.X)] / [Change] / NetList / NetDictionary | references/networking.md → [Sync] Properties | | Write RPCs ([Rpc.Broadcast/Host/Owner], NetFlags, caller info, filtering) | references/networking.md → RPC Messages | | React to connections (INetworkListener, INetworkSpawn, snapshot data) | references/networking.md → Network Events | | Use ISceneStartup for host vs client initialization | references/networking.md → Scene Startup | | Dedicated server / #if SERVER / user permissions | references/networking.md → Dedicated Servers | | Poll keyboard/mouse/controller input, haptics, glyphs | references/input-and-physics.md → Input | | Raycast / sphere / box / capsule trace with tag filters | references/input-and-physics.md → SceneTrace | | Access PhysicsWorld, gravity, physics events | references/input-and-physics.md → Physics World | | Implement collision/trigger listeners | references/input-and-physics.md → Collision System | | Use Vector3 / Rotation / Angles / Transform / BBox / Ray / Capsule | references/input-and-physics.md → Math Types | | Use Time.Now, Time.Delta, TimeSince, TimeUntil | references/input-and-physics.md → Time | | Draw debug gizmos (DrawGizmos, Gizmo.Draw) | references/input-and-physics.md → Gizmo | | Need the full signature of GameObject, Component, Scene, Input, etc. | references/api-schema-core.md | | Look up whether a given type exists & what it does | references/api-schema-extended.md | | See a complete worked example of a pattern before writing your own | references/patterns-and-examples.md | ---
Unity → s&box Translation Table
Any time you write one of the left column, you are hallucinating. Use the right column. | Unity / Wrong | s&box / Correct | |---|---| | class Foo : MonoBehaviour | public sealed class Foo : Component | | void Awake() | protected override void OnAwake() | | void Start() | protected override void OnStart() | | void Update() | protected override void OnUpdate() | | void FixedUpdate() | protected override void OnFixedUpdate() | | void OnEnable() / OnDisable() | protected override void OnEnabled() / OnDisabled() | | void OnDestroy() | protected override void OnDestroy() | | [SerializeField] float speed | [Property] public float Speed { get; set; } | | [HideInInspector] | [Hide] | | transform.position | WorldPosition (or GameObject.WorldPosition) | | transform.localPosition | LocalPosition | | transform.rotation | WorldRotation | | transform.forward | WorldRotation.Forward | | gameObject.SetActive(false) | GameObject.Enabled = false | | Destroy(gameObject) / Destroy(this) | GameObject.Destroy() / Component.Destroy() / DestroyGameObject() | | Instantiate(prefab, pos, rot) | prefab.Clone( pos, rot ) | | Instantiate(prefab); NetworkServer.Spawn(...) | prefab.Clone(pos).NetworkSpawn( owner ) | | GetComponent<T>() in Start/Update | GetComponent<T>() is fine; also Components.Get<T>( FindMode ) for ancestor/descendant searches | | FindObjectOfType<T>() / FindObjectsOfType<T>() | Scene.Get<T>() / Scene.GetAll<T>() / Scene.GetAllComponents<T>() | | GameObject.Find("Name") | Scene.Directory.FindByName("Name") | | OnCollisionEnter(Collision c) | Implement Component.ICollisionListener.OnCollisionStart(Collision c) | | OnTriggerEnter(Collider c) | Implement Component.ITriggerListener.OnTriggerEnter(Collider c) | | Physics.Raycast(...) | Scene.Trace.Ray( from, to ).Run() (builder; returns SceneTraceResult) | | Physics.OverlapSphere(pos, r) | Scene.Trace.Sphere( r, pos, pos ).RunAll() | | Rigidbody.AddForce(f, ForceMode.Impulse) | Rigidbody.ApplyImpulse( f ) | | Rigidbody.AddForce(f) | Rigidbody.ApplyForce( f ) | | Rigidbody.velocity | Rigidbody.Velocity (capital V) | | Input.GetKey(KeyCode.W) | Input.Down( "forward" ) — actions are strings configured in Project Settings | | Input.GetKeyDown(...) | Input.Pressed( "action" ) | | Input.GetAxis("Horizontal") / Vertical | Input.AnalogMove (Vector3) | | Input.mousePosition | Mouse.Position (Vector2) | | Camera.main | Scene.Camera | | Camera.main.ScreenPointToRay(Input.mousePosition) | Scene.Camera.ScreenPixelToRay( Mouse.Position ) | | StartCoroutine(Foo()) with IEnumerator | async Task Foo() with await Task.DelaySeconds(...); call as _ = Foo(); | | `yield return new WaitFo
Discussion
Health Signals
My Fox Den
Community Rating
Sign in to rate this booster