> 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/coming-from-other-tools/unity.md).

# Unity

If you've built games with Unity, there are some key differences you'll need to know to get started on All Out!

***

If you're coming from Unity, you'll feel at home with **entities + components**, a **hierarchy**, an **inspector**, and reusable **prefabs**. The biggest mindset shift is that All Out games are **multiplayer-first**: normal gameplay runs on the predicting client and authoritative server, while the engine syncs supported state for you.

## TL;DR: What’s different vs Unity

* **Multiplayer is the default**: you generally **do not** write RPCs, SyncVars, or Netcode spawning logic.
* **Write one gameplay path**: don't guard normal gameplay with `Game.is_server()` or you'll disable prediction.
* **Be intentional about player UI**:
  * Draw a player's gameplay UI from that player's `ao_late_update` inside `is_local_or_server()`.
  * Use `is_local()` only for player-specific visual overrides.
* **Avoid global singleton state**: multiple players connect to the same session. Prefer storing state on the player or on world components.
* **All Out gameplay is 2D**: position and scale use `v2`, while rotation is one angle in degrees.
* **Mobile-first**: avoid keyboard-only assumptions unless your game explicitly targets PC.

## Concept mapping (Unity → All Out)

| Unity                     | All Out                                         |
| ------------------------- | ----------------------------------------------- |
| Scene                     | Scene (world)                                   |
| GameObject                | Entity                                          |
| Transform                 | 2D entity transform (position/rotation/scale)   |
| Component / MonoBehaviour | Component (CSL class deriving from `Component`) |
| Prefab                    | Prefab asset (created in-editor)                |
| Hierarchy window          | [Hierarchy](/using-the-editor/hierarchy.md)     |
| Inspector window          | [Inspector](/using-the-editor/inspector.md)     |
| `Instantiate(prefab)`     | `Scene.instantiate(prefab_asset)`               |
| `Start()` / `Update()`    | `ao_start` / `ao_update(dt)` lifecycle          |

## Project layout: where “scripts” and “assets” live

* **Scripts**: Your game code lives in `.csl` files. New projects start with a `main.csl` that imports the engine and defines lifecycle entry points. See [Getting Started with CSL](/scripting/syntax.md).
* **Assets**: Game assets live under your project’s `/res` directory and are referenced by path **without** the `/res` prefix (example: `"ui/button.png"`). See [Assets and Resources](/core-engine-concepts/assets-and-resources.md).

### Imports (important difference)

In Unity, each C# script is compiled and can use its own `using` directives. In All Out, keep imports centralized:

* Import `"core:ao"` in `main.csl`
* If you add a folder (like `ui/`), import the folder **once** in `main.csl`
* Avoid adding imports in other files

Example:

```go
// main.csl
import "core:ao"
import "ui" // optional: brings all files under /scripts/ui into scope
```

## Lifecycle: MonoBehaviour → CSL

In Unity you typically attach a `MonoBehaviour` to a GameObject and implement:

* `Start()` / `Awake()`
* `Update()` / `LateUpdate()`
* `OnDestroy()`

In CSL, you’ll commonly use:

* Global procs in `main.csl` (for game-level setup)
* Component lifecycle methods on your components

Example component:

```go
// orbiter.csl
Orbiter :: class : Component {
    center: v2;
    radius: float;
    speed: float;
    angle: float;

    ao_start :: method() {
        center = entity.local_position;
        radius = 2.0;
        speed = 1.0;
        angle = 0.0;
    }

    ao_update :: method(dt: float) {
        angle += speed * dt;
        offset := v2{cos(angle) * radius, sin(angle) * radius};
        entity.set_local_position(center + offset);
    }
}
```

Global lifecycle procs run in each participating scene simulation; they are not server-only. Late-joining clients may receive a component whose start lifecycle already ran, so rebuild presentation from synchronized state in `ao_on_state_sync` when needed. See [Game/Frame Lifecycle](/scripting/game-frame-lifecycle.md).

## Prefabs: Unity Prefabs → All Out Prefabs

All Out prefabs are created in the editor and can be reused or spawned at runtime.

* **Create**: see [Prefabs](/using-the-editor/prefabs.md)
* **Spawn at runtime**:

```go
spawn_enemy :: proc() {
    prefab := get_asset(Prefab_Asset, "Enemies/BasicEnemy.prefab");
    e := Scene.instantiate(prefab, {10, 5});
}
```

{% hint style="info" %}
Linked instances preserve root properties, but component-field changes inside an instance are not independent overrides. See [Prefabs](/using-the-editor/prefabs.md).
{% endhint %}

## “Serialized fields” (Inspector-exposed variables)

Unity uses `[SerializeField]` and public fields to expose values in the Inspector. In CSL, use `@ao_serialize` to expose a field to the editor.

```go
Damage_On_Touch :: class : Component {
    damage: int = 10 @ao_serialize;
}
```

Then add your component to an entity in the [Inspector](/using-the-editor/inspector.md) and tweak values per entity.

## Spawning and querying: Instantiate/Find → Scene APIs

Unity patterns:

* `new GameObject()` / `Instantiate()`
* `FindObjectOfType<T>()`, `GetComponentsInChildren<T>()`

All Out patterns:

```go
// Create and destroy entities
e := Scene.create_entity();
e.set_local_position({0, 0});
e.destroy();

// Iterate entities (when you truly need "everything")
for e2: entity_iterator() {
}

// Iterate components of a specific type
for player: component_iterator(Player) {
}
```

## Collision & triggers

An enabled collider with `is_trigger` set can call `on_trigger_start`, `on_trigger_stay`, and `on_trigger_end`. Each callback receives the trigger collider and the other collider. A `Movement_Agent` is not required.

CSL does not expose a general solid-contact callback equivalent to `OnCollisionEnter`. Use a trigger for enter/exit behavior. For broad sensing, query nearby components:

```go
nearby: [..]Pickup;
Scene.get_all_components_in_range(entity.local_position, 2.0, ref nearby);

for p: nearby {
    // check distance / apply effect / etc.
}
```

See [Navmesh & Collision](/core-engine-concepts/navmesh-and-collision.md).

## Multiplayer mindset: inputs, UI, and “where code runs”

In Unity you can often assume “my client owns my character”. In All Out, write gameplay once for the shared predicted path:

* **Gameplay input/UI**: draw it from the player in `ao_late_update` inside `is_local_or_server()`.
* **Player-specific visual overrides**: use `is_local()`.

See [Networking Fundamentals](/scripting/networking-fundamentals.md).

## Common Unity-to-All-Out gotchas

* **Singleton managers**: prefer per-player or per-entity state instead of global `GameManager` style singletons.
* **Import habits**: import engine and folders from `main.csl` (don’t scatter imports across many files).
* **Server guards**: don't wrap normal gameplay in `Game.is_server()`.
* **3D transforms**: decide how the design maps into a 2D scene and use renderer layers for draw order.
* **Assuming singleplayer**: always think “what happens with 10 players connected?”
* **Hardcoded desktop input**: avoid requiring keyboard/mouse unless intentional.

## Where to go next

* [Getting Started with CSL](/scripting/syntax.md)
* [Hierarchy](/using-the-editor/hierarchy.md)
* [Inspector](/using-the-editor/inspector.md)
* [Prefabs](/using-the-editor/prefabs.md)
