# Troubleshooting

Use this page when a scene does not update the way you expect.

## Computing Outside `lift(...)`

Reactive math must be inside `lift(...)`.

```python
# Wrong: this tries to compute immediately.
y = np.sin(x)

# Right: this records that y depends on x.
y = lift(lambda x_value: np.sin(x_value), x)
```

## Passing Only Normal Values

An object is reactive only when at least one argument contains a reactive value.

```python
# Normal Manim values: created once, not tracked.
circle = d.Circle(radius=1)

# Reactive value: refreshed when r changes.
r = self.state(1)
circle = d.Circle(radius=r)
```

## Mutating State In Place

Treat state values as immutable. Do not mutate objects returned by `.get()` and expect Manim Stateflow to notice.

```python
# Wrong: this only mutates a local returned value.
points = state.points.get()
points[0] = [1, 2, 0]

# Right: set a new state value.
points = state.points.get()
points[0] = [1, 2, 0]
state.points.set(points)
```

Manim Stateflow snapshots common mutable values like arrays, lists, tuples, and dicts. For custom objects, choose your own safe pattern: immutable objects, copy/replace methods, or constructing a new object before `.set(...)`.

## Expecting Manim Stateflow To Replace Manim

Manim Stateflow does not draw, interpolate, or render. Manim still does those things. Manim Stateflow only tracks dependencies and decides when Manim methods or constructors should be called again.

## Forgetting That Object-To-Object Wiring Needs Motion

If an anchor never changes, object-to-object wiring runs once and then has nothing new to react to.

```python
# Useful when dot moves.
label.d.next_to(dot, UP)
```

## Dependency Snapshot Debugging

Use dependency inspection when a scene updates in a surprising order.

```python
from manim_stateflow import runtime_snapshot

snapshot = runtime_snapshot(self.runtime)
print(snapshot)
```

`runtime_snapshot(...)` returns plain data:

- value nodes
- computed nodes
- renderers
- effects
- mobjects
- dependency edges
- object-anchor edges

For public scenes, prefer explaining the relationship with normal Manim
objects, `d.call(...)`, and `.d.apply(...)` instead of introducing another
special visualization helper.

## Runtime Counters

Every runtime tracks lightweight counters:

- `flushes`
- `nodes`
- `renderers`
- `effects`
- `rebuilds`
- `patches`

Use `snapshot_stats()` when you want a measurement window for one section of a scene:

```python
self.runtime.snapshot_stats()
self.play(x.animate_to(3), run_time=2)
stats = self.runtime.snapshot_stats()
print(stats)
```

Calling `snapshot_stats()` returns the current counters and resets them.
