### Install Workshop Item Source: https://docs.facepunch.com/s/sbox-dev/doc/storage-ugc-hSgsh1Dvog Demonstrates how to query for workshop items and install them locally to access their files and metadata. ```APIDOC ## POST /Storage/QueryItem/Install ### Description Downloads and installs a workshop item identified by a query result. Once installed, the entry provides read-only access to its files and metadata. ### Method POST ### Endpoint Storage.QueryItem.Install() ### Parameters None - Invoked on a QueryItem instance. ### Request Example // No request body required, method called on instance ### Response #### Success Response (200) - **entry** (Storage.Entry) - The installed entry object containing file access and metadata. #### Response Example { "entry": { "Id": "12345", "Type": "save", "Files": "FileSystem" } } ``` -------------------------------- ### Model Asset Preview Example Source: https://docs.facepunch.com/s/sbox-dev/doc/asset-previews-ikgF8IYAjX Example of an AssetPreview implementation for a model resource, demonstrating how to load the model, set up a SkinnedModelRenderer, and position the camera. ```APIDOC ## Model Asset Preview Example ### Description This example shows how to create a custom asset preview for a model resource. It defines a class `PreviewMyModelResource` that inherits from `AssetPreview`. The class customizes the preview's rotation speed and thumbnail generation, loads the model, sets up a `SkinnedModelRenderer`, and centers the scene around the model's bounds. ### Method N/A (This is a class definition for asset preview) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ### Code Example ```csharp [AssetPreview( "mymdl" )] public class PreviewMyModelResource : AssetPreview { // The speed at which the model rotates. The length of a cycle in seconds is 1 / CycleSpeed public override float PreviewWidgetCycleSpeed => 0.2f; // This will evaluate a few frames and pick the one with the least alpha and most luminance for the thumbnail public override bool UsePixelEvaluatorForThumbs => true; public PreviewMyModelResource( Asset asset ) : base( asset ) { } public override Task InitializeAsset() { // Get the resource from the asset var resource = Asset.LoadResource(); // Get the Model from the resource var model = resource?.Model; if ( model is null ) { return Task.CompletedTask; } // Make sure we are scoped to the preview scene using ( Scene.Push() ) { // Create a new GameObject with a SkinnedModelRenderer component PrimaryObject = new GameObject( true, "Model Preview" ); PrimaryObject.WorldTransform = Transform.Zero; var modelRenderer = PrimaryObject.AddComponent(); modelRenderer.PlayAnimationsInEditorScene = true; modelRenderer.Model = model; // Set the model on the renderer // Center the scene around the model bounds, so the camera is positioned correctly SceneSize = model.Bounds.Size; SceneCenter = model.Bounds.Center; } return Task.CompletedTask; } } ``` ``` -------------------------------- ### Install Workshop Item in S&box Source: https://docs.facepunch.com/s/sbox-dev/doc/storage-ugc-hSgsh1Dvog Demonstrates how to query for a workshop item based on tags, install the chosen item, and access its metadata and files. It also notes that workshop entries are read-only. ```csharp var query = new Storage.Query { TagsRequired = { "save" } }; Storage.QueryResult result = await query.Run(); Storage.QueryItem chosenItem = result.Items.First(); // Install the workshop item Storage.Entry entry = await chosenItem.Install(); if ( entry == null ) throw new Exception( "Failed to install the chosen item." ); // The entry is now available locally Log.Info( $"Installed: {entry.Type} - {entry.Id}" ); // Read its metadata var playerName = entry.GetMeta( "playerName" ); // Access its files (read-only) if ( entry.Files.FileExists( "player.json" ) ) { var data = entry.Files.ReadAllText( "player.json" ); // Load the save... } // Workshop entries are read-only if ( entry.Files.IsReadOnly ) { Log.Info( "This is a workshop item (read-only)" ); } ``` -------------------------------- ### Example: GameNetworkManager Source: https://docs.facepunch.com/s/sbox-dev/doc/network-events-te4Wq9RLvs An example implementation of a component that uses INetworkListener to manage player spawning and ownership upon connection. ```APIDOC ## POST /api/users ### Description Creates a new user in the system. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **username** (string) - Required - The desired username for the new user. - **email** (string) - Required - The email address for the new user. - **password** (string) - Required - The password for the new user. ### Request Example ```json { "username": "johndoe", "email": "john.doe@example.com", "password": "securepassword123" } ``` ### Response #### Success Response (201) - **id** (string) - The unique identifier for the newly created user. - **username** (string) - The username of the created user. - **email** (string) - The email address of the created user. #### Response Example ```json { "id": "usr_abc123xyz", "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### CSS background-position Examples Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Shows how to define the starting position of a background image. It can accept one or two length values, specifying horizontal and vertical offsets respectively. This is useful for controlling background image placement. ```css background-position: 10px; ``` ```css background-position: 10px 15px; ``` -------------------------------- ### Start and Stop Basic Recording - C# Source: https://docs.facepunch.com/s/sbox-dev/doc/recording-api-cgdhAXIA6Z Demonstrates the fundamental usage of MovieRecorder to start and stop capturing the scene. It captures all default renderers, cameras, and sounds. The recording can then be compiled into a MovieClip. ```csharp var recorder = new MovieRecorder( Scene ); recorder.Start(); // ... later ... recorder.Stop(); ``` -------------------------------- ### Implementing AssetPreview Source: https://docs.facepunch.com/s/sbox-dev/doc/asset-previews-ikgF8IYAjX A guide on how to create a custom preview class for textures by overriding the InitializeAsset and UpdateScene methods. ```APIDOC ## CLASS AssetPreview ### Description Base class for creating custom previews for assets within the sbox editor. Developers can override methods to control how an asset is rendered in the preview window. ### Methods - **InitializeAsset()**: Called to set up the scene and objects for the preview. - **UpdateScene(float cycle, float timeStep)**: Called to update the preview scene, typically used for camera manipulation or animation. ### Implementation Example ```csharp [AssetPreview( "mytex" )] public class PreviewMyTextureResource : AssetPreview { public override bool IsAnimatedPreview => false; public PreviewMyTextureResource( Asset asset ) : base( asset ) { } public override Task InitializeAsset() { var resource = Asset.LoadResource(); var texture = resource?.Texture; if ( texture is null ) return Task.CompletedTask; using ( Scene.Push() ) { PrimaryObject = new GameObject( true, "Texture Preview" ); var spriteRenderer = PrimaryObject.AddComponent(); spriteRenderer.Texture = texture; spriteRenderer.Size = 100; } return Task.CompletedTask; } public override void UpdateScene( float cycle, float timeStep ) { base.UpdateScene( cycle, timeStep ); Camera.Orthographic = true; Camera.OrthographicHeight = 100; Camera.WorldPosition = Vector3.Backward * 100; Camera.WorldRotation = Rotation.LookAt( Vector3.Forward ); } } ``` ``` -------------------------------- ### Implement ISceneStartup in GameObjectSystem Source: https://docs.facepunch.com/s/sbox-dev/doc/iscenestartup-UaHEQHresW An example of implementing ISceneStartup within a GameObjectSystem to handle scene loading and lobby creation upon host initialization. ```csharp public sealed class MyGameManager : GameObjectSystem, ISceneStartup { public MyGameManager( Scene scene ) : base( scene ) { } void ISceneStartup.OnHostInitialize() { var slo = new SceneLoadOptions(); slo.IsAdditive = true; slo.SetScene( "scenes/engine.scene" ); Scene.Load( slo ); Networking.CreateLobby(); } } ``` -------------------------------- ### Implementing Screen Space Reflections Source: https://docs.facepunch.com/s/sbox-dev/doc/screen-space-tracing-xZSBSgQV7T A practical example demonstrating how to invoke ScreenSpace::Trace and apply the resulting hit data to a material's emission property based on hit confidence. ```csharp Texture2D FrameBufferCopy = /* .. */ Material m = /* .. */ float3 origin = /* world-space origin */; float3 direction = /* world-space direction */; float2 screenPos = /* screen-space position */; TraceResult result = ScreenSpace::Trace(origin, direction, screenPos); if (result.ValidHit) { float3 vReflectionColor = FrameBufferCopy[ result.HitClipSpace.xy ].rgb; m.Emission = lerp( m.Emission, vReflectionColor, result.Confidence ); } ``` -------------------------------- ### Implement a Custom GameObjectSystem Source: https://docs.facepunch.com/s/sbox-dev/doc/gameobject-systems-6vakGETtA4 Create a custom system by inheriting from GameObjectSystem. This example demonstrates registering a method to the PhysicsStep stage and retrieving components within the scene. ```csharp public class MyGameSystem : GameObjectSystem { public MyGameSystem( Scene scene ) : base( scene ) { Listen( Stage.PhysicsStep, 10, DoSomething, "DoingSomething" ); } void DoSomething() { Log.Info( "Did something!" ); var allThings = Scene.GetAllComponents(); } ``` -------------------------------- ### Test Game Components Source: https://docs.facepunch.com/s/sbox-dev/doc/unit-tests-xtbQZBAVAb Provides an example of testing scene components, such as a camera. Demonstrates creating a scene, adding components, and verifying state changes. ```csharp using Sandbox; [TestClass] public class Camera { [TestMethod] public void MainCamera() { var scene = new Scene(); using var sceneScope = scene.Push(); Assert.IsNull( scene.Camera ); var go = scene.CreateObject(); var cam = go.Components.Create(); Assert.IsNotNull( scene.Camera ); go.Destroy(); scene.ProcessDeletes(); Assert.IsNull( scene.Camera ); } } ``` -------------------------------- ### Creating a C# Root Panel Source: https://docs.facepunch.com/s/sbox-dev/doc/ui-kM9biZcQrj Provides an example of creating a root Panel component required for drawing UI to the screen or world panels. ```APIDOC ## Creating a C# Root Panel ### Description Shows how to create a `PanelComponent`, which serves as the root for UI elements, and attach it to a GameObject with a `ScreenPanel` or `WorldPanel` component. ### Method N/A (Code Example) ### Endpoint N/A ### Parameters N/A ### Request Example ```csharp public sealed class MyRootPanel : PanelComponent { MyPanel myPanel; protected override void OnTreeFirstBuilt() { base.OnTreeFirstBuilt(); myPanel = new MyPanel(); myPanel.Parent = Panel; } } ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Using a Razor Component Source: https://docs.facepunch.com/s/sbox-dev/doc/razor-components-UI4r9NrDOY Example of how to use the InfoCard component and pass content to its Header, Body, and Footer fragments, including event handling. ```APIDOC ## Using a Razor Component This demonstrates how to instantiate and use the `InfoCard` component, providing content for its fragments and handling events. ### Component Usage ```csharp
My Card
This is my card
Close Card
@code { void CloseCard() { Delete(); } } ``` ### Event Handling Event handlers like `onclick` can be directly attached to elements within the component's fragments, allowing interaction with the parent component's code. ``` -------------------------------- ### Creating a Custom ControlWidget Source: https://docs.facepunch.com/s/sbox-dev/doc/custom-editors-A59vozXTat This example demonstrates how to create a custom editor for a 'MyClass' object using the `[CustomEditor]` attribute and extending `ControlObjectWidget`. It shows how to define a custom layout and bind properties to UI elements. ```APIDOC ## Creating a Custom ControlWidget ### Description This section details how to create a custom editor for a specific C# class (`MyClass`) in S&box. By using the `[CustomEditor]` attribute, you can define a custom visual representation and interaction for your class properties within the S&box editor. ### Method N/A (This is a code example for defining a custom editor) ### Endpoint N/A ### Parameters N/A ### Request Example ```csharp public class MyClass { public Color Color { get; set; } public string Name { get; set; } } [CustomEditor(typeof(MyClass))] public class MyCustomControlWidget : ControlObjectWidget { // Whether or not this control supports multi-editing (if you have multiple GameObjects selected) public override bool SupportsMultiEdit => false; public MyCustomControlWidget(SerializedProperty property) : base(property) { Layout = Layout.Row(); Layout.Spacing = 2; // Get the Color and Name properties from the serialized object SerializedObject.TryGetProperty(nameof(MyClass.Color), out var color); SerializedObject.TryGetProperty(nameof(MyClass.Name), out var name); // Add some Controls to the Layout, both referencing their serialized properties Layout.Add( Create(color) ); Layout.Add( Create(name) ); } protected override void OnPaint() { // Overriding and doing nothing here will prevent the default background from being painted } } ``` ### Response N/A #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Query Components from GameObject (C#) Source: https://docs.facepunch.com/s/sbox-dev/doc/components-zIujvXKpIl Provides examples of how to retrieve components attached to a GameObject and its hierarchy in S&box using C#. It covers getting single or multiple components, searching in children, and searching in parents. ```csharp var x = go.GetComponents(); var x = go.GetComponent(); var x = go.GetComponentInChildren(); var x = go.GetComponentsInChildren(); var x = go.Components.GetComponentsInParent(); var x = go.Components.GetComponentInParent(); ``` -------------------------------- ### Create and Configure Storage Entry Source: https://docs.facepunch.com/s/sbox-dev/doc/storage-ugc-hSgsh1Dvog Demonstrates how to initialize a new storage entry, write data using the Filesystem API, set metadata, and assign a thumbnail for identification. ```csharp var saveEntry = Storage.CreateEntry( "save" ); saveEntry.Files.WriteAllText( "player.json", playerJson ); saveEntry.Files.WriteAllBytes( "world.dat", worldData ); saveEntry.Files.WriteJson( "config.json", gameConfig ); saveEntry.SetMeta( "playerName", "John Doe" ); saveEntry.SetMeta( "level", 42 ); saveEntry.SetMeta( "playtime", 3600 ); var thumbnail = CreateThumbnailBitmap(); saveEntry.SetThumbnail( thumbnail ); ``` -------------------------------- ### Accessing Caller Information in RPC (C#) Source: https://docs.facepunch.com/s/sbox-dev/doc/rpc-messages-u5EwxSsBrD Demonstrates how to use the Rpc.Caller object within an RPC method to get information about the client that invoked the RPC, such as their display name and Steam ID. This example logs the caller's information if they are not the host. ```csharp void OnPressed() { PlayOpenEffects( "bing", WorldPosition ); } [Rpc.Broadcast] public void PlayOpenEffects( string soundName, Vector3 position ) { if ( !Rpc.Caller.IsHost ) return; Log.Info( $"{Rpc.Caller.DisplayName} with the steamid {Rpc.Caller.SteamId} played open effects!" ); Sound.FromWorld( soundName, position ); } ``` -------------------------------- ### GET Request Source: https://docs.facepunch.com/s/sbox-dev/doc/http-requests-5iDlWBt8lQ Performs an asynchronous GET request and returns the response body as a string. ```APIDOC ## GET [URL] ### Description Fetches the content of a URL as a string. ### Method GET ### Endpoint https://[domain]/[path] ### Parameters #### Path Parameters - **url** (string) - Required - The target URL (must be domain-based, no IPs). ### Request Example await Http.RequestStringAsync( "https://google.com" ); ### Response #### Success Response (200) - **response** (string) - The body of the HTTP response. ``` -------------------------------- ### C# Scene Startup for Game Managers Source: https://docs.facepunch.com/s/sbox-dev/doc/game-project-y3Rm2sZORZ This C# code demonstrates how to implement the ISceneStartup interface to initialize game manager systems when a scene loads. It shows how to set scene loading options, such as making the loaded scene additive, and specifies the scene file to load. ```csharp public sealed class MyGameManager : GameObjectSystem, ISceneStartup { public MyGameManager( Scene scene ) : base( scene ) { } void ISceneStartup.OnHostInitialize() { var slo = new SceneLoadOptions(); slo.IsAdditive = true; slo.SetScene( "scenes/engine.scene" ); Scene.Load( slo ); } } ``` -------------------------------- ### Initialize Engine for Tests Source: https://docs.facepunch.com/s/sbox-dev/doc/unit-tests-xtbQZBAVAb Shows how to set up the Sandbox AppSystem for tests that require engine functionality. Uses AssemblyInitialize and AssemblyCleanup attributes to manage the lifecycle. ```csharp global using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class TestInit { public static Sandbox.AppSystem TestAppSystem; [AssemblyInitialize] public static void AssemblyInitialize( TestContext context ) { TestAppSystem = new TestAppSystem(); TestAppSystem.Init(); } [AssemblyCleanup] public static void AssemblyCleanup() { TestAppSystem.Shutdown(); } } ``` -------------------------------- ### Instantiating and Adding Widgets Source: https://docs.facepunch.com/s/sbox-dev/doc/editor-widgets-WBAKDbpTd3 Shows how to instantiate a widget as a standalone window by passing null as the parent, or as a child component by adding it to an existing widget's layout. ```csharp // Creates the Widget as a new Window since it has no parent var windowExample = new ExampleWidget(null); windowExample.Show() // Creates the Widget as the child of another Widget, then adds it to that Widget's Layout var childExample = new ExampleWidget(parentWidget); parentWidget.Layout.Add(childExample); ``` -------------------------------- ### Perform GET Request as String - C# Source: https://docs.facepunch.com/s/sbox-dev/doc/http-requests-5iDlWBt8lQ This snippet demonstrates how to make a GET request to a specified URL and retrieve the response body as a string. It utilizes the `Http.RequestStringAsync` method. ```csharp string response = await Http.RequestStringAsync( "https://google.com" ); ``` -------------------------------- ### Initialize and Attach Command List Source: https://docs.facepunch.com/s/sbox-dev/doc/command-lists-X1TmQPkLR4 Demonstrates how to instantiate a Command List and attach it to a camera during the OnEnabled lifecycle event. The commands added to the list will execute sequentially for any camera that includes this list. ```csharp protected override void OnEnabled() { commands = new Rendering.CommandList( "AmbientOcclusion" ); // Build your commands here eg commands.Set("Foo", 1.0f ); Camera.AddCommandList( commands, Rendering.Stage.AfterDepthPrepass ); } ``` -------------------------------- ### Instantiating Prefabs at Runtime in C# Source: https://docs.facepunch.com/s/sbox-dev/doc/prefabs-Tiq5GBWmm3 Demonstrates how to expose a PrefabFile as a component property and clone it into the scene during runtime. It also shows how to break the prefab link if individual object modification is required. ```csharp public sealed class MyGun : Component { [Property] GameObject BulletPrefab { get; set; } protected override void OnUpdate() { // throw an error if BulletPrefab wasn't defined Assert.NotNull( BulletPrefab ); if ( Input.Pressed( "Attack1" ) ) { // create a new instance of the bullet prefab at the gun's position GameObject bullet = BulletPrefab.Clone( WorldPosition ); // bullet is now in the current scene, what do you want to do with it? // maybe get components and set the velocity or something? // Optional: break the link to the prefab // bullet.BreakFromPrefab(); } } } ``` -------------------------------- ### Finding GameObjects by GUID Source: https://docs.facepunch.com/s/sbox-dev/doc/scenes-LT2kjsMBy4 Shows how to retrieve a specific GameObject from the scene directory using its unique identifier. This provides a fast lookup mechanism for objects when the GUID is known. ```csharp var obj = Scene.Directory.FindByGuid( guid ); ``` -------------------------------- ### VirtualGrid Gotchas and Best Practices Source: https://docs.facepunch.com/s/sbox-dev/doc/virtualgrid-bMc9umC79F Provides important considerations and tips for using the VirtualGrid component effectively, including styling and item consistency. ```APIDOC ## VirtualGrid Gotchas and Best Practices ### Description This section outlines critical points to be aware of when using the `VirtualGrid` component to ensure optimal performance and correct rendering. ### Method Not Applicable (Usage Guidelines) ### Endpoint Not Applicable (Usage Guidelines) ### Parameters N/A ### Request Example N/A ### Response #### Success Response (Guidelines) - **Sizing**: Ensure the `VirtualGrid` component has explicit dimensions set in its styles (e.g., `width: 100%`, `height: 100%`). - **Item Consistency**: All items within the `VirtualGrid` must have the same dimensions. - **Spacing**: Use CSS `gap` properties on the `VirtualGrid` element to add spacing between items. #### Response Example N/A ``` -------------------------------- ### CSS border Example Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Provides an example of the shorthand 'border' property in CSS, which allows setting border-width, border-style, and border-color in one declaration. This is a common way to style element borders. ```css border: 10px solid black; ``` -------------------------------- ### Custom Toon Shading Model Example Source: https://docs.facepunch.com/s/sbox-dev/doc/shading-model-E6j9LshRnx An example of a custom toon shading model. It demonstrates segmenting lighting into Direct/Indirect and Specular/Diffuse components, and includes logic for handling depth/normal and tool visualization outputs. ```csharp class ShadingModelToon { static float4 Shade( Material m ) { float4 color = 0; // Direct Lighting for( int i=0; i < DynamicLight::Count(); i++ ) { Light l = DynamicLight::From( ScreenPosition, WorldPosition, i ); ... float3 diffuse = /* */ float3 specular = /* */ color += diffuse + specular; } // Indirect Lighting { float3 diffuse = 0; { diffuse = /* ambient light */ diffuse *= min( m.AmbientOcclusion, ScreenSpaceAmbientOcclusion::Sample( m.ScreenPosition ); } float3 specular = 0; { specular = /* envmap */ specular += /* toon fresnel */ } color += diffuse + specular; } if( DepthNormal::WantsDepthNormal() ) return DepthNormal::Output( m ); if( ToolVis::WantsToolVis() ) return ToolVis::Output( color, m ); // Composite atmospherics after lighting color.xyz = Fog::Apply( m.WorldPosition, m.ScreenPosition.xy, color ); return color; } } ``` -------------------------------- ### Implement Dynamic Inputs/Outputs in C# Source: https://docs.facepunch.com/s/sbox-dev/doc/c-shader-nodes-f9EpXHYD8d Shows how to create custom nodes with a variable number of inputs or outputs by managing lists of IPlugIn and IPlugOut, allowing for dynamic node structures. ```csharp public class DynamicNode : ShaderNode { [Hide] private List _dynamicInputs = new(); [Hide] private List _dynamicOutputs = new(); public override IEnumerable Inputs => _dynamicInputs; public override IEnumerable Outputs => _dynamicOutputs; // You can modify these lists however you want, whenever you want. // This is just a basic example of creating a new plug. public void AddInput(string name, Type type) { var info = new PlugInfo() { Name = name, Type = type, DisplayInfo = new DisplayInfo { Name = name } }; _dynamicInputs.Add(new BasePlugIn(this, info, type)); } } ``` -------------------------------- ### Custom s&box Style Property Examples Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Examples of custom style properties available in s&box, including sound triggers, text strokes, and image tinting. These properties extend standard CSS functionality for UI development. ```css /* Sound triggers */ button:hover { sound-in: "ui.button.hover"; } button:active { sound-out: "ui.button.click"; } /* Text effects */ .header { text-stroke: 2px #000000; } /* Image tinting */ .icon { background-image-tint: #ff0000aa; } /* Aspect ratio */ .container { aspect-ratio: 16/9; } ``` -------------------------------- ### CSS box-shadow Example Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Shows an example of the box-shadow property, used to add one or more shadows to an element's frame. It accepts length values for horizontal offset, vertical offset, blur radius, spread radius, and a color. ```css box-shadow: 2px 2px 4px black; ``` -------------------------------- ### Create Custom GameObjectSystem Source: https://docs.facepunch.com/s/sbox-dev/doc/gameobjectsystem-6vakGETtA4 Demonstrates how to define a new system by deriving from GameObjectSystem and registering a method to be called during a specific stage. It shows how to access components within the scene. ```csharp public class MyGameSystem : GameObjectSystem { public MyGameSystem( Scene scene ) : base( scene ) { Listen( Stage.PhysicsStep, 10, DoSomething, "DoingSomething" ); } void DoSomething() { Log.Info( "Did something!" ); var allThings = Scene.GetAllComponents(); // do something to all of the things } } ``` -------------------------------- ### GET /services/stats/get Source: https://docs.facepunch.com/s/sbox-dev/doc/stats-As30shVf3K Retrieves stat data for global scope or specific players. ```APIDOC ## GET /services/stats/get ### Description Retrieves stat information. Can be scoped to Global, LocalPlayer, or a specific player ID. ### Method GET ### Parameters #### Query Parameters - **scope** (string) - Required - 'global', 'local', or 'player'. - **statName** (string) - Required - The identifier of the stat to fetch. - **playerId** (long) - Optional - Required if scope is 'player'. ### Response #### Success Response (200) - **Sum** (number) - The aggregated value of the stat. - **Players** (number) - The count of players contributing to this stat (global only). ### Response Example { "Sum": 150, "Players": 10 } ``` -------------------------------- ### GET /services/leaderboards Source: https://docs.facepunch.com/s/sbox-dev/doc/leaderboards-HLSCo50GWh Retrieves and manages leaderboard data for specific game statistics. ```APIDOC ## GET /services/leaderboards ### Description Fetches a leaderboard instance for a specific statistic and allows for various filtering, aggregation, and sorting configurations before refreshing the data. ### Method GET ### Endpoint Sandbox.Services.Leaderboards.GetFromStat(string ident, string statName) ### Parameters #### Path Parameters - **ident** (string) - Required - The unique identifier of the game/service. - **statName** (string) - Required - The name of the statistic to track. ### Request Example // Basic initialization var board = Sandbox.Services.Leaderboards.GetFromStat("facepunch.ss1", "zombies_killed"); await board.Refresh(); ### Response #### Success Response (200) - **Entries** (List) - A list of leaderboard entries containing Rank, DisplayName, and Value. #### Response Example { "Rank": 1, "DisplayName": "PlayerName", "Value": 150 } ``` -------------------------------- ### Create a Basic Unit Test Source: https://docs.facepunch.com/s/sbox-dev/doc/unit-tests-xtbQZBAVAb Demonstrates how to define a standard MSTest class and test method. This is the entry point for validating logic within your project. ```csharp using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class MyFirstTest { [TestMethod] public void Simple() { Assert.AreEqual( 4, 2 + 2 ); } } ``` -------------------------------- ### Component Capturer Implementation Source: https://docs.facepunch.com/s/sbox-dev/doc/recording-api-cgdhAXIA6Z Example of implementing a ComponentCapturer for ModelRenderer to capture its properties. ```APIDOC ## Component Capturer Implementation ### Description This example demonstrates how to create a custom capturer for the `ModelRenderer` component. It specifies which properties of `ModelRenderer` should be captured, including conditional capture for `BodyGroups`. ### Method N/A (This is a class implementation) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ```csharp class ModelRendererCapturer : ComponentCapturer { protected override void OnCapture( IMovieTrackRecorder recorder, ModelRenderer component ) { recorder.Property( nameof( ModelRenderer.Model ) ).Capture(); recorder.Property( nameof( ModelRenderer.Tint ) ).Capture(); recorder.Property( nameof( ModelRenderer.MaterialOverride ) ).Capture(); recorder.Property( nameof( ModelRenderer.RenderType ) ).Capture(); if ( component.HasBodyGroups ) { recorder.Property( nameof( ModelRenderer.BodyGroups ) ).Capture(); } } } ``` ``` -------------------------------- ### GET /input/motion Source: https://docs.facepunch.com/s/sbox-dev/doc/controller-input-T0B8XRcyf1 Retrieves motion data from controller sensors like gyroscopes and accelerometers. ```APIDOC ## GET /input/motion ### Description Accesses the accelerometer and gyroscope data from the controller if supported. ### Method GET ### Endpoint Input.MotionData ### Response #### Success Response (200) - **Acceleration** (Vector3) - Current accelerometer readings. - **AngularVelocity** (Vector3) - Current gyroscope readings. ``` -------------------------------- ### GET /input/analog Source: https://docs.facepunch.com/s/sbox-dev/doc/controller-input-T0B8XRcyf1 Retrieves raw analog input values from controller sticks and triggers. ```APIDOC ## GET /input/analog ### Description Retrieves the current state of analog inputs from the controller. This allows for precise movement and aim tracking. ### Method GET ### Endpoint Input.GetAnalog(InputAnalog inputType) ### Parameters #### Query Parameters - **inputType** (Enum) - Required - The specific analog input to query (e.g., LeftStickX, LeftTrigger). ### Request Example Input.GetAnalog(InputAnalog.LeftStickX); ### Response #### Success Response (200) - **value** (float) - The normalized value of the analog input (-1.0 to 1.0 for sticks, 0.0 to 1.0 for triggers). ``` -------------------------------- ### Apply UI Transitions with Custom Pseudo-Classes Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Demonstrates how to use the :intro and :outro pseudo-classes in SCSS to animate UI elements during creation and deletion. The :intro state triggers upon element creation, while :outro delays deletion until transitions complete. ```scss MyPanel { transition: all 2s ease-out; transform: scale( 1 ); // When the element is created make it expand from nothing. &:intro { transform: scale( 0 ); } // When the element is deleted make it double in size before being deleted. &:outro { transform: scale( 2 ); } } ``` -------------------------------- ### Iterate Over Scene Lights Source: https://docs.facepunch.com/s/sbox-dev/doc/light-2kZG4rs3k1 Demonstrates how to loop through all available lights in the current fragment using the Light::Count and Light::From methods. This approach utilizes Frustum Tiled Lighting optimizations. ```cpp for( int i=0; i < Light::Count(); i++ ) { Light l = Light::From( ScreenPosition, WorldPosition, i ); // Process light data } ``` -------------------------------- ### Custom Style Properties Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Details custom style properties implemented in Sbox, with their parameters and usage examples. ```APIDOC ## Custom Style Properties | Name | Parameters | Examples / Notes | |------|------------|------------------| | aspect-ratio | Float, Float (Optional) | `aspect-ratio: 1;`,`aspect-ratio: 16/9;` | | background-image-tint | Color | Multiplies the `background-image` by this Color. Not a replacement for `filter` or `backdrop-filter`. | | border-image-tint | Color | Multiplies the `border-image` by this Color. | | mask-scope | default / filter | `default` will apply the mask normally, `filter` will use the mask to blend between unfiltered and filtered. | | sound-in | String | The name of the sound to play when this style is applied to an element. This is useful to put on a `:hover` or `:active` style to play a sound on hover/click | | sound-out | String | The name of a sound to play when this style is removed from an element. | | text-stroke | Length, Color | This will put an outline | | text-stroke-color | Color | | | text-stroke-width | Length | | ``` -------------------------------- ### Implementing a Dockable Widget Source: https://docs.facepunch.com/s/sbox-dev/doc/editor-widgets-WBAKDbpTd3 Demonstrates how to use the [Dock] attribute to make a widget dockable within the editor's interface and automatically add it to the View menu. ```csharp [Dock("Editor", "Example Editor Dock", "local_fire_department")] ``` -------------------------------- ### Configuring MovieRecorderOptions with ComponentCapturers Source: https://docs.facepunch.com/s/sbox-dev/doc/recording-api-cgdhAXIA6Z Examples of how to configure MovieRecorderOptions to include custom component capturers and capture actions. ```APIDOC ## Configuring MovieRecorderOptions ### Description These examples show how to integrate custom `ComponentCapturer` instances into `MovieRecorderOptions`. You can manually add capturers or use helper methods like `WithCaptureAll` for convenience. ### Method N/A (Configuration examples) ### Endpoint N/A ### Parameters N/A ### Request Example **Example 1: Manually adding a capturer and a capture action** ```csharp var options = new MovieRecorderOptions() .WithComponentCapturer( new ModelRendererCapturer() ) .WithCaptureAction( recorder => { foreach ( var renderer in recorder.Scene.GetAllComponents() ) { // This will look for matching ComponentCapturers recorder.GetTrackRecorder( renderer )?.Capture(); } } ); ``` **Example 2: Using `WithCaptureAll` for convenience** ```csharp var options = new MovieRecorderOptions() .WithComponentCapturer( new ModelRendererCapturer() ) .WithCaptureAll(); ``` ### Response N/A ``` -------------------------------- ### Material Initialization and Processing (C++) Source: https://docs.facepunch.com/s/sbox-dev/doc/material-gVbbmBfLmp Provides helper functions for the Material API. `Material::From()` processes standard input to expose textures to the Material Editor, while `Material::Init()` is used to initialize an empty material for a Shading Model. ```cpp // Material::From( PixelInput i ) can be used to process the [standard input](/doc/default-vertex-and-pixel-shader-inputs-WAuOKVmkZ5) and expose textures to be used directly to the Material Editor ( MET ) // To initialize an empty material you can use Material::Init() and fill up the needed fields for the [Shading Model](/doc/shading-model-E6j9LshRnx) ``` -------------------------------- ### Custom Jump Link Implementation Source: https://docs.facepunch.com/s/sbox-dev/doc/navmesh-links-TmcuKrix7l Example of a custom NavMeshLink component that overrides OnLinkEntered to implement a parabolic jump for the agent. ```APIDOC ## POST /api/users ### Description This endpoint allows for the creation of new users in the system. It requires user details in the request body. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **username** (string) - Required - The desired username for the new user. - **email** (string) - Required - The email address of the new user. - **password** (string) - Required - The password for the new user. ### Request Example ```json { "username": "johndoe", "email": "john.doe@example.com", "password": "securepassword123" } ``` ### Response #### Success Response (201 Created) - **id** (string) - The unique identifier for the newly created user. - **username** (string) - The username of the created user. - **email** (string) - The email address of the created user. #### Response Example ```json { "id": "user-12345", "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Standard Shading Model Implementation Source: https://docs.facepunch.com/s/sbox-dev/doc/shading-model-E6j9LshRnx This snippet shows the standard Source 2 lighting process. It consumes a material and applies the ShadingModelStandard to produce the final lit output. ```csharp float4 MainPs(PixelInput i) : SV_Target0 { Material m = Material::From( i ); return ShadingModelStandard::Shade( m ); } ``` -------------------------------- ### Universal Wrapping Attribute Source: https://docs.facepunch.com/s/sbox-dev/doc/code-generation-zhqowLeADO An example of an attribute that can wrap properties (setters and getters) and methods, including static and instance members. ```APIDOC ## Wrapping Everything This attribute demonstrates mixing `CodeGeneratorFlags` to handle multiple use cases, including wrapping properties and methods, for both static and instance members. ### Attribute Definition ```csharp [CodeGenerator( CodeGeneratorFlags.WrapPropertySet | CodeGeneratorFlags.WrapPropertyGet | CodeGeneratorFlags.WrapMethod | CodeGeneratorFlags.Static | CodeGeneratorFlags.Instance, "MyStaticClass.OnWrapAnything" )] public class WrapAnything : Attribute {} ``` ### Example Usage ```csharp public class MyObject { [WrapAnything] public string MyString { get; set; } [WrapAnything] public static string MyStaticString { get; set; } [WrapAnything] public void MyMethod() { } [WrapAnything] public static void MyStaticMethod() { } } ``` ### Callback Methods in `MyStaticClass` **Note:** Because `CodeGeneratorFlags.Static` is specified, the callback methods must also be static. ```csharp public static class MyStaticClass { internal static void OnWrapAnything( WrappedPropertySet p ) { // Handle property set } internal static T OnWrapAnything( WrappedPropertyGet p ) { // Handle property get return p.Value; } internal static void OnWrapAnything( WrappedMethod m, params object[] args ) { // Handle instance method call m.Resume(); } internal static T OnWrapAnything( WrappedMethod p, params object[] args ) { // Handle instance generic method call p.Resume(); } } ``` ``` -------------------------------- ### Implement Custom Dynamic Reflections Source: https://docs.facepunch.com/s/sbox-dev/doc/dynamic-reflections-fpqeZ8jNCo Shows how to implement a custom dynamic reflections solution by providing a global dynamic reflection texture. This allows for custom reflection logic and integration with existing systems. ```csharp commands.SetGlobal( "ReflectionColorIndex", PlanarReflection.ColorIndex ); ``` -------------------------------- ### Creating a Razor Component Source: https://docs.facepunch.com/s/sbox-dev/doc/razor-components-UI4r9NrDOY Example of defining a basic Razor Component named InfoCard with Header, Body, and Footer render fragments. ```APIDOC ## Creating a Razor Component This section demonstrates how to define a reusable Razor Component. ### Component Definition ```csharp
@Header
@Body
@code { public RenderFragment Header { get; set; } public RenderFragment Body { get; set; } public RenderFragment Footer { get; set; } } ``` ### Usage Razor Components can be used by nesting them within other Razor files and providing content for their defined fragments. ``` -------------------------------- ### Configure Text Decoration Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Examples for applying multiple text decoration lines. This allows for combining styles like overline and underline simultaneously. ```css text-decoration-line: overline underline; ``` -------------------------------- ### Use WithCaptureAll for Convenience Source: https://docs.facepunch.com/s/sbox-dev/doc/recording-api-cgdhAXIA6Z Shows the simplified approach to registering a capturer and automatically capturing all instances of a specific component type using WithCaptureAll. ```csharp var options = new MovieRecorderOptions() .WithComponentCapturer( new ModelRendererCapturer() ) .WithCaptureAll(); ``` -------------------------------- ### Configure Font Styling Source: https://docs.facepunch.com/s/sbox-dev/doc/style-properties-WSPC2zsKHu Examples for setting font family and font weight properties. These properties allow for precise control over typography appearance. ```css font-family: Comic Sans MS; font-weight: bold; font-weight: 300; ``` -------------------------------- ### VR Input Handling in C# Source: https://docs.facepunch.com/s/sbox-dev/doc/vr-GPhXAmcHLM Demonstrates how to access and utilize VR controller input values, such as grip and trigger, and how to trigger haptic feedback on controllers. It also shows how to check if the game is currently running in a VR environment. ```csharp var grip = Input.VR.LeftHand.Grip.Value; if ( Input.VR.LeftHand.Trigger.Value > 0.5f ) { Log.Trace( "Shoot!" ); Input.VR.LeftHand.TriggerHapticVibration( duration: 0.5f, frequency: 10, amplitude: 1.0f ); } ``` ```csharp if ( Game.IsRunningInVR ) { Log.Info( "I am running the game in VR!" ); } ``` -------------------------------- ### Creating a Custom GameObjectSystem Source: https://docs.facepunch.com/s/sbox-dev/doc/gameobjectsystem-6vakGETtA4 This snippet demonstrates how to define a new system by deriving from GameObjectSystem and registering a method to be called during a specific stage. ```APIDOC ## Creating a Custom GameObjectSystem ### Description This example shows how to create a custom system by inheriting from `GameObjectSystem` and defining a method to be executed at a specific stage and order. ### Method Inheritance and Method Registration ### Endpoint N/A (Code Implementation) ### Parameters N/A ### Request Example ```csharp public class MyGameSystem : GameObjectSystem { public MyGameSystem( Scene scene ) : base( scene ) { // Register DoSomething to be called during the PhysicsStep stage with order 10 Listen( Stage.PhysicsStep, 10, DoSomething, "DoingSomething" ); } void DoSomething() { Log.Info( "Did something!" ); // Example of accessing components of a specific type var allThings = Scene.GetAllComponents(); // Perform operations on the retrieved components } } ``` ### Response N/A #### Success Response (200) N/A #### Response Example N/A ```