Create a Level
A level is made up of three parts: a LevelInfo ScriptableObject that describes it, a Unity scene that contains the tile grid and all actors, and a Build Settings entry so the scene can be loaded at runtime.
Overview
The three pieces must exist before a level can be played. Create them in this order:
| Component | Purpose |
|---|---|
LevelInfo (ScriptableObject) | Holds the level's display name, a reference to its scene, and the array of goal conditions that determine victory. |
| Level Scene (Unity scene) | Contains the tile grid, the player, all enemies and interactables, plus the manager GameObjects that drive execution. |
| Build Settings entry | The scene must be registered in File → Build Settings so it can be loaded at runtime by the scene reference stored in LevelInfo. |
Step 1 — Create the LevelInfo asset
- In the Project window navigate to Assets / Scriptable Objects / Levels.
- Right-click → Create → Loop Adventure → Level Info.
- Name the asset (e.g.
Level_06). - Fill in the fields described below, then link it to the scene you will create in Step 2.
| Field | Type | Description |
|---|---|---|
displayName | string | Name shown in the level-select UI. |
scene | SceneReference | Drag the level's .unity scene asset here. The system uses this reference to load the level at runtime — the scene must also be registered in Build Settings (covered in Step 2). |
goals | Goal[] | Array of victory conditions. Configured in Step 6. |
id field. It is auto-generated from the asset's GUID and is used to match save data to the correct level. Changing it will break existing save files.
Step 2 — Set up the scene
The fastest way to start is to duplicate an existing level scene from Assets / Scenes / Levels / — all manager GameObjects and UI will already be wired. Clear the old tile grid and enemies, then design the new layout.
To start from an empty scene instead, drag the Game Manager prefab into the Hierarchy. It bundles LevelManager, InstructionSheet, SoundManager and MusicManager with all Inspector fields pre-configured.
- Name the scene using the convention
Level_XX_(description).unityand save it to Assets / Scenes / Levels /. - Open File → Build Settings, click Add Open Scenes.
- Drag the new scene asset into the
scenefield of the LevelInfo asset from Step 1.
Step 3 — Build the tile grid
MapManager discovers all PathTile components in the scene automatically at startup — no manual wiring is needed. Place tiles as regular GameObjects and assign the correct TileType in the Inspector.
| TileType | Required count | Description |
|---|---|---|
Start | Exactly 1 | The player's starting position. The player is placed here when execution begins. |
Path | 1 or more | Walkable tiles the player can move through. |
End | Exactly 1 | The level objective. Reaching this tile triggers the win check. |
MapManager calculates cellSize from the SpriteRenderer of the first tile it finds. If tiles have different sizes the grid will be misaligned and movement offsets will be wrong.
Step 4 — Place the player
- Drag the Player_InGame prefab (in Assets / !!_Prefabs / Player /) into the Hierarchy.
- Position it on top of the
Starttile. - Assign the required Inspector fields listed below.
The player is discovered automatically via FindFirstObjectByType<PlayerController>() — you do not need to assign it to any manager.
| Field | Type | Description |
|---|---|---|
damageStat | Stat (SO) | ScriptableObject that defines the player's base damage value. |
defenseStat | Stat (SO) | ScriptableObject that defines the player's base defense value. |
useItemFX | Prefab | Visual effect spawned when the player uses an item. |
useItemParticles | ParticleSystem | Particle effect played alongside useItemFX. |
Step 5 — Wire the LevelManager
If you started from a duplicate scene or the Game Manager prefab these fields are already set. Otherwise, assign them on the LevelManager component in the Inspector.
| Field | Type | Description |
|---|---|---|
turnInterval | float | Duration of each execution turn in seconds. |
turnWait | float | Pause between the end of one turn and the start of the next (default: 1). |
instructionsContainer | GameObject | Root UI panel that contains the instruction sheet. Toggled visible during gameplay. |
audioSource | AudioSource | Audio source used to play turn and action-change sounds. |
turnChangeAudio | AudioClip | Sound played at the start of each execution turn. |
actionChangeAudio | AudioClip | Sound played when the active instruction step changes. |
Step 6 — Define goals
Goals are configured in the LevelInfo asset's goals array. Each entry pairs a goal class with a threshold value. All goals in the array must be satisfied simultaneously for the level to be marked complete.
| Class | Win condition | amountRequired |
|---|---|---|
LevelGoal_InstructionCount | Total instructions placed ≤ N | Maximum instruction count |
LevelGoal_LoopCount | Total loop iterations across all sequences ≤ N | Maximum loop count |
LevelGoal_PlayerHealth | Player's remaining health ≥ N | Minimum health at completion |
goals is empty the level completes as soon as the player reaches the End tile with no additional constraints — useful for tutorial levels that just teach movement.
To define a custom goal that evaluates any statistic from the completed run, see LevelGoal in the scripting reference.
Step 7 — Add enemies and interactables
Enemies, traps, and interactable objects are all ExecutionContextElement subclasses. Place their prefabs anywhere in the scene Hierarchy — they are discovered and cloned automatically when execution starts. No extra wiring to any manager is required.
See the related guides for how to configure each type:
- Create an Enemy Instruction — add AI behaviour that runs each turn alongside the player.
- Create an Interactable — doors, crates, levers and other world objects.
- Tile Traps — pressure plates and appearing spikes that activate automatically.
Step 8 — Register on the World Map
Each level needs a LevelMarker in the World Map scene so the player can select and launch it from the overworld. The marker reads the LevelInfo asset to display the level's name, star rating, and unlock state.
- Open the World Map scene (in Assets / Scenes /).
- Find an existing
LevelMarkerGameObject in the Hierarchy and duplicate it, or create a new one by adding the LevelMarker component to a suitable GameObject. - In the Inspector, assign the
LevelInfoasset created in Step 1 to the Level field. - Wire any child
LevelMarkerreferences in the Childs array to unlock the next levels in sequence once this one is completed. - Position the marker on the world map to match the level's place in the progression path.
LevelMarker compares save data against the goals array in the LevelInfo asset to decide how many stars to display. Make sure the goals are configured in Step 6 before testing.