Skip to content

History / Combat System

Revisions

  • Round 48: SRD items/chargen/plumbing — the last engine wave of #505 (#512/#514-#519/#548) Eight primitives closing the SRD engine register. Two stale claims corrected (chargen array/roll "not implemented"; the Wearer "affix sums" only). - Pack-Entity-Reference: chargen array_assign + roll step kinds now implemented (roll is server-authoritative, forged client values ignored); wearable gains static `modifiers` (#514) and `equip_affects` (#515, on-equip magic + OnHit procs, item-keyed derived state). - Abilities-and-Effects: worn static modifiers compose through the Wearer modSource (mulMod was hardwired to identity); teleport/push same-zone relocation ops (#516, forced-move harm-gated, same-zone structural, instance- entrance refused); the polymorphic dice_num + one-of conflict rejection (#517) and the `fixed` op flag (#515). - Combat-System: item procs = an equip-affect subscribing OnHit, with the OnHit self-loop guard + `fixed` rider; the prevents:move WALK fix (#548, a confirmed bug — attemptMove never consulted prevents:move, voiding the whole immobilize system). - Builder-Commands + Player-Reference: carrying capacity (carry_capacity derived attribute, enforced at acquisition, get-all-takes-what-fits); the `credits` verb (#519); rest short/long. - Pack-MUD-Settings: manifest license/attribution (accumulate per pack; a later pack can't erase an earlier notice). - Pack-Lua-Hooks: OnRest now live + OnShortRest/OnLongRest (distinct kinds, NOT the mag argument which would double a handler's heal). - Pack-Lua-Scripting: h:move now harm-gates forcing another player (was an ungated grief hole) — the safe co-move primitive for mounts/grapple-drag. Store field-drop trap again: #519 pack license needed BOTH fold loops (mergePacks file->Pack AND Merge Pack->LoadedContent) plus the pack_meta round-trip; #514/#515 ride existing wholesale-marshaled bodies.

    @yfronto yfronto committed Jul 26, 2026
  • Round 47: SRD engine primitives batch 2 (#536/#539/#541-#547) Nine composable SRD primitives, threaded into the combat/effect/schema pages. - Combat-System: #547 OnEnterCombat (the initiative checkpoint, seeded-rng, per entry); #544 crit dice-doubling (crit_dice doubles the dice term vs crit_mult the whole roll; reaches swing + check-band crits; set-not-multiply, no leak); #543 heterogeneous multiattack routine (replaces attacks, shares one to_hit, same dealDamage path per swing, capped); #536 absorb buffer in the funnel (after the OnDamageTaken reaction, before the vital; instance-set capacity, no max_attr, set_resource op). - Abilities-and-Effects: #541 highest-wins stacking + graded rungs, and the HIGH harm-classifier fix (affectIsDetrimental / respawn-strip now fold in RUNG modifiers/prevents — the 6th blind spot; decrement_rung gated cross-player); #545 duration_kind: indefinite + level/dispel-by-level (indefinite room-field lease kept finite); #546 prevents_source source-relative CC (a targeting gate, not a can't-harm firewall; fail-open across load); #539 concentration single slot (the cross-zone single-writer fix: expireConcentration gated on holder.zone==z + break-before-detach on transfer/quit); #542 richer if predicate (comparators + formula RHS; indeterminate operand fails to FALSE, not 0; unknown comparator rejected at parse); the set_resource / increment_rung / decrement_rung ops; the absorb resource fields. - Pack-Entity-Reference: resource absorb/fronts; affect level/concentration/ duration_kind/rungs/prevents_source + stacking: highest; combat_profile multiattack. - Pack-Lua-Hooks: OnEnterCombat + OnAffectBlocked added to the live event enum. Store field-drop trap hit TWICE this round (absorb/fronts on resource_defs; multiattack on combat_profiles) — both round-tripped through Postgres by the reflection test; noted as JSONB-body fields needing no migration.

    @yfronto yfronto committed Jul 26, 2026
  • Round 46: SRD engine primitives (#511/#513/#537/#538/#540/#535 + #557/#562) The capstone SRD-primitive round. Six composable primitives plus a fold-clamp fix and the check subject selector, threaded into the effect/combat pages. - Check pipeline (Combat-System + the check op in Abilities-and-Effects): * #511 boon/bane — a net-sign channel selecting among boon_dice/bane_dice/ neutral dice (NOT keep-high synthesis, which inverts the demo's roll-UNDER ladder); 5e cancellation falls out of sign-netting; composes through ordinary attribute modifiers, no new state/DTO. * #513 band `when` — a forcing fifth band axis (auto-crit / auto-fail-save) with no engine crit/fail vocabulary; truthiness is non-zero AND finite (NaN != 0 in Go); replaces an affine sentinel hack that broke on stacking. * #562 subject selector — subject: target is the saving-throw idiom (target rolls, narrates to the saver, OnCheck subject = saver, caster rides as other); does NOT rebind band-op target vocabulary (authoring trap noted). - Damage/death (Combat-System): * #537 per-target damage_taken_mult — an affect-granted map, product-composed like prevents (absence = identity-1 structurally), consulted after soak; per-FACTOR normalization at composition closes the "two {fire:-3} buffs compose to a 9x amplifier" cross-player harm-gate bypass. * #535 downed/dying — a third onPoolDepleted disposition: an active suspends_death affect holds the victim at 0 (no die/corpse/respawn); regen pauses, auto-swings stop (swingGatesPass now refuses a prevents:[act] attacker); the resolution is a content affect. die() keeps its one call site. - Reactions/affects (Combat-System + Abilities-and-Effects): * #540 incapacitation gate — canReact = canAct && !preventsTag("react") on every reaction checkpoint; gates reactions only, never the plain bus (passive on_event still fires while stunned). * #538 incoming-affect trait immunity — grants_immunity vetoes an incoming affect BEFORE attach on {ref}u{category}u tags; a separate multiset from prevents; the veto sits after the reattach branch so a load is never vetoed. * #557 attribute-fold clamp — the (base+flat)*mul fold saturates (+/-Inf -> +/-1e12, NaN -> pre-mod base); screen runs BEFORE min/max since NaN passes every range; the reachable consumers read attr() directly (resourceMax -> an unkillable bottomless pool, the OPPOSITE of the panel's claimed one-shot). - Pack-Entity-Reference affect schema: tags, grants_immunity, suspends_death, damage_taken_mult rows + the conventional act/react/cast prevents tags.

    @yfronto yfronto committed Jul 24, 2026
  • Round 43: the three review-bundle follow-ups (#397/#399/#401) Refinements to systems already documented (spawn-protection, comms history, the audit trail); each thread lands in its existing home. - Abilities-and-Effects (#397): the sourceless-ambient exemption. A room field with no applier ticks at actor==target, which guardHarmful treats as an exempt self-effect, so it kept damaging a just-respawned occupant. A sourcelessAmbient flag fires ENFORCEMENT even at actor==target while CANCELLATION stays actor!=target-gated, so the field never drops the occupant's own shield; threaded into all four such harm sites. - Combat-System (#397): a swing at a spawn-protected target is short-circuited BEFORE the pipeline, not zeroed inside it. Narration ran before dealDamage, so the target saw a phantom hit each round; the pre-gate also drops a still- protected attacker's own shield. - Builder-Commands + Pack-Entity-Reference (#401): a sent tell is recorded at the CONFIRMED-echo point, so no phantom entry on a resolve-miss or publish-failure; history channel appends a shard-local partial-view footer on a multi-shard fleet; the channel history ring is reaped on channel removal, and the schema now warns that loosening hear_access retroactively exposes buffered lines. - Persistence-and-Durability (#399): the async auditor now coalesces up to 64 events into one pgx.Batch round-trip, with per-row fallback under the same bounded ctx; newest-first reads order by at DESC, seq DESC for true insertion order incl. within a shared-now batch; and staff audit-by-name now folds in the target account tier_changed rows, scoped to the owning account.

    @yfronto yfronto committed Jul 24, 2026
  • Round 42: depletion hooks on any pool, damage-type pool routing, the depletion arithmetic Updates the builder-facing reference for #405/#406/#407: - resources: `vital` now means only "emptying this causes death"; every pool runs its own on_depleted. Documents the level-trigger and the two authoring rules it forces (make the hook idempotent; never reward from one), and the $depletion.overflow/.applied/.amount scalars with the carry-over idiom. - damage_types: target_resource, the three-tier routing precedence, why a capacity-less target is immune by construction (and how to use a 0-base capping attribute as an opt-in lever), and the never-retrofit rule. - Combat System: the same two corrections where it described the seam as vital-only and the routing as op-level-only.

    @MrG0rd0x MrG0rd0x committed Jul 23, 2026
  • Round 35 milestone: multi-vital support (#71) Corrects a now-stale claim: Abilities-and-Effects asserted "multi-vital is unsupported (only the lowest-ref pool damages and kills)". - Abilities-and-Effects: multiple independently-lethal vital pools, each with its own on_depleted; deal_damage routes via `resource` (empty = the new `primary` vital, so existing content is unchanged); `primary` replaces the implicit lowest-ref rule; max<=0 is natural immunity; non-vital pools are damageable but never lethal. - Combat-System: damage now subtracts from the ROUTED pool; documents the per-pool vitalDepleted predicate (def.vital && max>0 && cur<=0) and why the max>0 term is load-bearing (a zero-max pool would read as already-depleted and instantly kill); the death-generation guard is ordered BEFORE the pool-local cancel re-check so a cross-pool cascade yields exactly one die(). - Pack-Entity-Reference: vital row updated, new `primary` row (rides the resource JSONB body, no migration), per-pool on_depleted, and the LintVitalResources / LintDealDamageResources lints. - Pack-Lua-Scripting: h:damage gains `resource=` for the routed pool.

    @yfronto yfronto committed Jul 18, 2026
  • Round 34 milestone: spawn-protection window, audit trail, comms history - Combat-System + Abilities-and-Effects: the actor-agnostic post-respawn spawn-protection window shipped (#394) — updates the #318 "deferred" note. respawnPlayer opens a pulse-deadline protectedUntil; guardHarmful refuses harmful ops aimed at a protected player AHEAD of the !isPlayer no-op so a MOB attacker is covered (safe-room cannot be); drops when the player acts. - Persistence-and-Durability (new section) + Accounts-and-Auth-Internals: the append-only character_audit trail (#350) — world emits died/attr/track via an async per-shard auditor (saver twin, drains on shutdown), account emits create/tier_changed in-transaction; idempotent on (subject,kind,dedup_key) with a DURABLY-UNIQUE key (died = per-death UUID, not the transient deaths counter that collided across relogs); audit self-view scoped by stable pid, audit <name> staff-only. - Builder-Commands + Player-Reference: tells/replay session tell history (#349, structural pair-privacy, skips ignored authors, resets on relog) and history <channel> scrollback (#348, fetch-time canHear gate, shard-local partial view); Pack-Entity-Reference channel_defs.history row enriched.

    @yfronto yfronto committed Jul 18, 2026
  • Round 33 milestone: staff visibility pair + respawn hostile-affect strip - Pack-Entity-Reference: help_defs gains an optional per-topic min_rank; a gated topic is invisible in both the index and a direct lookup (falls through to "no help on ..." so existence never leaks), see_also is filtered per-viewer, and the gate fails open (a dropped field un-gates text, never a capability) (#351). - Combat-System: document the "no hostile effect survives respawn" invariant at the respawnPlayer chokepoint — whitelist inversion (provably-benign is closed/checkable, unknown ops fail toward stripping), hard removal with no on_expire hooks, and the tickOnce re-entrancy guard for a lethal DoT (#318). - Builder-Commands + Accounts-and-Auth-Internals + RPC-and-Protobuf + Trust-Tier-Model: promote/demote now have the wiz-command posture for non-staff (plain Huh?, no refusal, no account-service round-trip) via a manage_tiers visibility bit on IssueSessionAssertion; the service stays authoritative, the bit is defense-in-depth visibility only (#369).

    @yfronto yfronto committed Jul 17, 2026
  • Round 25: durable-zone login fix + engine-side notes for #69/#262/#266 The round self-documented #69 (Abilities), #262 and #266 (Sysadmin). Closing the engine-page gaps and the one undocumented item: - Persistence-and-Durability: NEW 'Where a returning player lands' — characters.zone_ref is the login routing key (#320). Documents the data-loss bug it fixed (an intra-shard walk + logout silently reset you to the home zone's start room), the link-dead reconnect side-fix, the room_ref warn, the checkpoint drift guard, and the remaining shard-not-zone placement gap. - Combat-System: the death generation (Living.deaths) + die() entry re-entrancy latch (an item dupe) + why position/location can't carry the 'did it die' signal (#69). - Scoped-Event-Bus: paced durable NAK redelivery + the tri-state ack decision (#266). - RPC-and-Protobuf: AdoptZone is signed on keyed shards (#262). - Edge-and-Protocol: the connect diagram binds the durable zone.

    @yfronto yfronto committed Jul 10, 2026
  • Engine Dev: abilities/effects, combat, loot/spawns/crafting - Abilities-and-Effects: substrate, effect-op vocabulary, 10-step lifecycle, the PvP gate + guardHarmful, tag-CC, affect runtime (stale-comment corrections) - Combat-System: round loop, swing pipeline, death checkpoint, reactions; honest gaps (lag logged-only, auto-swings ungated by prevents, dead formula seam) - Loot-Spawns-and-Crafting: resolver, quality/affixes, scheduled spawns, tracks/bundles/four modes, crafting + tier-bound salvage

    @yfronto yfronto committed Jul 9, 2026
  • Scaffold wiki + author About and Getting Started - 48-page skeleton across all audiences (flat files + grouped _Sidebar) - Every page carries an Audience + Status banner (Ready/Draft/Placeholder) - About: Overview, History of MUDs (Ready) - Getting Started: Getting-Started, Running-Locally, First-Admin-Setup, Content-Packs-Intro (Ready) — dev bypass, local GitHub OAuth, bootstrap admin, promote/demote, content-pack model, all grounded in code - SRD5/WoW/D6 pack pages are honest placeholders (packs not yet built)

    @yfronto yfronto committed Jul 9, 2026