### UI Preview with Decorator in C# Source: https://docs.allout.game/guides/ui This C# example showcases the `UIPreview` decorator for live UI rendering in the editor. It allows structuring UI code as functions that can be called with example data, providing immediate visual feedback. This is ideal for iterating on UI designs without running the game. ```csharp [UIPreview] public static void DrawNextUp() { var timeInCurrentState = Time.TimeSinceStartup % 6; DrawNextUp("Red Light, Green Light", timeInCurrentState); } public static void DrawNextUp(string title, float time) { var nextUpTexture = Assets.GetAsset("ui/next_game_banner.png"); //... Rest of function } ``` -------------------------------- ### Draw a Simple Alert Window (C#) Source: https://docs.allout.game/guides/changelog Provides an example of using `UI.DrawAlertWindow` to display a basic alert message with a title, description, and two buttons in AllOut Game's UI system. ```csharp void ShowMyAlert() { UI.DrawAlertWindow( title: "Important Update", message: "Protocol 39 has been released. Please review the changes.", confirmButtonText: "OK", cancelButtonText: "Later", onConfirm: () => { Log.Info("User confirmed the alert."); // Handle confirm action }, onCancel: () => { Log.Info("User cancelled the alert."); // Handle cancel action } ); } ``` -------------------------------- ### Quadtree Usage Example for Spatial Partitioning Source: https://docs.allout.game/guides/changelog Demonstrates how to use the new Quadtree class for efficient spatial partitioning and querying of game entities. It shows insertion, removal, and querying of destructible objects within a defined spatial area. This requires the Quadtree class and Destructible components to be implemented. ```csharp public class GameManager : Component { public Quadtree DestructibleQuadtree; public List QuadtreeQueryResultCache = new(); public override void Awake() { DestructibleQuadtree = new(maxDepth: 5, lo: new Vector2(-100, -100), hi: new Vector2(100, 100)); } public override void Update() { QuadtreeQueryResultCache.Clear(); Vector2 position = ...; float radius = ...; DestructibleQuadtree.Query(position, radius, QuadtreeQueryResultCache); // there is also a lo+hi variant foreach (var destructible in QuadtreeQueryResultCache) { /* ... */ } } } public class Destructible : Component { public QuadtreeEntry Insertion; public override void Awake() { Insertion = GameManager.Instance.DestructibleQuadtree.Insert(this, lo: Position, hi: Position); } public override void OnDestroy() { GameManager.Instance.DestructibleQuadtree.Remove(Insertion); } } ``` -------------------------------- ### Implement Navmesh Stitching (C#) Source: https://docs.allout.game/guides/navmeshes Demonstrates how to set up and use Navmesh stitching, where multiple child Navmeshes are combined into a parent Navmesh. This example shows adding a child Navmesh and triggering a parent rebuild. ```csharp // Example of adding a new child navmesh to a parent Navmesh parentNavmesh = ...; Navmesh childNavmesh = Entity.Create().AddComponent(); childNavmesh.Entity.SetParent(parentNavmesh.Entity); Navmesh_Loop childLoop = Entity.Create().AddComponent(); childLoop.Entity.SetParent(childNavmesh.Entity); childNavmesh.SetPoints(...); // SetPoints will set childNavmesh.MarkedForRebuild to true. parentNavmesh.RebuildImmediately(); // Could also do `parentNavmesh.MarkedForRebuild = true;` if // you are planning to do several modifications. ``` -------------------------------- ### Fetch Inventory Example (C#) Source: https://docs.allout.game/api/AO.Inventory Demonstrates how to asynchronously fetch inventory data using the Inventory.Fetch method. This method takes an inventory ID, a count, and a callback function to process the retrieved inventory. It's suitable for both client-side and server-side calls. ```csharp Inventory.Fetch($"{UserId}_my_inventory", 10, (Inventory inventory) => { // Do something with the inventory }); ``` -------------------------------- ### Teleporter Component Implementation in C# Source: https://docs.allout.game/guides/getting-started This C# script demonstrates how to create a 'Teleporter' component in the All Out game engine. It attaches a callback to an 'Interactable' component, allowing a player to teleport to a specified position upon interaction. Ensure the Interactable component is added to the same entity. ```csharp using AO; public class Teleporter : Component { public override void Awake() { var interactable = Entity.GetComponent(); interactable.OnInteract = (Player p) => { player.Teleport(new Vector2(10, 10)); }; } } ``` -------------------------------- ### Implementing a Modal UI with PUSH_MODAL in C# Source: https://docs.allout.game/guides/changelog Demonstrates the usage of `UI.PUSH_MODAL` for creating modal dialogs in the UI. This helper function draws a dimmed background and automatically handles closing the modal when the background is clicked or the Escape key is pressed. The example shows how to use it within a conditional block to manage the visibility of a menu. ```csharp if (CoolMenuIsOpen) { using var _ = UI.PUSH_MODAL(UI.ScreenRect, "cool_menu", out ModalResult modal); var windowRect = UI.SafeRect.CenterRect().Grow(200, 300, 200, 300); UI.Image(windowRect, windowBg); // if (modal.Close) { CoolMenuIsOpen = false; } } ``` -------------------------------- ### Get Animation Length with SpineSkeletonAsset (C#) Source: https://docs.allout.game/guides/changelog Demonstrates how to get the length of a specific animation from a `SpineSkeletonAsset` using the new `TryGetAnimationLength` method in AllOut Game. ```csharp SpineSkeletonAsset skeletonAsset = Assets.Load("my_spine_animation.asset"); float animationLength; if (skeletonAsset != null && skeletonAsset.TryGetAnimationLength("walk", out animationLength)) { Log.Info($"The 'walk' animation has a length of: {animationLength} seconds."); } else { Log.Warning("Could not retrieve the length for the 'walk' animation."); } ``` -------------------------------- ### Start GA Thread - C# Source: https://docs.allout.game/api/GameAnalyticsSDK.Net.Threading Initiates the background thread managed by GAThreading. This method should be called to begin processing tasks scheduled on the GAThread. Ensure this is called before scheduling any tasks. ```csharp public static void StartThread() ``` -------------------------------- ### Insecure ServerRpc for Damage Dealing (C#) Source: https://docs.allout.game/guides/networking Illustrates a 'Bad' example of a CombatPlayer dealing damage using a ServerRpc. This implementation is vulnerable because it allows clients to arbitrarily call the RPC with any parameters, potentially leading to exploits. ```csharp public class CombatPlayer : Player { public SyncVar Health = new(100); // Even though your code is fine, malicious clients can call this ServerRpc with any value for shotPlayer and damage at any time and wreak havoc. [ServerRpc] public void DealDamage(Player shotPlayer, int damage) { CombatPlayer shotCombatPlayer = (CombatPlayer)shotPlayer; shotCombatPlayer.Health.Set(shotCombatPlayer.Health - damage); } public override void Update() { if (IsLocal && playerIsShooting) { CallServer_DealDamage(shotPlayer, 5); } } } ``` -------------------------------- ### Configure Collider Interactions with Category and Mask Bits in C# Source: https://docs.allout.game/guides/colliders This example shows how to set the Category Bits and Mask Bits for a collider programmatically in C#. Category Bits define what the collider is, while Mask Bits determine what it interacts with. This allows for fine-grained control over physics interactions in the game engine. ```csharp EnemyCollider.CategoryBits = 0x00000004; // Collides with Environment and Enemy playerCollider.MaskBits = 0x00000001 | 0x00000004; ``` -------------------------------- ### Implement Shop - C# Source: https://docs.allout.game/guides/economy-shop Sets up a shop system, allowing for categories and products with defined prices and currencies. Requires the Economy, Network, and Awake() method. The purchase handler is set on the server. ```csharp public class MyShop : System { public Shop Shop; public override void Awake() { Shop = Economy.CreateShop("My Shop"); if (Network.IsServer) { Shop.SetPurchaseHandler(OnPurchase); } var category = Shop.AddCategory("category"); category.Icon = "icon.png"; category.AddProduct(new ShopCategory.ProductDescription(){ Id = "item1", Name = "Item", Price = 100, Icon = "image.png", Currency = MyCurrency }); } public bool OnPartsPurchase(Player player, GameProduct product) { // Grant the items and return true if successful } } ``` -------------------------------- ### JSONNode.ValueEnumerator Current Property Source: https://docs.allout.game/api/GameAnalyticsSDK.Net.Utilities.JSONNode Gets the current JSONNode in the enumeration. This property provides access to the element the enumerator is currently pointing to. ```csharp public JSONNode Current { get; } ``` -------------------------------- ### Draw Generic UI Demo in C# Source: https://docs.allout.game/guides/ui Demonstrates drawing a list of UI elements with selection functionality and conditional execution of demo functions. It utilizes UI.Button, UI.Image, and UI.ScrollView, with settings defined by UI.ButtonSettings and ListTextSettings. ```csharp public static UI.ButtonSettings ListButtonSettings = new UI.ButtonSettings() { Sprite = UI.WhiteSprite, BackgroundColorMultiplier = new Vector4(0.5f, 0.5f, 0.5f, 1), PressScaling = 0.25f, }; public static int CurrentSelection; public static void DrawUIDemo() { var listRect = UI.SafeRect.SubRect(0, 0.5f, 0, 0.5f).Grow(250, 300, 250, 0).Offset(10, -35); UI.Image(listRect, null, new Vector4(0, 0, 0, 0.75f)); Action demoFunction = null; var sv = UI.PushScrollView("list", listRect, new UI.ScrollViewSettings(){Vertical = true}); { bool Entry(ref Rect listRect, int selection, string text) { var rect = listRect.CutTop(45); var bs = ListButtonSettings; if (CurrentSelection == selection) { bs.BackgroundColorMultiplier = new Vector4(0.25f, 1, 0.25f, 1); } if (UI.Button(rect.Inset(5), text, bs, ListTextSettings).Clicked) { CurrentSelection = selection; } return CurrentSelection == selection; } if (Entry(ref sv.contentRect, 0, "None")) {} if (Entry(ref sv.contentRect, 1, "Serial Numbers 1")) { demoFunction = DemoSerialNumbers1; } if (Entry(ref sv.contentRect, 2, "Serial Numbers 2")) { demoFunction = DemoSerialNumbers2; } } UI.PopScrollView(); if (demoFunction != null) { demoFunction(); } } [UIPreview] public static void PreviewUI(Rect rect) { DrawUIDemo(); } public override void Update() { if (IsLocal) { DrawUIDemo(); } } ``` -------------------------------- ### Implement Layer Demo in C# Source: https://docs.allout.game/guides/ui Demonstrates the use of UI layers for drawing elements at different depth levels. It utilizes UI.PUSH_LAYER to control rendering order, drawing windows with random background colors at specified layers. ```csharp public static void DemoLayers() { var bgRect = UI.ScreenRect.CenterRect().Grow(150, 200, 150, 200); UI.Image(bgRect, null, new Vector4(1, 1, 1, 1)); void DrawWindow(Rect rect, ref ulong rng) { for (int i = 0; i < 3; i++) { UI.Image(rect, null, new Vector4(RNG.RangeFloat(ref rng, 0.5f, 1.0f), RNG.RangeFloat(ref rng, 0.5f, 1.0f), RNG.RangeFloat(ref rng, 0.5f, 1.0f), 1)); rect = rect.Inset(30); } } ulong rng = RNG.Seed(1337); var layer1 = (((int)Time.TimeSinceStartup) % 2 == 0) ? 100 : 200; var layer2 = 150; { using var _ = UI.PUSH_LAYER(layer1); DrawWindow(UI.ScreenRect.CenterRect().Grow(100).Offset(-75, 25), ref rng); } { using var _ = UI.PUSH_LAYER(layer2); DrawWindow(UI.ScreenRect.CenterRect().Grow(100).Offset( 75, -25), ref rng); } } ``` -------------------------------- ### Create Currency - C# Source: https://docs.allout.game/guides/economy-shop Defines and registers a new currency within the economy system. Requires the Economy and Awake() method for initialization. ```csharp public const string MyCurrency = "Moni"; public override void Awake() { Economy.RegisterCurrency(MyCurrency, "gold.png"); } ``` -------------------------------- ### Using TextAsset for .txt Files (C#) Source: https://docs.allout.game/guides/changelog Shows how to load and use `.txt` files as `TextAsset` objects in AllOut Game. These assets can be found in the `res/` directory of your project. ```csharp // Assuming you have a file named 'mydata.txt' in your 'res/' directory TextAsset myTextData = Assets.Load("mydata.txt"); if (myTextData != null) { string fileContent = myTextData.text; // Process the file content here Log.Info("File content loaded successfully."); } ``` -------------------------------- ### Run GA Thread - C# Source: https://docs.allout.game/api/GameAnalyticsSDK.Net.Threading Starts or resumes the execution of the GAThread. This method might be used to ensure the thread is active and processing tasks. Its specific behavior might depend on the current state of the thread. ```csharp public static void Run() ``` -------------------------------- ### Implement Z-Order Demo in C# Source: https://docs.allout.game/guides/ui Illustrates how to control the drawing order of UI elements using Z-values. It uses IM.PUSH_Z to ensure one image is drawn above another, demonstrating dynamic Z-order manipulation based on time. ```csharp public static void DemoZ() { var bgRect = UI.ScreenRect.CenterRect().Grow(150, 200, 150, 200); UI.Image(bgRect, null, new Vector4(1, 1, 1, 1)); { using var _ = UI.PUSH_LAYER(100); // just so that we are guaranteed to draw above the bgRect above. var rect1 = UI.ScreenRect.CenterRect().Grow(25).Offset(-15, 0); var rect2 = UI.ScreenRect.CenterRect().Grow(25).Offset(15, 0); UI.Image(rect1, null, new Vector4(1, 0, 0, 1)); { var y = MathF.Sin(Time.TimeSinceStartup * 1.5f) * 50; using var _1 = IM.PUSH_Z(y); UI.Image(rect2.Offset(0, y), null, new Vector4(0, 1, 0, 1)); } } } ``` -------------------------------- ### Board Meeting Effect Implementation - C# Source: https://docs.allout.game/guides/effects An example of a custom effect, BoardMeetingEffect, that implements game-specific logic. This effect handles player teleportation, UI instantiation and interaction, server calls for voting, and sound effects. ```csharp public partial class BoardMeetingEffect : MyEffect { public override bool IsActiveEffect => true; public override bool FreezePlayer => true; public Entity UI; public override float DefaultDuration => 17f; public bool HasPlayedEndSound; public override void OnEffectStart(bool isDropIn) { var playerSeat = Player.AssignedMeetingSeat; Player.Teleport(playerSeat.Value.Position); Player.SetFacingDirection(playerSeat.Value.GetComponent().FaceLeft ? false : true); if (Player.IsLocal) return; UI = Entity.Instantiate(Assets.GetAsset("BoardMeetingUI.prefab")); Notifications.Show("A board meeting to elect a new CEO has been called..."); var voteLeft = UI.TryGetChildByName("VoteLeft"); var voteRight = UI.TryGetChildByName("VoteRight"); var leftCandidate = PromoNPC.Instance.Candidate1.Value.GetComponent(); var rightCandidate = PromoNPC.Instance.Candidate2.Value.GetComponent(); if (voteLeft.Alive() && voteRight.Alive()) { var voteLeftButton = voteLeft.GetComponent(); var voteRightButton = voteRight.GetComponent(); var voteLeftText = voteLeft.GetComponent(); var voteRightText = voteRight.GetComponent(); voteLeftText.Text = leftCandidate.Name; voteRightText.Text = rightCandidate.Name; voteLeftButton.OnClicked = () => { PromoNPC.Instance.CallServer_CountVote(1); }; voteRightButton.OnClicked = () => { PromoNPC.Instance.CallServer_CountVote(2); }; } } public override void OnEffectEnd(bool interrupt) { Player.Teleport(new Vector2(0, 0)); Player.SetLightOn(false); if (Player.IsLocal) { UI.Destroy(); } } public override void OnEffectUpdate() { if (AO.Util.OneTime(DurationRemaining <= 4.25f, ref HasPlayedEndSound)) { SFX.Play(Assets.GetAsset("sfx/levelup.wav"), new SFX.PlaySoundDesc() {Volume=1f}); } } } ``` -------------------------------- ### Server-Side Rewarded Ad Handling (C#) Source: https://docs.allout.game/guides/ads Sets up a server-side ad system to handle rewarded ad callbacks. It requires a custom Player class and listens for ad reward events, returning true if the reward is successfully processed. ```csharp public class AdSystem : System { public override void Awake() { if (Network.IsServer) { Ads.SetRewardHandler(OnAdReward); } } private bool OnAdReward(Player _player, string adId) { var player = (MyPlayer)_player; if (adId == "ANY_STRING") { return true; } return false; } } ``` -------------------------------- ### Add Custom Fields with SyncVar - C# Source: https://docs.allout.game/guides/player This C# example shows how to define a custom player class `WorkerPlayer` that extends `Player` and includes custom fields using `SyncVar`. `SyncVar` is used for synchronizing variables across the game network. ```csharp public partial class WorkerPlayer : Player { public SyncVar Role = new("Janitor"); public SyncVar Salary = new(0); public SyncVar Money = new(0); public SyncVar Experience = new(0); } ``` -------------------------------- ### Client-Side Rewarded Ad Prompting (C#) Source: https://docs.allout.game/guides/ads Prompts a rewarded ad on the client side, which will open a dialog for the user. Requires an ad ID, reward details, and an icon asset. ```csharp Ads.PromptRewardedAd("ANY_STRING", "75XP", "Watch to get 75XP", Assets.GetAsset("$AO/new/icons/Video.png")); ``` -------------------------------- ### Implement Auto-Scaling Demo in C# Source: https://docs.allout.game/guides/ui Demonstrates UI auto-scaling behavior by drawing images with and without explicit scale factor manipulation. It uses UI.PUSH_SCALE_FACTOR to control the scaling of UI elements, comparing scaled and unscaled rendering. ```csharp public static void DemoAutoscaling() { var bgRect = UI.ScreenRect.CenterRect().Grow(150, 200, 150, 200); UI.Image(bgRect, null, Vector4.White); // no scaling { using var _ = UI.PUSH_SCALE_FACTOR(1); UI.Image(bgRect.SubRect(0.5f, 1, 0.5f, 1).Grow(0, 200, 75, 200), null, new Vector4(1, 0, 0, 1)); } // with scaling { UI.Image(bgRect.SubRect(0.5f, 0, 0.5f, 0).Grow(0, 200, 75, 200), null, new Vector4(0, 1, 0, 1)); } } ``` -------------------------------- ### Implement Serial Numbers Demo in C# Source: https://docs.allout.game/guides/ui Displays a demo of text rendering with auto-scaling background highlighting. It uses UI.Image and UI.Text to draw a background rectangle and text, dynamically adjusting the text displayed and its highlight box based on time. ```csharp public static void DemoSerialNumbers() { var bgRect = UI.ScreenRect.CenterRect().Grow(100, 150, 100, 150); UI.Image(bgRect, null, new Vector4(1, 1, 1, 1)); var bgSerial = IM.GetNextSerial(); var ts = ListTextSettings; ts.WordWrap = true; var str = "This is a long message with an auto-sizing background."; var actualTextRect = UI.Text(bgRect, str.Substring(0, ((int)(Time.TimeSinceStartup * 10)) % (str.Length+1)), ts); IM.SetNextSerial(bgSerial); UI.Image(actualTextRect, null, new Vector4(0, 1, 0, 1)); } ``` -------------------------------- ### Manage User Wallets - C# Source: https://docs.allout.game/guides/economy-shop Provides functions to grant and remove currency from player wallets. Uses Economy.DepositCurrency and Economy.WithdrawCurrency. Includes a check for sufficient funds before withdrawal. ```csharp public void Grant(Player p) { Economy.DepositCurrency(p, MyCurrency, 100); } public void Remove(Player p) { if (!Economy.WithdrawCurrency(p, MyCurrency, 100)) { Log.Info("Player did not have enough currency"); } } ``` -------------------------------- ### Initialize and Control Camera Position (C#) Source: https://docs.allout.game/guides/camera-control This C# code demonstrates how to initialize a CameraControl instance for the local player and update its position in the game world. It assumes the existence of a Camera class with a CreateCameraControl method and an Entity with a Position property. ```csharp public partial class MyPlayer : Player { public CameraControl CameraControl; public override void Awake() { if (IsLocal) { CameraControl = Camera.CreateCameraControl(1); } } public override void Update() { if (IsLocal) { CameraControl.Position = Entity.Position + new Vector2(0, 0.5f); } } } ``` -------------------------------- ### Implement RectCuts Demo in C# Source: https://docs.allout.game/guides/ui Provides a placeholder for demonstrating rectangle manipulation functions, specifically 'cuts'. The current implementation only draws a background rectangle, indicating where further rectangle operations would be applied. ```csharp public static void DemoRectCuts() { var bgRect = UI.ScreenRect.CenterRect().Grow(200, 200, 200, 200); UI.Image(bgRect, null, Vector4.White); } ``` -------------------------------- ### QuadData Constructors Source: https://docs.allout.game/api/AO.IM This section details the different constructors available for the QuadData structure, allowing for various initializations. ```APIDOC ## QuadData() ### Description Default constructor for QuadData. ### Method Constructor ### Parameters None ### Request Example ```json { "example": "new QuadData()" } ``` ### Response Example ```json { "example": "QuadData object initialized with default values." } ``` ## QuadData(Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector4, Texture) ### Description Constructor for QuadData with all vertex and UV coordinates, color, and texture. ### Method Constructor ### Parameters #### Path Parameters - **p1** (Vector2) - Description - **p2** (Vector2) - Description - **p3** (Vector2) - Description - **p4** (Vector2) - Description - **uv1** (Vector2) - Description - **uv2** (Vector2) - Description - **uv3** (Vector2) - Description - **uv4** (Vector2) - Description - **c** (Vector4) - Description - **sprite** (Texture) - Description ### Request Example ```json { "example": "new QuadData(p1, p2, p3, p4, uv1, uv2, uv3, uv4, c, sprite)" } ``` ### Response Example ```json { "example": "QuadData object initialized with provided values." } ``` ## QuadData(Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector4, Texture) ### Description Constructor for QuadData with specific vertex and UV coordinates, color, and texture. ### Method Constructor ### Parameters #### Path Parameters - **p1** (Vector2) - Description - **p2** (Vector2) - Description - **p3** (Vector2) - Description - **p4** (Vector2) - Description - **uv1** (Vector2) - Description - **uv2** (Vector2) - Description - **c** (Vector4) - Description - **sprite** (Texture) - Description ### Request Example ```json { "example": "new QuadData(p1, p2, p3, p4, uv1, uv2, c, sprite)" } ``` ### Response Example ```json { "example": "QuadData object initialized with provided values." } ``` ## QuadData(Vector2, Vector2, Vector4, Texture) ### Description Constructor for QuadData using min/max vectors, color, and texture. ### Method Constructor ### Parameters #### Path Parameters - **min** (Vector2) - Description - **max** (Vector2) - Description - **color** (Vector4) - Description - **sprite** (Texture) - Description ### Request Example ```json { "example": "new QuadData(min, max, color, sprite)" } ``` ### Response Example ```json { "example": "QuadData object initialized with min/max, color, and texture." } ``` ## QuadData(Vector2, Vector2, float, Vector4, Texture) ### Description Constructor for QuadData with min/max vectors, rotation, color, and texture. ### Method Constructor ### Parameters #### Path Parameters - **min** (Vector2) - Description - **max** (Vector2) - Description - **rotationRadians** (float) - Description - **color** (Vector4) - Description - **sprite** (Texture) - Description ### Request Example ```json { "example": "new QuadData(min, max, rotationRadians, color, sprite)" } ``` ### Response Example ```json { "example": "QuadData object initialized with min/max, rotation, color, and texture." } ``` ``` -------------------------------- ### ProductDescription Fields: Currency and Description Source: https://docs.allout.game/api/AO.ShopCategory These C# code snippets define the 'Currency' and 'Description' fields within the ShopCategory.ProductDescription struct. 'Currency' is a string representing the product's currency type, and 'Description' is a string providing a textual description of the product. ```csharp public string Currency__ // Field Value: string ``` ```csharp public string Description__ // Field Value: string ``` -------------------------------- ### Implement Server RPC for LockedDoor in C# Source: https://docs.allout.game/guides/rpcs Demonstrates how to create a Server RPC in C# for a LockedDoor component. This allows clients to submit a passcode to the server. The component requires the `partial` keyword and utilizes `SyncVar` for state synchronization. The server-side logic is executed within the `SubmitPasscode` function. ```csharp public partial class LockedDoor : Component { public string Passcode = null; public SyncVar Unlocked = new(false); // Only generate the passcode in the server's Awake. It will remain null on the client. public override void Awake() { if (Network.IsServer) { Passcode = "secure"; } } // In the real game there would be some UI that allows typing a passcode. When you hit "enter" it's submitted to this function [ServerRpc] public void SubmitPasscode(string submittedPasscode) { if (submittedPasscode == Passcode) { Unlocked.Set(true); } } public void ClientSubmitPasscode() { var passcode = "passcode from a UI component etc..."; CallServer_SubmitPasscode(passcode); } } ``` -------------------------------- ### SFX.PlaySoundDesc Constructor Source: https://docs.allout.game/api/AO.SFX Initializes a new instance of the SFX.PlaySoundDesc struct. This default constructor sets up a basic sound description, likely with default values for its fields. ```csharp public PlaySoundDesc()__ ``` -------------------------------- ### Create a New Item Definition (C#) Source: https://docs.allout.game/guides/items-and-inventory This C# code snippet shows how to define a new item in the game. It utilizes the `Item_Definition.Create` method with an `ItemDescription` object to specify properties such as ID, icon, name, and stack size. A stack size of -1 indicates infinite stacking. ```csharp public Item_Definition Item; public override void Awake() { Item = Item_Definition.Create(new ItemDescription() { Id = "fish", Icon = "my_asset.png", Name = "Fish", StackSize = -1, // Infinite }); } ``` -------------------------------- ### Player Nametag Overlay with TextSettings in C# Source: https://docs.allout.game/guides/ui This C# code provides a reusable `GetTextSettings` function for configuring UI text appearance, including font, size, color, and alignment. The `LateUpdate` method then uses these settings to render a player's nametag overlay in world space, ensuring it updates after player movement. ```csharp // Useful text settings wrapper you can pull in wherever you need it: public UI.TextSettings GetTextSettings(float size, float offset = 1.90f, FontAsset font = null, UI.HorizontalAlignment halign = UI.HorizontalAlignment.Center) { if (font == null) { font = UI.Fonts.BarlowBold; } var ts = new UI.TextSettings() { Font = font, Size = size, Color = Vector4.White, DropShadowColor = new Vector4(0f,0f,0.02f,0.5f), DropShadowOffset = new Vector2(0f,-3f), HorizontalAlignment = halign, VerticalAlignment = UI.VerticalAlignment.Center, WordWrap = false, WordWrapOffset = 0, Outline = true, OutlineThickness = 3, Offset = new Vector2(0, offset), }; return ts; } // Should be in late update so it takes into account player movement this frame. public override void LateUpdate() { using var _1 = UI.PUSH_CONTEXT(UI.Context.WORLD); // Use the player's Z Offset using var _2 = IM.PUSH_Z(GetZOffset() - 0.001f); using var _3 = UI.PUSH_PLAYER_MATERIAL(this); var rect = new Rect(Entity.Position, Entity.Position).Grow(0.125f); var ts = GetTextSettings(0.225f); UI.Text(rect, "CEO", ts); } ``` -------------------------------- ### Rectangle Manipulation and Text Cutting (C#) Source: https://docs.allout.game/guides/ui Demonstrates advanced rectangle manipulation techniques like CutTop and CutTopUnscaled for precise text placement. It highlights the difference between scaled and unscaled cutting, crucial for accurate UI layouts, especially when dealing with text height. ```csharp var rect = bgRect.TopRect().Offset(0, -15); // hardcoded cut { UI.Text(rect.CutTop(25), "Text 1", ListTextSettings); UI.Text(rect.CutTop(25), "Text 1", ListTextSettings); UI.Text(rect.CutTop(25), "Text 1", ListTextSettings); } rect.CutTop(50); // cut based on text height, but its wrong! { void DrawText(ref Rect rect) { var actualTextRect = UI.Text(rect, "Text 2", ListTextSettings); rect.CutTop(actualTextRect.Height); // wrong! use CutTopUnscaled! } DrawText(ref rect); DrawText(ref rect); DrawText(ref rect); } rect.CutTop(50); // cut based on EXACT VALUE of text height, not scaled { void DrawText(ref Rect rect) { var actualTextRect = UI.Text(rect, "Text 3", ListTextSettings); rect.CutTopUnscaled(actualTextRect.Height); // good :) } DrawText(ref rect); DrawText(ref rect); DrawText(ref rect); } ``` -------------------------------- ### Define ShopCategory.ProductDescription Struct Source: https://docs.allout.game/api/AO.ShopCategory This C# code defines the public struct ShopCategory.ProductDescription. It is part of the AO namespace and is located in CoreAssembly.dll. This struct is used to hold various details about a product within the game's shop. ```csharp public struct ShopCategory.ProductDescription { // Fields are detailed below } ``` -------------------------------- ### Grid Layout with Interactive Buttons (C#) Source: https://docs.allout.game/guides/ui Generates a grid layout within a specified background rectangle and populates it with interactive buttons. Each button has a random color multiplier and logs a message when clicked, demonstrating dynamic UI element creation and event handling. ```csharp public static void DemoGrids() { var bgRect = UI.ScreenRect.CenterRect().Grow(200, 200, 200, 200); UI.Image(bgRect, null, Vector4.White); var grid = UI.GridLayout.Make(bgRect, 4, 4, UI.GridLayout.SizeSource.ElementCount, padding: 4); ulong rng = RNG.Seed(1337); for (int i = 0; i < 16; i++) { var rect = grid.Next(); using var _ = UI.PUSH_ID(i); var bs = new UI.ButtonSettings(); bs.Sprite = UI.WhiteSprite; bs.ColorMultiplier = new Vector4(RNG.RangeFloat(ref rng, 0.25f, 1.0f), RNG.RangeFloat(ref rng, 0.25f, 1.0f), RNG.RangeFloat(ref rng, 0.25f, 1.0f), 1); if (UI.Button(rect, "", bs, default).Clicked) { Log.Info("Clicked " + i); } } } ``` -------------------------------- ### Configure ao.project for Multiple Game IDs Source: https://docs.allout.game/guides/publishing This JSON configuration allows you to specify multiple game IDs within your `ao.project` file. This is useful for managing different versions of your game, such as a public version and a staging version, enabling a dropdown selection in the editor for publishing. ```json { "project_id": "6696a895ca27f9b1833bdc70", "projects": [ { "name": "Murder Mystery", "id": "660dbd382928ad7252a47ec9" }, { "name": "Murder Mystery (staging)", "id": "6696a895ca27f9b1833bdc70" } ] } ``` -------------------------------- ### VignetteConfig Constructor Source: https://docs.allout.game/api/AO.PostProcessing Initializes a new instance of the VignetteConfig struct. This is a parameterless constructor. ```csharp public VignetteConfig() ``` -------------------------------- ### Register and Handle Chat Commands in C# Source: https://docs.allout.game/guides/social This C# code demonstrates how to register a chat command handler and process incoming chat messages. It allows for parsing commands and their arguments to execute various in-game actions, such as changing game state, camera zoom, or player speed. It includes logic to restrict commands based on player ID or editor launch status. ```csharp public override void Awake() { Chat.RegisterChatCommandHandler(RunChatCommand); } public void RunChatCommand(Player p, string command) { var parts = command.Split(' '); var cmd = parts[0].ToLowerInvariant(); MyPlayer player = (MyPlayer)p; var allowCommands = Game.LaunchedFromEditor; if (player.UserId == "your_user_id") allowCommands = true; if (!allowCommands) { return; } switch (cmd) { case "help": { Chat.SendMessage(p,"\nChat Commands:\n"+ "/z[oom] : Set camera zoom\n"+ "/s[tart] : start round immediately\n"+ "/sp[eed] \n"+ break; } case "s": case "start": { State = GameState.CountingDown; Countdown.Set(0); break; } case "z": case "zoom": { if (parts.Length != 2) { Chat.SendMessage(player, "/zoom needs a zoom value as a parameter."); break; } if (float.TryParse(parts[1], out var z)) { player.CurrentZoomLevel.Set(z); } break; } case "sp": case "speed": { if (parts.Length != 2) { Chat.SendMessage(player, "/speed needs a speed value as a parameter."); break; } if (float.TryParse(parts[1], out var s)) { player.CheatSpeedMultiplier.Set(s); } break; } } } ``` -------------------------------- ### Implement Gym Pass Interactable with C# Source: https://docs.allout.game/guides/interactables This C# script defines a Gym Pass interactable entity. It customizes the interactable's behavior to check player cash and grant a gym pass upon successful purchase. The script utilizes `AO.Component` and `AO.Interactable` for game logic and interaction handling. Requires the entity to be a networked entity. ```csharp using AO; public class GymPass : Component { public int Cost = 100; private Interactable interactable; public override void Awake() { interactable = Entity.GetComponent(); interactable.CanUseCallback += (Player p) => { var op = (OfficePlayer)p; return !op.HasGymPass; }; interactable.OnInteract = (Player p) => { if (!Network.IsServer) return; var op = (OfficePlayer)p; if (op.Cash < Cost) { op.CallClient_ShowNotification("You don't have enough money to buy a gym pass!"); return; } op.Cash.Set(op.Cash - Cost); op.HasGymPass.Set(true); op.CallClient_PlaySFX("sfx/money.wav"); op.CallClient_ShowNotification("You now have access to the gym..."); }; } public override void Update() { if (Network.IsServer) return; interactable.Text = $"Buy a gym pass for ${Cost}"; } } ``` -------------------------------- ### Spawn Single Projectile per Frame (C#) Source: https://docs.allout.game/guides/projectiles Demonstrates spawning a single projectile each frame when the left mouse button is pressed. Requires a projectile prefab with specific components and identical projectile IDs on client and server. ```csharp public class MyPlayer : Player { public override void Update() { if (IsInputDown(Input.UnifiedInput.MOUSE_LEFT)) { Game.SpawnProjectile("MyProjectile.prefab", $"{UserId}_projectile1", Entity.Position, Vector2.Right); } } } ``` -------------------------------- ### ProductDescription Fields: Name and Price Source: https://docs.allout.game/api/AO.ShopCategory These C# code snippets define the 'Name' and 'Price' fields within the ShopCategory.ProductDescription struct. 'Name' is a string representing the product's name, and 'Price' is a long integer indicating the product's price. ```csharp public string Name__ // Field Value: string ``` ```csharp public long Price__ // Field Value: long ``` -------------------------------- ### Inventory.DrawOptions Constructor (C#) Source: https://docs.allout.game/api/AO.Inventory Initializes a new instance of the Inventory.DrawOptions struct. This constructor provides default settings for drawing options. ```csharp public DrawOptions() ``` -------------------------------- ### NPC Pathfinding Movement with Navmesh Source: https://docs.allout.game/guides/movement-agent Enables NPC movement towards a target position using navmesh pathfinding. It calculates the path, determines the next point, and sets the velocity towards that point, ignoring direct player input. This is crucial for AI-driven navigation. ```csharp agent.CustomVelocityCallback = (agent, currentVelocity, input, dt) => { Vector2 target = GetTargetPosition(); Vector2[] pathPoints = null; // It would be best practice to store this as a class variable // and reuse it to prevent generating garbage every frame. if (navmesh.TryFindPath(agent.Entity.Position, target, ref pathPoints, out int pathLength)) { Vector2 nextPoint = pathPoints[1]; Vector2 direction = (nextPoint - agent.Entity.Position).Normalized; return direction * 200 * dt; } return Vector2.Zero; }; ``` -------------------------------- ### Git Ignore File for All Out Game Projects Source: https://docs.allout.game/guides/git-integration A sample .gitignore file to exclude build artifacts, generated files, temporary files, and editor-specific configurations from version control. This helps keep the repository clean and avoids unnecessary conflicts. ```gitignore bin generated obj Assembly.csproj build scene_backups scene_temp .idea .vs *.ao *.ao.ios res/.preprocessed ``` -------------------------------- ### QuadData Constructors (C#) Source: https://docs.allout.game/api/AO.IM Provides various constructors for initializing the QuadData structure. These constructors allow for flexible creation of quad data by specifying vertex positions, UV coordinates, color, rotation, and texture. The constructors handle different combinations of parameters to suit various use cases in graphics rendering. ```csharp public QuadData()__ ``` ```csharp public QuadData(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 uv1, Vector2 uv2, Vector2 uv3, Vector2 uv4, Vector4 c, Texture sprite)__ ``` ```csharp public QuadData(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 uv1, Vector2 uv2, Vector4 c, Texture sprite)__ ``` ```csharp public QuadData(Vector2 min, Vector2 max, Vector2 uvMin, Vector2 uvMax, Vector4 color, Texture sprite)__ ``` ```csharp public QuadData(Vector2 min, Vector2 max, Vector4 color, Texture sprite)__ ``` ```csharp public QuadData(Vector2 min, Vector2 max, float rotationRadians, Vector4 color, Texture sprite)__ ``` -------------------------------- ### Initialize UI.TextInputSettings Struct Source: https://docs.allout.game/api/AO.UI Default constructor for the UI.TextInputSettings struct. This constructor initializes a new instance of the struct with default values. ```csharp public TextInputSettings() ``` -------------------------------- ### Implement Network Serialization for SpeedBoostEffect (C#) Source: https://docs.allout.game/guides/inetworkedcomponent Shows how to implement NetworkSerialize and NetworkDeserialize for a custom effect, SpeedBoostEffect, which inherits from AEffect. The BoostAmount is serialized and deserialized to ensure consistency across clients, especially when players join mid-game. ```csharp public class SpeedBoostEffect : AEffect // Note that you don't have to add INetworkedComponent. AEffect already does this. { public float BoostAmount; public override void NetworkSerialize(AO.StreamWriter writer) { writer.Write(BoostAmount); } public override void NetworkDeserialize(AO.StreamReader reader) { BoostAmount = reader.Read(); } } ``` -------------------------------- ### ProductDescription Fields: Icon and Id Source: https://docs.allout.game/api/AO.ShopCategory These C# code snippets define the 'Icon' and 'Id' fields within the ShopCategory.ProductDescription struct. 'Icon' is a string representing the product's icon identifier, and 'Id' is a string uniquely identifying the product. ```csharp public string Icon__ // Field Value: string ``` ```csharp public string Id__ // Field Value: string ``` -------------------------------- ### Perform a Box Cast with Whitelist (C#) Source: https://docs.allout.game/guides/changelog Demonstrates the usage of `Physics.BoxCastWithWhitelist` for performing a physics cast in a box shape, only considering entities within a specified whitelist in AllOut Game. ```csharp Vector3 origin = new Vector3(0, 0, 0); Vector3 halfExtents = new Vector3(1, 1, 1); Rotation rotation = Rotation.Identity; Vector3 direction = new Vector3(0, 0, 1); float maxDistance = 10f; List whitelist = new List() { /* Add entities to whitelist here */ }; List hits = Physics.BoxCastWithWhitelist(origin, halfExtents, rotation, direction, maxDistance, whitelist); foreach (var hit in hits) { Log.Info($"Box cast hit entity: {hit.entity.Name}"); } ``` -------------------------------- ### SyncVar Usage for State Synchronization (C#) Source: https://docs.allout.game/guides/networking Demonstrates the 'Bad' implementation of a LockedDoor component using a SyncVar for synchronization. This approach is vulnerable as it exposes sensitive information directly on the client. ```csharp public class LockedDoor : Component { // Declaring the password like this will allow cheaters to access it from the game's memory public string Passcode = "hunter2"; public SyncVar Unlocked = new(false); // In the real game there would be some UI that allows typing a passcode. When you hit "enter" it's submitted to this function public void OnClientPasscodeSubmit(string submittedPasscode) { if (Network.IsServer && submittedPasscode == Passcode) { Unlocked.Set(true); } } } ``` -------------------------------- ### Enable Automatic Game Analytics Instrumentation (C#) Source: https://docs.allout.game/guides/analytics This snippet shows how to enable automatic analytics for your game using the GameAnalytics SDK within the All Out framework. It requires a game key and secret key obtained from the GameAnalytics website. The instrumentation is enabled only on the client side to avoid server overhead. ```csharp public class GameManagerSystem : System { public override void Awake() { if (!Network.IsServer) { Analytics.EnableAutomaticAnalytics("your game key", "your secret key"); } } } ```