> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/changelog/readme.md).

# Changelog

{% updates format="full" %}
{% update date="2026-07-15" %}

## Protocol 45 - July 15th, 2026 (Currently Nightly)

Protocol 45 adds UIDoc and scene-owned paint canvases, expands CSL gameplay and rendering APIs, improves live development tooling, and delivers substantial multiplayer, pathfinding, collision, scripting, and runtime improvements.

<details>

<summary>Compatibility and Migration</summary>

* Client version
  * The client version is now 1.45.1
  * Android version code is now 492
* Protocol and game data
  * Protocol 45 clients and servers cannot communicate with protocol 44 builds
  * Deploy matching client and server builds together
  * The game-state memory version increased from 58 to 75
  * Rebuild and republish games and packed scene data after upgrading
* Replicated C# components
  * Replicated component IDs now support values above 255
  * The limit remains 255 serialized components per entity
  * Entity payloads over 65,535 bytes now fail explicitly instead of being truncated
* CSL template strings
  * Backtick strings now support `{expression}` interpolation
  * Literal braces in existing raw backtick strings must be written as `{{` and `}}`
  * A lone closing brace is now a compile error
  * Interpolated templates require `import "core:basic"` and are not compile-time constants
  * Backtick strings without interpolation remain raw constants
* Numeric literals
  * Literals larger than 64 bits now fail compilation
  * Values outside an explicit integer suffix or enum range now fail instead of silently wrapping or truncating
  * Fractional literals can no longer use an integer suffix
* Source builds
  * Native Windows, Linux, and iOS builds now require Rust/Cargo for UIDoc layout support
  * iOS builds also require the `aarch64-apple-ios` Rust target

</details>

<details>

<summary>UIDoc Screen-Space UI</summary>

* Added `.uidoc` directory assets for authoring responsive screen-space UI
  * Each asset contains an `index.html` and can include an `index.css`
  * Supported content includes text, images, buttons, text inputs, conditions, and repeated lists
  * CSL can bind text, bools, floats, image paths, lists, inputs, and events
* Layout and styling
  * Supports responsive flex and block layouts, safe areas, interaction states, and client-specific viewport sizing
  * Supports vertical and horizontal scrolling, nested scroll-state restoration, and bound `data-scroll-zoom`
  * Tailwind-style utilities, responsive and pseudo-state variants, arbitrary values, and `@apply` can be lowered during asset baking when enabled by the stylesheet
  * Layout accounts for each client's viewport, locale, safe area, and replicated UI scale
* New CSL surface
  * Added `UIDoc_Asset`, `UIDoc_Event`, `UI.uidoc`, binding and list helpers, event polling, and text-input value access
* UIDoc uses a deliberately constrained HTML/CSS subset
  * It is deterministic engine UI, not an embedded browser
  * JavaScript, browser APIs, forms, external URLs, CSS grid, variables, transitions, and keyframes are not supported
  * Unsupported output fails asset validation instead of silently degrading
* Existing immediate-mode UI and UIK projects remain supported
  * Guidance for new screen-space UI now favors UIDoc

</details>

<details>

<summary>Visual UIDoc Editor</summary>

* Selecting a UIDoc replaces the entity-centric scene, hierarchy, and inspector with UIDoc authoring tools
* The scene view uses the production UIDoc parser, layout, and renderer for an exact runtime-backed preview
* Elements can be selected, moved, resized, inserted, duplicated, deleted, reordered, and reparented
* Design and Styles inspectors edit common HTML and CSS properties, including colors
* The Interface inspector infers fields, inputs, lists, and actions directly from UIDoc markup
* Saving generates a typed CSL wrapper under `scripts/generated/uidoc`
* UIDoc edits have document-aware save, undo/redo, external-change detection, and compiler diagnostics

</details>

<details>

<summary>New CSL Gameplay and Rendering APIs</summary>

* Scene-owned dynamic canvases
  * `Dynamic_Canvas` can create, destroy, fill, stamp, set, and sample pixel canvases
  * `Sprite_Renderer` can display a canvas
  * Spine attachments can override their texture with a canvas and optionally use skeleton-space UVs
  * Animated Spine hit positions can be converted back to stable canvas coordinates
  * Canvas state participates in sync, prediction, rollback, and reconciliation
  * Current limits are 512×512 pixels, 16 canvases per scene, and 4 MiB of canvas pixels per scene
* Scene color sampling
  * `Player.request_scene_color_sample` and `Player.try_get_scene_color_sample` support eyedropper-style mechanics
  * Sample results are client-authored visual input and must not be trusted as authoritative game state
* Dynamic canvas methods are currently available from CSL
  * C# receives the generated `Dynamic_Canvas` handle but not the full canvas API
* Interactables
  * Added subtitle getters, setters, and editable subtitle color
* Emotes and effects
  * Added equipped-emote checks, counted block reasons, trigger and cancellation APIs
  * Added `Effect_Base.get_duration_remaining`
* Inventory
  * Added `Inventory.has_item_id`
  * Added `Inventory_Draw_Options.on_before_draw` and `on_after_draw`
* Rendering and interpolation
  * Added `get_fixed_delta_time`, `Camera.size_last_frame`, `world_to_screen_interpolation_offset`, and `UI.quad_interpolated`
  * Added `UI.player_avatar` for drawing a static player avatar
  * Added interpolated aiming helpers and an Entity overload for tutorial arrows
* Spine and player materials
  * Added helpers for using a player's material and destroying an entity after its current animation
  * Added canvas painting options and skeleton-space attachment overrides
  * Added `color_replace_get_color` for reading avatar palette colors
* Sound documentation now covers `SFX.fade_out_and_stop` and controlling returned sound IDs from server-side CSL

</details>

<details>

<summary>Player and Runtime Changes</summary>

* CSL games now support the standard emote wheel
  * Equipped thumbnails, synchronized effects and sounds, looping, gameplay block reasons, and movement cancellation are supported
  * Fixed several emote state and headless-server crashes
* Interaction prompts can display a localized, independently colored subtitle
* Instant interactables with no hold duration now trigger correctly from a mobile tap
* Aiming indicators, target reticles, tutorial arrows, and dropped-item UI now interpolate more smoothly
* Multiplayer
  * Ongoing state and drop-in traffic is substantially smaller
  * Recovery from missing updates and long hitches is more reliable
  * Prediction now continues catching up instead of accumulating a permanent resimulation backlog
  * Web clients use the correct simulation budget on high-refresh-rate displays
  * Rollback no longer repeats UI side effects such as click sounds
* Scroll views
  * New views remain at the start until deliberately scrolled
  * Horizontal-only views accept horizontal wheel input
  * Transient zero-sized layouts no longer corrupt scroll offsets
  * Recreated UIDoc elements retain their scroll position
* UI scale now participates correctly in prediction and replay, reducing layout and hit-target mismatches after changing scale
* Android hardware volume buttons continue controlling system volume while in-game
* Global leaderboard names containing formatting characters such as `%` now display literally
  * Offscreen leaderboards are also culled
* Dropped items can be culled visually without freezing their gameplay movement
* Reparenting an entity beneath a disabled entity immediately applies the correct disabled state
* Rewarded-ad and CSL purchase grants more reliably wait for client replication before processing
* Restored the built-in CSL green-button asset reference
* All Collider-derived components on an entity now participate in CSL physics
  * Projects using multiple colliders may observe newly correct contacts

</details>

<details>

<summary>CSL Compiler and Project Workflow</summary>

* Compiler diagnostics
  * Capturing procedure literals remain unsupported and now produce an explicit error
  * `return` outside a procedure now reports an error instead of crashing
  * Very long boolean chains and large switches no longer overflow the compiler's native stack
* Script-heavy workloads benefit from optimizer, bytecode-inlining, and value-formatting improvements
* Core library vendoring
  * Opening a CSL project copies the engine core library into `scripts/.ao_core`
  * `import "core:*"` resolves against that project copy
  * The copy is included when publishing and is not rewritten when unchanged
  * Treat `.ao_core` as generated content and do not edit it manually

</details>

<details>

<summary>C# API Changes</summary>

* `Vector2`, `Vector3`, and `Vector4` now explicitly implement component-wise `Equals` and `GetHashCode`
  * Their behavior in dictionaries and sets is now consistent
* Added `Camera.WorldToScreenInterpolationOffset`
* Built-in aiming indicators and target reticles now use frame interpolation
* Aiming helpers gained optional interpolation-offset parameters
  * Normal calls remain source-compatible
  * Reflection, delegates, or method groups relying on the previous exact arity may need updating

</details>

<details>

<summary>Editor, Automation, and Testing</summary>

* Editor `compile` can hot-reload CSL into a running editor-launched game and reconnect clients to the updated state
  * Scene edits still require a stop and restart
* Restored and hardened live game tools for starting and stopping games, screenshots, UI-tree inspection, clicking and holding, keyboard input, and text input
* Added `test_action` for running individual Test.Runner actions in a live game
  * Supported actions include waiting, movement, navmesh pathfinding, interaction, abilities, assertions, inventory and save operations, and variable or component inspection
* Added `assets_validate`, `uidoc_interface`, and `uidoc_diagnostics`
* Direct `client_wait` and `client_health` integrations should migrate to `test_action(wait)` and the newer automation health classification
* `Test.pathfind_to` now follows the navmesh
* Injected test movement is no longer discarded by mobile joystick recomputation
* Screenshot requests time out cleanly instead of occasionally hanging
* Test execution fails fast when a game launch is already in progress
* Automation and compile failures now provide clearer diagnostics and stack traces

</details>

<details>

<summary>Performance, Hosting, and Stability</summary>

* Navmesh pathfinding and rebuilds are substantially faster, especially for repeated paths and unreachable targets
* Collision-heavy CSL games now avoid testing every collider against every other collider
* Web builds use a smaller initial memory reservation and clean up failed asset decode and download paths more reliably
* Linux-hosted servers account for container memory limits while loading assets, reducing startup and prewarming out-of-memory failures
* Asset prewarming and UIDoc replication have lower peak memory use

</details>
{% endupdate %}

{% update date="2026-06-13" %}

## Protocol 44 - June 13th, 2026

This protocol update focuses on CSL compiler performance and memory use, better callback resolution, smoother sync/interpolation behavior, and several runtime fixes for strings, assets, and world-space UI.

<details>

<summary>Sync and Interpolation</summary>

* Network sync now uses the protocol 44 32hz variable sim/sync cadence
  * Game simulation now advances at a lower fixed cadence than rendering
  * Rendering can still look smooth by drawing with an interpolation offset from the previous rendered position to the current simulated position
* Entity-attached rendering
  * World-space rendering calls inside supported component callbacks are automatically attached to that component's entity and interpolated
  * In those callbacks, `UI.push_world_draw_context()` is enough for labels, prompts, health bars, and similar entity-following visuals to move smoothly between sim ticks
  * Outside component callbacks, use `UI.begin_world_space_ui(entity)` and `defer UI.end_world_space_ui()` when drawing world-space UI or other immediate-mode visuals that should follow an entity
  * `UI.begin_world_space_ui(entity)` pushes the world draw context and uses the entity's built-in interpolation data
  * Use `entity.mark_teleported()` when an entity moves discontinuously and you explicitly do not want the next render to interpolate across that jump
  * Large teleports are also detected automatically: if an entity moves more than 3 world units since the previous frame, interpolation is skipped for that frame
* Manual interpolation offsets
  * Use `UI.push_interpolation_offset(offset)` before any custom rendering that needs interpolation
  * Always pair it with `UI.pop_interpolation_offset()`, usually through `defer UI.pop_interpolation_offset()`
  * The offset should represent the movement from the last rendered position to the current position
  * Component entity anchoring uses the same interpolation-offset stack, so nested manual offsets follow normal push/pop order
* Custom non-entity positions
  * Use `Position_Interpolation_Helper` in your own class or struct when you own a position that is not covered by an entity's built-in interpolation
  * Store one helper per moving thing, call `.update(current_position)`, and pass the returned offset to `UI.push_interpolation_offset`
* Animated fill amounts
  * Use `Float_Interpolation_Helper` with `UI.quad(..., params={fill=UI.quad_fill(helper.update(progress), .RIGHT)})` for smoothly animated fills such as progress bars
  * Use `UI.quad_fill(progress, .RIGHT)` when the fill amount does not need interpolation
  * `.RIGHT` fills left to right as the amount moves from `0` to `1`; `.NONE` leaves the quad unfilled and is the zero-initialized value
  * `Quad_Params` also accepts `nine_slice` data for the same draw call

```csl
Particle :: class {
    position: v2;
    velocity: v2;
    interp: Position_Interpolation_Helper;

    update :: method(dt: float) {
        position += velocity * dt;

        UI.push_interpolation_offset(interp.update(position));
        defer UI.pop_interpolation_offset();

        // Draw the particle here.
    }
}
```

* Interpolation anchor context
  * Supported component lifecycle callbacks now automatically push that component entity's interpolation offset while the callback runs
  * This applies to `ao_start`, `ao_update`, `ao_late_update`, `ao_end`, `ao_on_interactable_used`, and `ao_on_holding_interactable`
  * `ao_can_use_ability`, `ao_can_use_interactable`, and `ao_on_state_sync` are intentionally not anchored; keep them small, fast, and pure
  * This applies to sim-owned world-space draw contexts only; present/combine rendering does not read component interpolation anchor state
  * C# component update loops also scope this with push/pop per component, so exceptions cannot leak a stale interpolation anchor

</details>

<details>

<summary>CSL Language and Compiler Changes</summary>

* New procedure-resolution directives
  * `#optional_procedure_of_call(call)` was added
  * It works like `#procedure_of_call(call)`, but unresolved optional calls return an empty procedure value instead of producing a hard error
  * `#procedure_types_are_leniently_compatible(src_type, dst_type)` was added as a compile-time bool check for callback/interface compatibility
* Interface and callback matching
  * Interface procedure requirements now allow compatible derived-class parameter types where the call is safe
  * Overloaded interface method implementations now resolve to the concrete implementation on the actual receiver type
  * Procedure type-vs-overload mistakes now produce clearer compile errors
* Polymorphic assignability constraints
  * Polymorphic type parameters can now constrain assignability with syntax like `$T/Base`
  * This supports APIs that accept a base type while preserving the caller's concrete type
* Range loop bounds
  * Integer widening is now allowed for range bounds when the widening conversion is safe
  * Invalid non-widening range bounds now report a compile error instead of crashing
* New GC helper
  * `#unrootify_object(value)` was added
  * It removes a root from an existing object without freeing the object immediately
* Diagnostics and performance
  * Misplaced `give` statements now produce a targeted error
  * Source locations were compacted internally, preserving file/line reporting while reducing compiler memory
  * The compiler received major memory and throughput optimizations for large scripts

</details>

<details>

<summary>Core API and Runtime Changes</summary>

* `Interactable.set_listener`
  * Now accepts a concrete component listener type instead of collapsing the listener to `Component`
  * Callback lookup now uses CSL call resolution through `#optional_procedure_of_call`
  * Inherited and overload-nested `can_use`, `on_interact`, and `on_holding` callbacks now resolve to the right concrete listener procedure
  * `Interactable` now also declares the `can_use` interface callback
* World-space UI
  * `UI.begin_world_space_ui(entity)` now pushes world draw context in addition to interpolation offset
  * Passing `null` is supported and uses a zero interpolation offset
  * `UI.end_world_space_ui()` now pops both interpolation and draw context
* Global leaderboard package
  * `core:global_leaderboard` adds a reusable `Global_Leaderboard : Component` for world-space ranked scoreboards backed by ordered saves
  * Import it with `import "core:global_leaderboard"` and add `Global_Leaderboard` to a scene entity
  * Set `leaderboard_id` on the component, optionally set `optional_title`
  * On the server, call `Global_Leaderboard.increment_score(player, leaderboard_id, amount)` to add to a player's score
* String getters
  * `Player.get_username()`, `Player.get_user_id()`, `Player.get_name_override()`, and `Entity.get_name()` now cache rooted CSL strings
  * Repeated calls avoid unnecessary string allocation while still updating when the native value changes
* Asset handles
  * Spine skeleton, attachment texture, and cosmetic APIs now resolve CSL asset handles through the scene asset lookup table
  * This fixes cases where CSL-visible assets are represented by script stubs instead of direct native VM objects
* Formatting
  * `tprint`/formatted string output now recognizes `Format_Int` and `Format_Float` by link id
  * Padded integer and float formatting now works in cases where the format helper type is not pointer-identical to the cached runtime type

</details>
{% endupdate %}

{% update date="2026-05-21" %}

## Protocol 43 - May 27th, 2026

This protocol update tightens CSL validation, removes several legacy APIs, changes UIK interaction handling, and updates a few core library behaviors.

<details>

<summary>Breaking CSL Changes</summary>

* Struct and class parameters
  * Explicit `$` on struct or class parameters is now illegal
  * `struct($T: typeid)` → `struct(T: typeid)`
  * This affects patterns like `List`, `Hashtable`, and `Component_Iterator`
  * Polymorphic procedures like `proc($T: typeid, ...)` still work
* Stray `$identifier` usage
  * Standalone `$identifier` is now rejected instead of being treated like `identifier`
* Reserved keywords
  * `bit_field` is now a reserved keyword
  * Any identifier named `bit_field` will now fail
* String and char escapes
  * Unknown escape sequences now produce a compile error
  * They no longer slip through or panic at runtime
* Invalid code now fails earlier
  * Calling non-procedure or non-polymorphic types now errors
  * Comparing incompatible types now errors

</details>

<details>

<summary>Core API Breaks</summary>

* `core:ao/generated`
  * `src/csl/core/ao/generated.csl` was removed
  * Its contents were folded into `core:ao`
  * Direct imports of `core:ao/generated` now break
* `game_support.csl`
  * `src/csl/game_support.csl` was deleted
  * Code relying on its empty `Player :: class : Player_Base` must now define `Player` directly
* Generated `self` fields
  * Generated `self` fields were removed from wrappers like `Entity`, `Component`, `State_Machine*`, `Item_Definition_Base`, `Item_Instance_Base`, and `Inventory_Base`
* Item definition getters
  * `Item_Definition_Base.get_name()` and `Item_Definition_Base.get_id()` were removed from the base API
  * `Item_Definition` still keeps soft-deprecated getters
  * Code typed as `Item_Definition_Base` must use `.name` and `.id`
* Spine instance hierarchy
  * `Spine_Instance_Base` was removed
  * `Spine_Instance` now inherits `Spine_Instance_Fields` directly
  * Explicit references or casts to `Spine_Instance_Base` now break
* Skeleton APIs
  * `Spine_Animator.set_skeleton()` and `Spine_Instance.set_skeleton()` now return `u64`
  * `get_skeleton()` now takes an optional `id: u64 = 0`
* Collider hierarchy
  * `Circle_Collider`, `Box_Collider`, `Polygon_Collider`, and `Edge_Collider` now inherit from `Collider`
  * They no longer inherit directly from `Component`
  * Normal component usage should still work
  * Reflection and direct parent checks can break

</details>

<details>

<summary>UIK Breaks</summary>

* Interact handles were removed
  * `UIK.Interact_Handle` was removed
  * Interactive APIs now return `Interact_Result` directly
  * This affects `panel_begin_interactive`, `toggle`, `card_end`, both `tab` overloads, `button`, `icon_button`, `icon_button_label`, and `title_area`
* Resolve flow changed
  * `UIK.resolve(handle)` was removed
  * `UIK.clicked`, `UIK.hovering`, `UIK.pressed`, and related helpers now take `Interact_Result`
  * You can also read `.clicked`, `.hovering`, and related fields directly
* Deferred handle patterns
  * Old patterns that store handles and resolve them after `UIK.end()` should be rewritten to the new simpler pattern
* Yellow enum names
  * `..._YELLOW1` was renamed to `..._YELLOW`
  * `..._YELLOW2` was renamed to `..._ORANGE`

</details>

<details>

<summary>Library and behavior changes</summary>

* Math helpers
  * Generic `lerp`, `clamp`, `min`, and `max` were replaced with concrete overloads
  * `lerp` now supports `v2`, `v3`, `v4`, and `float`
  * `clamp`, `min`, and `max` now support `int` and `float`
  * Calls on other types can now break
* UIK layout helpers
  * `rect_sidebar_left`, `rect_sidebar_right`, `rect_topbar`, `rect_hotbar`, and `rect_dialog` changed layout behavior
  * Their signatures stay the same
  * Existing layouts may shift

</details>

<details>

<summary>Developer workflow</summary>

* `csl.exe <folder>` now defaults to compile and run
* Use `csl.exe <folder> -no_run` for compile-only behavior

</details>
{% endupdate %}

{% update date="2026-04-07" %}

## Protocol 42 - April 16th, 2026

This protocol update brings major CSL breaking changes, stricter runtime enforcement, an overhauled SFX system, and several new engine APIs.

<details>

<summary>Breaking Changes</summary>

* Type system
  * `b8`, `b16`, `b32`, and `b64` were removed. Only `bool` remains.
  * Scripts using those type names will fail to compile.
* Entity hierarchy fields were replaced with methods
  * `entity.parent` → `entity.get_parent()`
  * `entity.first_child` / `entity.last_child` → `entity.get_first_child()` / `entity.get_last_child()`
  * `entity.next_sibling` / `entity.prev_sibling` → `entity.get_next_sibling()` / `entity.get_prev_sibling()`
  * `entity.first_component` / `entity.last_component` → `entity.get_first_component()` / `entity.get_last_component()`
* Component navigation fields were replaced with methods
  * `component.prev_component_on_entity` → `component.get_prev_component_on_entity()`
  * `component.next_component_on_entity` → `component.get_next_component_on_entity()`
* Component state fields were replaced with accessors
  * `component.enabled` → `component.get_enabled()` / `component.set_enabled()`
* Component iterator updates
  * `next(ref Component_Iterator)` was removed. Use `.next()` instead.
* Effects system was restructured
  * `entity.active_effect` → `entity.get_active_effect()` and now safely returns `null` when no effects exist
  * `entity.first_effect` → `entity.get_first_effect()`
  * `entity.last_effect` → `entity.get_last_effect()`
* List construction changed
  * `List.append` is now hard-deprecated for list construction. Use `[..]T` instead.
* Math functions
  * `atan2` changed parameter order from `atan2(x, y)` to `atan2(y, x)` to match standard C behavior
  * Generic `min(a, b)` and `max(a, b)` procedures were removed from `basic.csl`
  * `normalize(v)` no longer includes a zero-length safety check and may now produce `NaN` or `inf`
  * `sin`, `cos`, `atan2`, `pow`, and `sqrt` changed from foreign calls to intrinsic VM opcodes
  * Serialized bytecode is incompatible with previous builds
  * New `f64` overloads were added for `sin`, `cos`, `atan2`, `pow`, and `sqrt`
* Removed APIs
  * The `Gif` asset class was removed entirely, including the `Gif` type, `UI.Gif()` widget, `UIGif` component, and related internal calls in C# and CSL
  * `Sprite_Renderer.WaitForLoad` was removed and now only exists as an obsolete no-op in C#
* Runtime enforcement
  * UI functions now panic outside player update context on the client
  * This affects `ui_button`, `ui_begin_button`, `ui_end_button`, `ui_push_scroll_view`, `ui_pop_scroll_view`, `ui_compute_scroll_bar_rect`, `ui_drag_drop_source`, `ui_drag_drop_target`, `ui_blocker`, `ui_begin_modal`, and `ui_end_modal`
  * These must be called from `core_player_update` or `core_player_late_update`
* SFX system overhaul
  * SFX playback is now authoritative on the server
  * The server tracks active sounds persistently, including ID, duration, elapsed time, and fade-out state
  * Clients now mirror the server's active sound list
  * `sfx_stop` now works correctly across the network

</details>

<details>

<summary>CSL Language Changes</summary>

* Method call syntax now uses `.` instead of `->`
  * `b->set_x(20);` → `b.set_x(20);`
* Fixed-size array literals now support values directly
  * `[4]int{1, 2, 3, 4}` is now valid
* Casting now supports prefix syntax in addition to suffix casting
* Half-closed ranges now support `^`
* Hashtables are now supported
* Class members now support default values, including reassignment in derived classes
* Implicit integer widening is now allowed for safe widening conversions
  * Example: `s32` → `s64`
* `switch` cases now support multiple values and inclusive ranges

```csl
switch level {
    case 1, 2, 3: tier = .BEGINNER;
    case 4..10:   tier = .INTERMEDIATE;
    case 11..20, 25, 30..50: tier = .ADVANCED;
    default:      tier = .UNKNOWN;
}
```

{% hint style="warning" %}
Migration tooling note: do **not** blindly replace every `->` with `.`. Return type definitions still use `->`, so a global search-and-replace will corrupt valid code.
{% endhint %}

</details>

<details>

<summary>Deprecations</summary>

* `case:` with no expression in a `switch` is deprecated. Use `default:` instead.
* Duplicate `default` cases now produce a compile error.
* `get_real_time()` is now soft-deprecated. Use `rng_root_seed()` for RNG seeding.
* `rng_seed_time()` is now soft-deprecated and returns `rng_root_seed()` internally.

</details>

<details>

<summary>New APIs</summary>

* `Datetime`
  * Includes `year`, `month`, `day`, `hour`, `minute`, and `second` as `s64`
* `get_nanoseconds_since_epoch() -> s64`
  * Returns UTC nanoseconds
* `get_utc_datetime() -> Datetime`
* `rng_root_seed() -> u64`
  * Returns the deterministic game-instance RNG seed
* `SFX.fade_out_and_stop(id, fade_time)`
* `Player_Base.get_name_override() -> string`
* `Player_Base.set_name_override(name)`
* `core_globals.server_on_chat_message_received`
  * Callback signature: `proc(player: Player, message: string)`
* `Texture_Asset.get_uvs() -> v2, v2`
  * Returns low and high UV coordinates
* `Time.nanoseconds_since_epoch() -> u64`
* `SFX_Desc.local_only: bool`
  * Hard-deprecated. Use `SFX_Desc.specific_to_player`.
* `SFX_Desc.specific_to_player: Player`
  * Tracks the sound on the server but only triggers playback on the target player's client
* `Sprite_Renderer.mask_in_shadow: bool`
* `Spine_Animator.mask_in_shadow: bool`
* Spine animation APIs
  * `Spine_Animator.set_on_event()`
  * `Spine_Animator.set_on_animation_start()`
  * `Spine_Animator.set_on_animation_end()`
  * `Spine_Event_Data`
* Spine animator access
  * All Spine methods are now available directly on `Spine_Animator`
  * `.instance` is no longer required
* `Entity.set_name()`
* `Entity.compare_name(name: string) -> bool`
* Scene inventory and save APIs
  * Added inventory capacity APIs
  * Added auto-save APIs
* Voice and VOIP APIs
  * `voice_set_range(float)`
  * `voice_get_range()`
  * `Scene::voip_range`
* UIK
  * New API for building UIs
  * Docs are coming soon

</details>
{% endupdate %}

{% update date="2026-03-06" %}

## Protocol 41 - March 3rd, 2026

This protocol update improved CSL netcode performance dramatically and introduced new **Terrain and Tilemap editor tools and a built in agent to help with scripting and world building!**

<details>

<summary>New Features</summary>

* Terrain tool
  * Paint grasslands, oceans, shores, caves and more with broad high performance brush strokes
* Tilemap editor tool
  * Bring a tile set (or use one of ours) and create tiled maps using the new tilemap component
* Agent pane
  * Hooks into Claude Code or Codex-Cli and can build maps, write scripts, and design UI
* New MCP features
  * Tools for world building
  * Tools for reading game logs
  * Tools for adding full SFX from our catalog to your games!

</details>

<details>

<summary>API Changes</summary>

* Improved leaderboard culling APIs

</details>

<details>

<summary>Bug Fixes</summary>

* Major crash fixes & performance improvements!

</details>
{% endupdate %}

{% update date="2026-01-30" %}

## Protocol 40 - Feb 9th, 2026

This protocol update introduces CSL and makes major improvements to the editor workflow for new projects. Protocol 40 is expected to launch around Feb 3rd

<details>

<summary>New Features</summary>

* Adds support for our new game programming language. You'll see new experiences built with this soon!
* Voice chat quality and moderation accuracy improved
* Added chat spam prevention
* Core app features are now translated into 34 languages!
* Improved text rendering on low-end devices
* Android now supports deeplinks from web/push notifications into the app.

</details>

<details>

<summary>Editor Changes</summary>

* The editor now has you select a "game projects" directory at startup and will make any game there available to you\
  When creating a new game from Campfire, we now automatically fill in the ao.project with your game ID.
* Added saving progress bar to the top of the editor when saving
* Added in-editor asset search
* Assets in your project can now be rearranged in folders directly in the editor
* Improved project upload (zip) speed
* Launching the game for testing will use the latest version of the scene even if you haven't saved yet
* You can now change the scale of Sprite\_Renderers directly in editor
* You can now create and save custom layouts for editor panel positions
* The MCP server is now installed automatically
* CSL is now default for new projects. If you need C# you must remove csl: true from ao.project

</details>

<details>

<summary>API Changes</summary>

* Added C# Save.GetAllKeys()

</details>

<details>

<summary>Bug Fixes</summary>

* No major bug fixes this release

</details>
{% endupdate %}
{% endupdates %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.allout.game/changelog/readme.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
