# `periphemu` — CraftOS-PC Peripheral Emulation

In-repo reference for the `periphemu` global exposed by [CraftOS-PC](https://www.craftos-pc.cc/). It does **not** exist in CC:Tweaked in-game — always guard usage with `if periphemu then`.

Upstream: <https://www.craftos-pc.cc/docs/periphemu>. See also the [CraftOS-PC glossary](craftos_pc_glossary.md) and [ADR-0005](adrs/adr-0005-craftos-pc-harness-and-probes.md) (why CraftOS-PC is our local harness, and why our startup attaches only a modem).

## Usage in this repo

`startup/boot.lua` attaches a single top modem when running under CraftOS-PC:

```lua
if periphemu then
  periphemu.create('top', 'modem');
end
```

That is the only `periphemu` call in the codebase. In-game (`periphemu == nil`) the block is a no-op. Locally a top modem is enough to boot the router, `ping-server`, and clients on the same VM.

To exercise cross-computer behavior locally, spawn extra peers ad-hoc from the shell:

```
periphemu create 10 computer    # spawn router VM (id 10)
periphemu create 1 computer     # spawn a client VM
```

Each call opens a new CraftOS-PC window (GUI mode). Keep this out of `startup/boot.lua` — persistent emulated peers clutter the desktop and leave stale state under `~/Library/Application Support/CraftOS-PC/computer/<id>/`.

## API

### `periphemu.create(side, type[, arg])` → `boolean`

Attaches a peripheral. Returns `true` on success, `false` if `side` is already occupied.

- `side` (string | number) — string for directional sides (`"top"`, `"left"`, …) or arbitrary names (`"modem_4"`); a number to attach a `computer` peripheral by id.
- `type` (string) — see types below.
- `arg` (optional) — type-specific, see table below.

### `periphemu.remove(side)` → `boolean`

Detaches the peripheral on `side`. Returns `false` if nothing is attached.

### `periphemu.names()` → `string[]`

Returns the list of peripheral type identifiers this CraftOS-PC build accepts as the `type` argument to `create`.

## Peripheral types

| Type           | Third arg            | Notes                                                                |
| -------------- | -------------------- | -------------------------------------------------------------------- |
| `modem`        | network id (number)  | Default network if omitted. Used to isolate modem networks.          |
| `computer`     | —                    | `side` is the computer id (number). Spawns a new VM window.          |
| `drive`        | mount path / `record:` / `treasure:` / `computer:<id>` | Initial mounted disk.            |
| `monitor`      | —                    | Size is set via `monitor.setTextScale` after attach.                 |
| `printer`      | output PDF path      | Required. Receives printed pages as PDF.                             |
| `speaker`      | —                    | See caveat below about `playAudio` vs CC:T.                          |
| `debugger`     | —                    | Attaches the CraftOS-PC debugger; see upstream debugger docs.        |
| `debug_adapter`| —                    | DAP front-end peripheral.                                            |
| `chest`        | `true`/`false`       | `true` = double chest. Also accepts `minecraft:chest`.               |
| `energy`       | max energy (number)  | Optional further args declare supported energy type strings.         |
| `tank`         | tank count (number)  | Optional further args set tank size and accepted fluid type strings. |

Call `periphemu.names()` from a CraftOS-PC shell to confirm what the current build supports — the upstream list grows occasionally.

## Caveats

- **CC:T has no `periphemu`.** Always guard with `if periphemu then`. [AGENTS.md](./../AGENTS.md) and [ADR-0005](adrs/adr-0005-craftos-pc-harness-and-probes.md) treat that guard as mandatory.
- **Speaker `playAudio` differs from CC:T** unless [standards mode](https://www.craftos-pc.cc/docs/standards) is on — CraftOS-PC queues audio without ever returning `false`.
- **Modem network id** segregates emulated networks. Two modems with different ids will not see each other; useful for testing modem-based code against a sealed network.
- **Persisted per-computer state** lives at `~/Library/Application Support/CraftOS-PC/computer/<id>/` and `config/<id>.json` (labels stored base64-encoded). Spawning a new id leaves that state behind across sessions.
