> For the complete documentation index, see [llms.txt](https://docs.fullscreen.no/info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fullscreen.no/info/standalone-assets/runtime-studio/muting-concept.md).

# Muting Concept

{% hint style="warning" %}

#### Technical Overview

This section explains the internal muting system used by Runtime Studio. It is intended for developers working on custom integrations or those interested in how runtime behavior is managed. Most users will not need to interact with these systems directly.
{% endhint %}

This page explains how Runtime Studio keeps gameplay logic from waking up while the user is only editing a scene.

It covers:

* the core muting model
* when muting runs
* what `OwnsBehaviourEnabledState` means
* how Runtime Studio restores runtime behavior for Runtime Studio play mode
* how the Game Creator 2 plugin mutes triggers, characters, hotspots, cameras, and related behaviors

### Why muting exists

Runtime Studio edits live runtime scenes.

That means a selected object is still a real scene object with real components. If those components keep running their gameplay logic while the user edits them, a few bad things happen:

* `OnEnable`, `Start`, and `Update` logic can fire while the user is only moving objects around
* AI, triggers, cameras, animators, and character controllers can start reacting to edit-time state
* placed prefabs can immediately wake gameplay systems
* save/load restore can briefly re-enable systems before Runtime Studio has finished rebinding them

Muting is the mechanism Runtime Studio uses to temporarily freeze those runtime behaviors during edit mode, then restore them when entering Runtime Studio play mode.

### Core idea

At a high level, Runtime Studio separates two states:

1. The authored state the object should really have
2. The temporary muted state needed while the editor is active

The authored state is what should be saved, exported, and restored for gameplay.

The muted state is only a temporary edit-time shell. Runtime Studio applies it so users can safely inspect, move, duplicate, save, load, and place objects without firing package runtime logic.

### The core muting lifecycle

The muting contract lives in `RuntimeIntegration`.

Key hooks:

* `OwnsBehaviourEnabledState(Behaviour behaviour)`
* `ApplyEditIsolation(Component component)`
* `ApplyEditModeState()`
* `RestoreEditModeState()`
* `EnterRuntimePlayMode()`
* `PrepareForSceneRestore()`
* `OnComponentRestored(Component component)`
* `RebindRestoredObject(GameObject gameObject)`
* `PreparePlacedObject(GameObject gameObject, RuntimeSceneObjectPlacementContext context)`
* `GetEditModeBehaviourStates()`

#### What each hook is for

`OwnsBehaviourEnabledState(...)`

* Tells Runtime Studio that the integration wants to manage a behavior's enabled state itself.
* This matters for packages that need to remember the authored enabled state separately from the temporary muted state.

`ApplyEditIsolation(...)`

* Called per component when Runtime Studio needs to mute runtime behavior for edit mode.
* Best for local one-component muting such as disabling a trigger, hotspot, or package-specific behavior.

`ApplyEditModeState()`

* Applies package-wide edit-mode muting across the scene.
* Best for global scans like "find all package characters and freeze them."

`RestoreEditModeState()`

* Restores the captured authored edit-time values after Runtime Studio play mode exits.
* This is the step that puts objects back into the user-authored edit shell.

`EnterRuntimePlayMode()`

* Re-enables runtime behavior for Runtime Studio play mode.
* This is where a package should turn gameplay systems back on and reinitialize them if needed.

`PrepareForSceneRestore()`

* Freezes package state before save/load restore work starts.
* Important because scene restore may replace objects and serialized state in phases.

`OnComponentRestored(...)` and `RebindRestoredObject(...)`

* Repair runtime-only links after serialized data is back.
* Useful when package internals need startup or rebinding after restore.

`PreparePlacedObject(...)`

* Runs when Runtime Studio places a prefab or preview object into the scene.
* This is the main defense against newly placed package objects waking up immediately.

`GetEditModeBehaviourStates()`

* Returns the authored enabled state Runtime Studio should preserve in save/export snapshots.
* Without this, snapshots may accidentally capture the temporary muted state instead of the real intended state.

### Important limitation: `Awake` is different

Runtime Studio can mute many runtime behaviors after it initializes, but it cannot undo an `Awake` that Unity already ran before Runtime Studio got control.

That means:

* `OnEnable`, `Start`, runtime callbacks, and many package systems can be muted
* `Awake` cannot be retroactively "un-fired"

If a third-party system must not run `Awake` until play, it needs to be authored inactive/disabled or routed through a package-specific startup path that the integration triggers later.

### What `OwnsBehaviourEnabledState` really means

This method is the handoff point between core Runtime Studio and an integration.

When an integration returns `true` for a behavior:

* the integration becomes responsible for preserving the intended enabled state
* the integration can safely force that behavior into a muted state during editing
* the integration can later restore or reinterpret the intended state for play

This is especially important for systems like:

* characters
* animators
* triggers
* custom package behaviors
* cameras

If a package only disables components without capturing authored values, save/load and repeated play sessions can drift away from what the content author intended.

### How muting interacts with save/load

Runtime Studio wants save/load to preserve the authored state, not the temporary muted state.

That is why integrations are expected to:

* capture intended enabled values
* return those values from `GetEditModeBehaviourStates()`
* re-freeze objects in `PrepareForSceneRestore()`
* repair runtime-only links in `OnComponentRestored(...)` and `RebindRestoredObject(...)`

The result is:

* edit mode stays safe
* save data stays faithful
* runtime play mode can still rebuild the true package runtime state

### How muting interacts with placed prefabs

When Runtime Studio places an object from the Project panel, hierarchy shortcuts, or a drop action, it creates the object inactive first, then calls `PreparePlacedObject(...)`.

This gives integrations a chance to:

* disable package runtime behaviors
* sanitize runtime-only objects
* prepare references
* stop `OnEnable` and `Start` chains from waking up immediately

After that, Runtime Studio restores the placed root's authored active state.

This is one of the most important safety guarantees in the system.

### Game Creator 2 muting overview

The Game Creator 2 plugin uses a dedicated `RuntimeIntegration` plus a large `RuntimeBridge` helper to implement muting and restore behavior.

The integration takes ownership of Game Creator runtime behavior by:

* reporting GC2-owned behaviors through `OwnsBehaviourEnabledState(...)`
* muting GC2 objects in `ApplyEditIsolation(...)`
* scanning the whole scene in `ApplyEditModeState()`
* restoring authored values in `RestoreEditModeState()`
* rebuilding live runtime state in `EnterRuntimePlayMode()`
* freezing and rebinding objects during restore and placement

The GC2 integration handles several categories differently:

* triggers
* characters
* animators on characters
* hotspots
* GC2 camera behaviors
* other GC2-owned behaviors under characters

### Game Creator 2 triggers

Triggers are muted in a special way.

Runtime Studio does not just disable the `Trigger` component and call it done. Instead, it keeps track of two trigger-event states:

* the real runtime event the trigger should use
* a temporary editor-muted event installed while editing

#### How trigger muting works

When Runtime Studio isolates a GC2 `Trigger`:

1. It reads the real trigger event from `m_TriggerEvent`
2. It stores that event in an internal `TriggerEventState.RuntimeEvent`
3. If the event was already initialized and active, it calls the event's `OnDisable(trigger)` lifecycle
4. It marks the trigger as muted
5. It swaps the live `m_TriggerEvent` field to an internal `EditorMutedEvent`

That `EditorMutedEvent` is just a placeholder event used to stop the real event from reacting during edit mode.

#### Why GC2 triggers are muted this way

This approach gives Runtime Studio a few benefits:

* the trigger component can stay present in the scene
* the inspector can still edit the real trigger configuration
* the real runtime event is preserved separately from the temporary edit-time event
* when Runtime Studio enters play mode, the real event can be restored and started correctly

#### Trigger state tracked by Runtime Studio

For each trigger, Runtime Studio tracks:

* `Muted`
* `MutedEvent`
* `RuntimeEvent`
* `RuntimeInitialized`
* `RuntimeEnabled`
* `RuntimeStarted`

This lets the plugin avoid double-initializing the same trigger event and correctly resume its lifecycle later.

#### What happens when entering Runtime Studio play mode

When Runtime Studio enters its own play mode, the GC2 bridge:

1. clears dead cached trigger state entries
2. restores the real trigger event back into `m_TriggerEvent`
3. reapplies trigger requirements/configuration
4. runs the trigger event lifecycle in order:
   * `OnAwake(trigger)` if needed
   * `OnEnable(trigger)` if active
   * `OnStart(trigger)` if runtime play should run start logic

This is why GC2 triggers can stay editable in Runtime Studio without firing during edit mode, but still come back alive when runtime play begins.

### Game Creator 2 characters

Characters use a broader muting model than triggers.

The GC2 integration captures a `CharacterEditState` with:

* authored controllable state
* authored player state
* authored driver kinematics state
* authored enabled state

#### What Runtime Studio does in edit mode

When a GC2 `Character` is muted for edit mode, Runtime Studio:

1. captures the authored character state if it has not already been captured
2. forces `IsControllable` to `false`
3. forces `IsPlayer` to `false`
4. forces driver kinematics updates off
5. keeps character model animators in an edit-safe state
6. disables the `Character` component itself

This prevents common edit-time problems such as:

* movement or input waking up while dragging the character
* player shortcut registration sticking to edit-time objects
* navmesh driver logic starting while the user is placing or restoring content
* character-owned GC2 systems reacting during restore

#### Why Runtime Studio stores "intended" player and controllable values

The inspector still needs to show the values the user actually authored.

So while edit mode may temporarily force:

* `IsPlayer = false`
* `IsControllable = false`

Runtime Studio separately stores the intended values in the character edit state.

That means:

* the inspector can display the intended authored values
* saves and exports preserve the authored values
* runtime play can restore the correct live behavior later

#### Character animators are handled specially

Character animators are not simply disabled in the same way as other behaviors.

Runtime Studio captures each animator's authored enabled state and keeps it in a dedicated animator state map.

During normal edit isolation:

* character animators are usually kept enabled if their authored state was enabled
* this allows pose/model preview to remain usable while editing

During scene restore:

* `CharacterSceneRestoreInProgress` is set
* animators are temporarily suppressed while rebinding and model repair happen

#### Other GC2-owned behaviors under characters

The plugin also mutes other GC2-owned behaviors attached under a character hierarchy.

That includes:

* behaviors in `GameCreator.Runtime.Characters.*`
* other `GameCreator.Runtime.*` behaviors that belong under a character
* `NavMeshAgent` when it belongs to a GC2 character

Those behaviors are captured and disabled separately so their authored enabled values can be restored later.

### Game Creator 2 hotspots

Hotspots are muted by:

* capturing their authored enabled state
* cleaning up transient hotspot runtime objects
* disabling the hotspot during edit mode

This avoids leftover tooltip, hint, and temporary hotspot objects surviving into edit mode or restore flows.

### Game Creator 2 cameras and shot cameras

GC2 camera behaviors are also muted during edit mode.

Runtime Studio:

* captures their authored enabled state
* disables them while editing
* rebinds shot types and camera transitions after restore
* reactivates them when entering Runtime Studio play mode

This prevents edit-time camera systems from competing with the scene editing camera.

### Scene restore behavior for GC2

Before a restore starts, the GC2 plugin does extra preparation:

* freezes characters into edit mode
* cleans up rig handles
* prepares hotspots for restore
* marks that a character scene restore is in progress

After objects are restored, the plugin:

* refreshes trigger events
* syncs intended character state from restored data
* repairs character runtime bindings
* rebinds shot cameras and cameras
* repairs IK and model references
* re-applies character model prefabs if needed

This is why the GC2 integration can survive save/load and import/export without the live runtime systems drifting into broken or half-active states.

### Runtime Studio play entry for GC2

When Runtime Studio enters its runtime play mode, the GC2 plugin:

1. clears pooled GC2 runtime children
2. prepares all characters for runtime play
3. restores GC2-owned behaviors to their intended enabled states
4. restores real trigger events
5. re-registers player, main camera, and main shot shortcuts
6. starts shot cameras and camera transitions

#### A useful subtlety

If a character's intended `IsPlayer` is true, Runtime Studio normalizes that character to a live runtime state for Runtime Studio play.

This prevents repeated edit/play cycles in the same Unity session from leaving the player character accidentally muted or non-functional.

### Mental model for extension authors

If you are writing your own package integration, the safest way to think about muting is:

* capture authored state once
* force a safe edit shell
* save the authored state, not the shell state
* rebuild runtime-only state after restore
* restore the authored runtime state only when entering Runtime Studio play

If your package behaves like GC2 triggers:

* keep a separate stored runtime payload
* swap in a harmless edit-time placeholder
* restore the real payload before runtime play

If your package behaves like GC2 characters:

* capture authored flags separately from the live object
* mute the runtime systems broadly
* repair runtime-only caches and bindings after restore
* normalize play-entry state explicitly
