Contagion — Contact-Based Outbreak Engine

Contagion — Contact-Based Outbreak Engine

A configurable infection engine for Paper: spreads by proximity, incubates silently, escalates through symptom stages, and ends in transformation — with quarantine zones and a craftable antidote.

27 downloads 0 followers

Contagion

Contagion turns your server into an outbreak scenario. An infection spreads from player to player by proximity, incubates silently, escalates through configurable symptom stages, and finally turns its host. Players fight back with quarantine zones and a craftable antidote.

Everything — timings, symptoms, potion effects, chances, messages and the recipe — is driven by config.yml. No other plugins and no external services are required.

HEALTHY ──infected──▶ INCUBATING ──▶ STAGE 1 ──▶ STAGE 2 ──▶ … ──▶ STAGE N ──▶ TURNED
   ▲                                                                              │
   └──────────────── antidote / /cg cure  (+ immunity window) ────────────────────┘

✨ Features

  • 🦠 Proximity transmission — every scan interval, contagious players look for healthy players inside a radius. The chance is base-chance × stage multiplier × distance falloff, with optional line-of-sight requirement.
  • ⏳ Silent incubation — a symptom-free window in which the player can already be a carrier, so outbreaks start before anyone notices.
  • 🤒 Symptom stages — any number of stages, each with its own duration, potion effects, chat message and contagiousness multiplier.
  • 🧟 Transformation — the terminal state: permanent heavy effects, maximum contagiousness, glowing, and by default not curable by the antidote.
  • 🏥 Quarantine zones — cylindrical zones with optional vertical limits. Flags block transmission inside and push infected players back at the border.
  • 🧪 Craftable antidote — a shaped recipe you define. The item is identified by a persistent data tag, so renaming it in an anvil keeps it working and a look-alike does not.
  • 📊 Action bar HUD — infected players see their current stage and the countdown to the next one.
  • 💾 Offline-aware progression — progression is timestamp based, so a player who logs out mid-stage returns with the correct remaining time, having advanced stages while away.
  • 🔌 Developer API — ContagionInfectEvent (cancellable), ContagionStageChangeEvent, ContagionCureEvent.

The plugin uses only stable Bukkit/Paper and Adventure API — no NMS and no reflection into server internals.

🎮 Commands

Root command: /contagion, alias /cg. Every argument is tab-completed (player names, stage ids, zone names, flag names).

Command Description Permission
/cg status [player] State, stage, time remaining and immunity contagion.status
/cg infect <player> [stage] Infect a player; without [stage] they start in incubation contagion.admin
/cg cure <player> Full cure plus the configured immunity window contagion.admin
/cg outbreak start [count] Pick random healthy online players as patient zero contagion.admin
/cg outbreak stop Cure everyone and end the outbreak contagion.admin
/cg zone add <name> <radius> [flag=value…] Create a zone centred on your position contagion.admin
/cg zone remove <name> Delete a zone contagion.admin
/cg zone list List zones with their flags contagion.admin
/cg zone flag <name> <flag> <true|false> Toggle a zone flag contagion.admin
/cg reload Reload config.yml + zones.yml and re-register the recipe contagion.admin

/cg infect accepts a stage id (mild), a 1-based number (2) or turned. /cg zone add also accepts y-min=<value> and y-max=<value>:

/cg zone add hospital 24 deny-infected-entry=true y-min=50 y-max=90

Permissions

Node Default Grants
contagion.status everyone /cg status for yourself
contagion.status.others op /cg status <other player>
contagion.admin op all administrative subcommands

⚙️ Configuration

All colour codes use & (and &#RRGGBB for hex).

transmission:
  enabled: true
  check-interval-ticks: 40      # 20 ticks = 1 second
  radius: 4.0                   # blocks
  base-chance: 0.15             # per scan (0.0-1.0)
  distance-falloff: true        # chance *= (1 - distance / radius)
  require-line-of-sight: false
  contagious-during-incubation: true
  ignore-same-team: false
  ignored-gamemodes: [CREATIVE, SPECTATOR]
  ignored-worlds: []

incubation:
  duration-seconds: 180
  notify-on-symptom-start: true

stages:                          # ordered; add or remove entries freely
  - id: mild
    duration-seconds: 300
    contagious-multiplier: 1.0
    message: "&7Your throat feels sore..."
    effects:
      - "SLOWNESS:0:ambient"     # TYPE:AMPLIFIER[:ambient] - amplifier 0 = level I
  - id: moderate
    duration-seconds: 300
    contagious-multiplier: 1.5
    message: "&eA fever is setting in."
    effects: ["SLOWNESS:0", "WEAKNESS:0", "HUNGER:0"]
  - id: severe
    duration-seconds: 240
    contagious-multiplier: 2.0
    message: "&cYour vision is fading!"
    effects: ["SLOWNESS:1", "WEAKNESS:1", "BLINDNESS:0:ambient", "MINING_FATIGUE:0"]

turned:
  enabled: true                  # if false, the last stage simply never ends
  contagious-multiplier: 3.0
  curable-by-antidote: false
  glowing: true
  effects: ["SLOWNESS:1", "WEAKNESS:2", "STRENGTH:0", "HEALTH_BOOST:1"]
  broadcast: "&4&l{player} has turned!"

cure:
  immunity-seconds: 300          # 0 disables immunity
  clear-effects: true
  message: "&aThe infection has been cleared from your blood."

antidote:
  enabled: true
  item:
    material: POTION             # must be consumable
    name: "&bAntidote"
    lore: ["&7Clears the infection."]
    custom-model-data: 7301
    potion-color: "#2FD0C4"
  recipe:                        # shaped, up to 3x3, spaces are empty slots
    shape: ["  G", " NF", "B  "]
    ingredients:
      G: GHAST_TEAR
      N: NETHER_WART
      F: FERMENTED_SPIDER_EYE
      B: GLASS_BOTTLE

outbreak:
  auto-start-on-boot: false
  patient-zero-count: 1
  broadcast-on-infect: false

death:
  cure-on-death: false

hud:
  action-bar: true
  format: "&cInfection: &f{stage} &8| &7{remaining}"

Effect types are resolved from the server registry by name, so both modern (SLOWNESS, MINING_FATIGUE) and legacy (SLOW, SLOW_DIGGING) spellings work. An unknown effect is logged and skipped instead of breaking the stage. Only effects Contagion applied are ever removed — potions the player drank themselves are left alone.

Zones (zones.yml)

Written by the commands, but editable by hand:

zones:
  hospital:
    world: world
    x: 120.5
    y: 64.0
    z: -340.5
    radius: 24.0
    y-min: 50        # optional; without it the cylinder is vertically unbounded
    y-max: 90
    flags:
      block-transmission: true
      deny-infected-entry: true

📦 Requirements

Server Paper 1.21 – 1.21.11 (or a Paper fork)
Java 21+
Dependencies none

🚀 Installation

  1. Download the Contagion jar and drop it into your server's plugins/ folder.
  2. Start the server once — plugins/Contagion/config.yml is generated.
  3. Edit the config to taste and run /cg reload (no restart needed).

Player states are stored in a local SQLite database. On first start the SQLite JDBC driver is downloaded by Paper's library loader; if that download is unavailable on a fully offline server, Contagion logs a warning and falls back to a YAML data file.

Version Minecraft Loader Download

Contagion — Contact-Based Outbreak Engine 1.0.0

1.0.0

1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11
paper, purpur
Download