<!-- Source: https://docs.biosimulant.com/how-to/library/use-bioworld -->

# How to Use a BioWorld

Use `BioWorld` when you want to register modules, validate connections, run the graph for a duration, and collect visuals or snapshots afterward.

## Create a world

```python

world = biosim.BioWorld(communication_step=0.1)
```

## Add modules with WiringBuilder

```python
from src.vision_demo import Eye, LGN, SuperiorColliculus

builder = biosim.WiringBuilder(world)
builder.add("eye", Eye())
builder.add("lgn", LGN())
builder.add("sc", SuperiorColliculus())
```

## Wire connections

```python
builder.connect("eye.visual_stream", ["lgn.retina"])
builder.connect("lgn.thalamus", ["sc.vision"])
builder.apply()
```

**Warning:**

  Always pass destinations as a list such as `["target.port"]`.

## Run the simulation

```python
world.run(duration=10.0)
```

The world advances all modules across the same communication windows. The legacy external tick parameter is not part of the current runtime API.

## Propagate final outputs

Downstream modules only observe outputs after those outputs are committed at a
communication boundary. If a report, export, or visualisation module should
consume outputs produced at the final boundary, settle the graph after the run:

```python
world.run(duration=10.0)
world.settle(steps=1)
```

Settling calls downstream modules with `advance_window(current_time, current_time)`
and does not advance simulated time.

## Listen to events

```python
from biosimulant import WorldEvent

def listener(event, payload):
    if event == WorldEvent.STEP:
        print(f"t={payload['t']:.3f}")
    elif event == WorldEvent.FINISHED:
        print("done")

world.on(listener)
world.run(duration=1.0)
world.off(listener)
```

## Collect visuals

```python
visuals = world.collect_visuals()
for entry in visuals:
    print(entry["module"], len(entry["visuals"]))
```

## Pause, resume, and stop

```python
world.request_pause()
world.request_resume()
world.request_stop()
```

These are cooperative and take effect at communication boundaries.

## Repeatable reruns

There is no kernel-level reset method in the current world API. Use snapshots or build a fresh world.

```python
world.setup()
baseline = world.snapshot()

world.run(duration=5.0)
world.restore(baseline)
world.run(duration=5.0)
```

If you are sweeping constructor parameters rather than just simulation state, prefer a small `build_world()` factory that creates a fresh world per run.

## Next steps

- [Create a BioModule](/how-to/library/create-biomodule)
- [Serve a Local Lab](/how-to/library/serve-local-lab)
- [BioWorld API Reference](/references/library/bioworld-api)
