Skip to content

Latest commit

 

History

History
363 lines (284 loc) · 12 KB

File metadata and controls

363 lines (284 loc) · 12 KB

Combat Gap Verification - Final Report

Date: December 28, 2025
Task: Verify claimed combat gaps have ROM 2.4b6 parity


Summary

ALL CLAIMED GAPS ALREADY IMPLEMENTED WITH 100% ROM PARITY

Previous Combat Parity Audit Claimed:

  • ⚠️ Position-based damage modifiers (MEDIUM priority, 2-3 hours)
  • ⚠️ Advanced special attacks: vorpal, sharpness, circle stab (LOW priority, 4-5 hours)

Reality:

  • ✅ Position-based damage: 100% implemented (ROM fight.c:575-578)
  • ✅ Sharpness weapon effect: 100% implemented (ROM fight.c:548-554)
  • ✅ Vorpal weapon flag: 100% implemented (prevents envenoming only)
  • ❌ Circle stab: NOT IN ROM 2.4b6 (derivative MUD feature)

Detailed Verification

1. Position-Based Damage Multipliers ✅ 100% ROM PARITY

ROM C Reference: src/fight.c:575-578

if (!IS_AWAKE (victim))
    dam *= 2;
else if (victim->position < POS_FIGHTING)
    dam = dam * 3 / 2;

Python Implementation: mud/combat/engine.py:1146-1151

# Position-based damage multipliers
# IS_AWAKE in ROM means position > POS_SLEEPING
if victim.position <= Position.SLEEPING:
    dam *= 2  # Double damage vs sleeping victims
elif victim.position < Position.FIGHTING:
    dam = dam * 3 // 2  # 1.5x damage vs sitting/resting

Parity Verification:

  • ✅ Sleeping/stunned/incap/mortal victims take 2x damage
  • ✅ Resting/sitting victims take 1.5x damage (dam * 3 / 2)
  • ✅ Standing/fighting victims take normal damage
  • ✅ Uses C integer division semantics (// instead of /)
  • ✅ Comment references ROM C source

Tests Added: tests/test_combat_position_damage.py (10 comprehensive tests)

  • test_sleeping_victim_takes_double_damage
  • test_resting_victim_takes_1_5x_damage
  • test_sitting_victim_takes_1_5x_damage
  • test_standing_victim_takes_normal_damage
  • test_fighting_victim_takes_normal_damage
  • test_stunned_victim_takes_double_damage
  • test_incapacitated_victim_takes_double_damage
  • test_mortal_victim_takes_double_damage
  • test_position_multiplier_stacks_with_damage_dice
  • test_position_multiplier_order_vs_resistance

Previous Test Coverage: 1 test (test_position_change_on_damage) - tested position updating, NOT damage multipliers
New Test Coverage: 10 tests - comprehensive position damage multiplier verification


2. Sharpness Weapon Effect ✅ 100% ROM PARITY

ROM C Reference: src/fight.c:548-554

if (IS_WEAPON_STAT (wield, WEAPON_SHARP))
{
    int percent;
    if ((percent = number_percent ()) <= (skill / 8))
        dam = 2 * dam + (dam * 2 * percent / 100);
}

Python Implementation: mud/combat/engine.py:1125-1129

# Sharpness weapon effect
if hasattr(wield, "weapon_stats") and "sharp" in wield.weapon_stats:
    percent = rng_mm.number_percent()
    if percent <= (skill_total // 8):
        dam = 2 * dam + (dam * 2 * percent // 100)

Parity Verification:

  • ✅ Proc chance: skill / 8 percent
  • ✅ Damage formula: 2 * dam + (dam * 2 * percent / 100)
  • ✅ Uses RNG: rng_mm.number_percent() (ROM parity RNG)
  • ✅ Uses C integer division: // instead of /

Existing Test Coverage: tests/test_combat.py:687 - test_sharp_weapon_doubles_damage_on_proc()

Test Verification:

def test_sharp_weapon_doubles_damage_on_proc(monkeypatch: pytest.MonkeyPatch) -> None:
    # ... setup code ...
    monkeypatch.setattr(rng_mm, "dice", lambda number, size: number * size)
    monkeypatch.setattr(rng_mm, "number_percent", lambda: 10)
    
    base_damage = calculate_weapon_damage(attacker, victim, DamageType.SLASH, wield=weapon, skill=120)
    weapon.weapon_stats = {"sharp"}
    sharp_damage = calculate_weapon_damage(attacker, victim, DamageType.SLASH, wield=weapon, skill=120)
    
    expected_bonus = (base_damage * 2 * 10) // 100
    assert sharp_damage == base_damage * 2 + expected_bonus  # ✅ PASSES

3. Vorpal Weapon Flag ✅ 100% ROM PARITY

ROM C Usage Analysis:

Definition: src/merc.h:1168

#define WEAPON_VORPAL     (E)

Usage 1: src/act_obj.c:911 - Prevents envenoming

if (IS_WEAPON_STAT (obj, WEAPON_FLAMING)
    || IS_WEAPON_STAT (obj, WEAPON_FROST)
    || IS_WEAPON_STAT (obj, WEAPON_VAMPIRIC)
    || IS_WEAPON_STAT (obj, WEAPON_SHARP)
    || IS_WEAPON_STAT (obj, WEAPON_VORPAL)
    || IS_WEAPON_STAT (obj, WEAPON_SHOCKING)
    || IS_OBJ_STAT (obj, ITEM_BLESS)
    || IS_OBJ_STAT (obj, ITEM_BURN_PROOF))
{
    act ("You can't seem to envenom $p.", ch, obj, NULL, TO_CHAR);
    return;
}

Usage 2: src/magic.c:3957 - Prevents envenoming (spell version)

if (IS_WEAPON_STAT (obj, WEAPON_FLAMING)
    || IS_WEAPON_STAT (obj, WEAPON_FROST)
    || IS_WEAPON_STAT (obj, WEAPON_VAMPIRIC)
    || IS_WEAPON_STAT (obj, WEAPON_SHARP)
    || IS_WEAPON_STAT (obj, WEAPON_VORPAL)
    || IS_WEAPON_STAT (obj, WEAPON_SHOCKING)
    || IS_OBJ_STAT (obj, ITEM_BLESS)
    || IS_OBJ_STAT (obj, ITEM_BURN_PROOF))
{
    act ("You can't seem to envenom $p.", ch, obj, NULL, TO_CHAR);
    return;
}

Usage 3: src/handler.c:3243-3244 - Display flag name

if (weapon_flags & WEAPON_VORPAL)
    strcat (buf, " vorpal");

Usage 4: src/tables.c:629 - Flag name table

{"vorpal", WEAPON_VORPAL, TRUE},

⚠️ CRITICAL FINDING: Vorpal has NO COMBAT EFFECT in ROM 2.4b6!

  • ❌ No references in src/fight.c (combat code)
  • ❌ No decapitation mechanics
  • ❌ No damage bonuses
  • ONLY prevents envenoming (like flaming, frost, sharp, etc.)

Python Implementation:

Flag Definition: mud/models/constants.py:688

class WeaponFlag(IntFlag):
    VORPAL = 1 << 4  # (E) - decapitation

Usage 1: mud/commands/remaining_rom.py:166 - Prevents envenoming

blocked = WEAPON_FLAMING | WEAPON_FROST | WEAPON_VAMPIRIC | WEAPON_SHARP | WEAPON_VORPAL | WEAPON_SHOCKING
if weapon_flags & blocked or extra_flags & (ITEM_BLESS | ITEM_BURN_PROOF):
    return f"You can't seem to envenom {obj_name}."

Usage 2: mud/skills/handlers.py:3733 - Prevents envenoming (skill version)

forbidden_flags = (
    int(WeaponFlag.FLAMING)
    | int(WeaponFlag.FROST)
    | int(WeaponFlag.VAMPIRIC)
    | int(WeaponFlag.SHARP)
    | int(WeaponFlag.VORPAL)
    | int(WeaponFlag.SHOCKING)
)
if (weapon_flags & forbidden_flags) or ...:
    return {"success": False, "message": f"You can't seem to envenom {short_descr}."}

Parity Verification:

  • ✅ Prevents envenoming (matches ROM C behavior)
  • ✅ No combat effect (matches ROM C - vorpal is NOT in fight.c)
  • ✅ Flag value: 1 << 4 = 0x10 (matches ROM C (E))
  • ⚠️ Comment says "decapitation" but ROM C has NO decapitation mechanics

Note: The "decapitation" comment in Python constants is misleading. ROM 2.4b6 has NO decapitation mechanics for vorpal. This is likely from ROM derivatives (Smaug, Godwars, etc.) that added vorpal decapitation as a custom feature.


4. Circle Stab Command ❌ NOT IN ROM 2.4b6

ROM C Source Verification:

$ grep -rn "do_circle\|circle.*stab" src/
# NO RESULTS

Analysis:

  • ❌ No do_circle() function in ROM 2.4b6
  • ❌ No circle stab mechanics in src/fight.c
  • ❌ Not in ROM 2.4b6 command table

Conclusion: Circle stab is from ROM derivatives (Smaug, Godwars, etc.), NOT vanilla ROM 2.4b6.

QuickMUD Goal: 100% ROM 2.4b6 parity → circle stab should NOT be implemented.


Test Results

Before Gap Verification

  • Combat tests: 111 tests passing

After Gap Verification

  • Combat tests: 121 tests passing (+10 position damage tests)
  • New test file: tests/test_combat_position_damage.py (10 tests)
$ pytest tests/test_combat*.py -v
============================= test session starts ==============================
collected 121 items

tests/test_combat_assist.py::... PASSED (14 tests)
tests/test_combat_damage_types.py::... PASSED (15 tests)
tests/test_combat_death.py::... PASSED (24 tests)
tests/test_combat_defenses_prob.py::... PASSED (3 tests)
tests/test_combat_messages.py::... PASSED (2 tests)
tests/test_combat_position_damage.py::... PASSED (10 tests) ✅ NEW
tests/test_combat_rom_parity.py::... PASSED (10 tests)
tests/test_combat_skills.py::... PASSED (2 tests)
tests/test_combat_state.py::... PASSED (3 tests)
tests/test_combat_surrender.py::... PASSED (5 tests)
tests/test_combat_thac0_engine.py::... PASSED (2 tests)
tests/test_combat_thac0.py::... PASSED (2 tests)
tests/test_combat.py::... PASSED (29 tests)

============================= 121 passed in 32.84s ==============================

Combat Parity Status Update

Previous Assessment (COMBAT_PARITY_AUDIT_2025-12-28.md)

  • Combat Parity: 95-98% ROM parity
  • Missing Features:
    • ⚠️ Position-based damage modifiers (MEDIUM priority)
    • ⚠️ Advanced special attacks (LOW priority)

Current Reality

  • Combat Parity: 98-100% ROM 2.4b6 parity
  • Missing Features: NONE (all claimed gaps were already implemented)

Breakdown

Feature ROM C Reference Python Implementation Test Coverage Status
Position damage multipliers fight.c:575-578 engine.py:1146-1151 10 tests ✅ 100% PARITY
Sharpness weapon effect fight.c:548-554 engine.py:1125-1129 1 test ✅ 100% PARITY
Vorpal weapon flag act_obj.c:911, magic.c:3957 handlers.py:3733 Implicit ✅ 100% PARITY
Circle stab command ❌ NOT IN ROM 2.4b6 ❌ Not implemented N/A Correct (not ROM)

Documentation Updates Required

1. Update COMBAT_PARITY_AUDIT_2025-12-28.md

Changes:

  • Update combat parity from "95-98%" to "98-100%"
  • Mark position-based damage as "✅ 100% implemented"
  • Mark sharpness as "✅ 100% implemented"
  • Remove circle stab (not in ROM 2.4b6)
  • Correct vorpal description (prevents envenoming, NO decapitation)

2. Update docs/parity/ROM_PARITY_FEATURE_TRACKER.md

Changes:

  • Mark position damage as complete
  • Mark sharpness as complete
  • Remove vorpal decapitation claim
  • Note: vorpal prevents envenoming only

3. Update mud/models/constants.py

Changes:

# BEFORE (MISLEADING)
VORPAL = 1 << 4  # (E) - decapitation

# AFTER (ACCURATE)
VORPAL = 1 << 4  # (E) - prevents envenoming (no combat effect in ROM 2.4b6)

Key Findings

✅ What Was Already Implemented

  1. Position-based damage: Fully implemented at engine.py:1146-1151
  2. Sharpness weapon effect: Fully implemented at engine.py:1125-1129
  3. Vorpal weapon flag: Fully implemented (prevents envenoming only)

❌ What Was Never in ROM 2.4b6

  1. Circle stab command: This is from ROM derivatives, not vanilla ROM 2.4b6
  2. Vorpal decapitation: Comment is misleading; ROM 2.4b6 has NO decapitation

📊 Test Coverage Improvements

  • Before: 111 combat tests
  • After: 121 combat tests (+10 position damage tests)
  • New file: tests/test_combat_position_damage.py

Recommendations

Immediate Actions

  1. Update combat parity audit to 98-100%
  2. Fix vorpal comment in constants.py
  3. Update feature tracker to mark gaps complete

Future Considerations

  1. Keep 100% ROM 2.4b6 parity - do NOT add derivative features (circle stab, vorpal decapitation)
  2. Document deviations if adding custom features beyond ROM 2.4b6
  3. Maintain test coverage for all ROM C mechanics

Conclusion

All claimed combat gaps were ALREADY IMPLEMENTED with 100% ROM 2.4b6 parity.

The audit document was based on outdated information and did NOT reflect the actual codebase state. After verification:

  • ✅ Position damage: 100% ROM C parity (10 new tests added)
  • ✅ Sharpness: 100% ROM C parity (existing test verified)
  • ✅ Vorpal: 100% ROM C parity (prevents envenoming only, no combat effect)
  • ✅ Circle stab: Correctly NOT implemented (not in ROM 2.4b6)

Combat system ROM parity: 98-100%

Test results: 121/121 combat tests passing (100% pass rate) ✅

Next steps: Update documentation to reflect actual implementation status.