1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
## Hazards
A **hazard** is an environmental threat attached to a room — a sandstorm, solar
radiation, falling rocks, toxic spores. It rolls an "attack" against everyone in
the room every few ticks using the **same combat formulas as a mob**: the hazard
supplies the accuracy and max hit, and the player defends with their Defense
level plus the equipment defense bonus selected by the hazard's attack type. No
new combat math, no special gear — your existing armour and Defense skill are
what keep you alive.
Hazards are **shared, ID-referenced definitions** (like drop tables and modules):
define a hazard once in `data/hazards/<id>.yaml`, then reference it from any number
of rooms with `hazard: <id>` (see `rooms.md`). This makes one hazard reusable
across a whole area and lets a future `examine` command resolve it by name.
**The filename is the ID** (`solar_radiation.yaml` → reference it as `hazard: solar_radiation`); the loader derives it from the filename. Do not put an `id:` field in the file — it is ignored.
```yaml
name: scorching solar radiation
description: "Unfiltered sunlight pours through a gap in the dome, burning exposed skin."
attack_type: science # stab/slash/crush/ranged/science — picks player defense + protect tech
attack: 40 # accuracy roll level
attack_bonus: 0 # equipment-equivalent accuracy bonus
max_hit: 6 # maximum damage per hit
speed: 5 # ticks between hazard rolls
warn_message: "The dome shielding fails here — raw solar radiation pours in."
hit_message: "Solar radiation sears you for %d damage." # optional single %d for the damage
miss_message: "You shield your eyes and weather a wave of solar glare."
required_item: "" # optional: an equipped item that NEGATES the hazard entirely
```
### Fields
| Field | Description |
|---|---|
| `name` | Display name used in warnings and default messages |
| `description` | Flavour text (for a future `examine`) |
| `attack_type` | `stab`/`slash`/`crush`/`ranged`/`science` — selects which player defense bonus applies and which protection tech reduces the damage (empty = `crush`) |
| `attack` | Hazard accuracy level |
| `attack_bonus` | Equipment-equivalent accuracy bonus |
| `max_hit` | Maximum damage per hit |
| `speed` | Ticks between hazard rolls (default 5 if ≤ 0) |
| `warn_message` | Shown when warning the player about the area |
| `hit_message` | Message on a hit; include a single `%d` to show the damage |
| `miss_message` | Message on a miss |
| `required_item` | If set and equipped, the hazard is fully negated for that player |
### How it behaves
- **Applies to everyone in the room, always** — idle, passing through, working a task,
or fighting a mob. Strong incentive to work fast, take cover, or leave.
- **Tech protection applies automatically.** Because the hazard has an attack type, the
matching protection tech reduces its damage: Kinetic Barrier (melee types),
Projectile Screen (`ranged`), Neural Firewall (`science`).
- **Safespots block all hazard damage.** A hidden player behind a safespot object takes
no hazard damage, regardless of hazard type. Note that doing a *melee* attack/work step
forces you out of cover — so ranged/science work lets you stay sheltered, melee does not.
- **Right gear negates it.** If `required_item` is set and equipped, the hazard is skipped
for that player entirely. The item must exist (validated at startup).
- **Hazards never interrupt movement.** Unlike a mob hit (which aborts a flee with
"Can't escape!"), a hazard hit does not touch your walk — you can keep moving out of
the danger zone while taking hits.
### Entry warning
Players walking from a **safe** room into a **hazardous** one get a `[Y/n]` confirmation
(pressing return defaults to yes; anything other than empty/`y`/`yes` cancels). Moving
between two hazardous rooms does not re-prompt. Players can disable the prompt with the
account option `danger_warning` (`option danger_warning false`).
### Examine (forward-compatible)
Because the hazard is a shared def referenced by ID, a future `examine sandstorm` can
resolve the current room's `hazard` ID, load the def, and render its attack type, accuracy,
max hit and description — no hidden objects required.
|