## 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/.yaml`, then reference it from any number of rooms with `hazard: ` (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 pounds down through a gap in the atmospheric dome." combat: attack_types: [science] # list: exactly one melee (stab/slash/crush) + optional ranged/science stats: attack: 40 # accuracy level strength: 0 ranged: 0 science: 0 speed: 5 # ticks between hazard rolls max_melee_hit: 0 max_ranged_hit: 0 max_science_hit: 6 # maximum science damage per hit bonuses: attack_bonus: 0 # equipment-equivalent accuracy bonus strength_bonus: 0 ranged_bonus: 0 ranged_strength_bonus: 0 science_bonus: 0 science_percent_bonus: 0 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 ``` ### Combat Fields The `combat:` block mirrors a mob's combat block exactly — same stats, same bonuses, same per-type max hits. Hazards have **no defense stats** because they are never attacked — they only attack the player. | Field | Description | |---|---| | `combat.attack_types` | List of attack types. At least one melee (`stab`/`slash`/`crush`) plus optional `ranged`/`science`. The first melee type is used as the primary attack type. | | `combat.stats.attack` | Attack level (base accuracy) | | `combat.stats.strength` | Strength level (melee max-hit base) | | `combat.stats.ranged` | Ranged level (ranged accuracy base) | | `combat.stats.science` | Science level (science accuracy base) | | `combat.stats.speed` | Ticks between hazard rolls (default 5) | | `combat.stats.max_melee_hit` | Maximum melee damage per hit | | `combat.stats.max_ranged_hit` | Maximum ranged damage per hit | | `combat.stats.max_science_hit` | Maximum science damage per hit (a set value — not level-derived) | #### Bonuses (`combat.stats.bonuses:`) | Field | Description | |---|---| | `attack_bonus` | Equipment-equivalent attack bonus (added to accuracy roll) | | `strength_bonus` | Equipment-equivalent strength bonus (added to melee max hit) | | `science_bonus` | Equipment-equivalent science attack bonus | | `science_percent_bonus` | Percent boost to science damage (applied to `max_science_hit`) | | `ranged_bonus` | Equipment-equivalent ranged attack bonus | | `ranged_strength_bonus` | Equipment-equivalent ranged strength bonus (added to ranged max hit) | ### General Fields | Field | Description | |---|---| | `name` | Display name used in warnings and default messages | | `description` | Flavour text (for a future `examine`) | | `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.