Skills reference
MythicMobs-class declared skills — pure data, zero script calls on the hot path
Skills give a declared mob MythicMobs-style abilities: when X happens, with chance C and under conditions, apply mechanics M to targets T. They are Sulfur’s first intentional extension beyond vanilla gameplay.
Native implementation, not interop. Sulfur’s skill system is a from-scratch native API with MythicMobs feature parity as the checklist. No Bukkit/Java plugin is ever loaded or executed, and no YAML compatibility is pursued. The underlying subsystems a mechanic calls into (damage, effects) are the already-ported, jar-faithful vanilla paths — so skill damage respects vanilla armor, i-frames, and knock-on effects exactly.
Skills are even stronger than goals on the declare-once principle: a skill is captured as pure data at load — no Starlark callable is retained at all. The Go hot path interprets the declaration structs directly, so a skill-bearing mob burns zero Starlark calls per tick, idle or active.
Declaring skills
Skills attach to a mob declaration via the skills list of
declare_mob:
All four builtins (skill, mechanic, targeter, condition) validate everything at load:
unknown kinds, missing or forbidden arguments, out-of-range values, and — crucially —
capabilities. mechanic("damage") in a plugin whose manifest lacks skills.damage is a loud
load error (fail-closed), not a runtime denial.
skill(...)
Triggers
targeter(kind, r=?)
mechanic(kind, ...)
Passing an argument that doesn’t belong to the kind (e.g. amount on an effect mechanic) is a
load error — arguments are never silently dead.
Implemented effect ids
The effect mechanic accepts these ids, with or without the minecraft: prefix:
poison, regeneration, speed, slowness, weakness, haste, resistance, jump_boost,
strength, wither, fire_resistance, water_breathing, instant_health, instant_damage.
An effect outside this set is a load error — never a silently-inert buff.
condition(kind, value)
Runtime semantics
Execution order per skill fire: conditions → chance gate → targeter resolve → mechanics in declared order, per target.
- Per-mob state is just the timer countdowns and a re-entrancy guard; the declaration itself is shared immutable data across all spawned mobs of the type.
- Re-entrancy is dropped: a mechanic whose side effect re-triggers the same mob (e.g. a
self-damage mechanic firing the mob’s own
damagedtrigger) is suppressed while the skill executes — no cascades. - RNG discipline: the only RNG draw is the optional
chancegate, on the caster’s own seeded per-entity stream. Vanilla mobs declare no skills, so no vanilla RNG stream is ever perturbed.
Complete example: zapmob
The zapmob test plugin declares a pig-based mob with a periodic AoE zap and a retaliation hit:
For what’s coming next (summon/heal/throw/teleport mechanics, meta-skills, cooldowns, more triggers and conditions, and ModelEngine-class models), see the Roadmap.

