Skip to content

Replace duck-typed combatant and caster parameters with a protocol #104

Description

@mmacy

The kernel's flagship functions take the creature they act on as object or Any: 36 such parameters in core/combat.py, 43 in core/spells.py, 15 in core/effects.py, and 2 in core/items.py (attacker, defender, target, combatant, caster, reader, carrier). After the docstring pass (#87 to #99) every one says in prose that a Character or a MonsterInstance satisfies it, but the signature still says nothing: pyright cannot check a caller, the reference cannot link the type, and a reader has to trust prose over the annotation. The pre-Phase-7 audit named this and it was never done.

Proposed shape: a Combatant protocol in osrlib.core listing the attributes the kernel reads through those parameters (id, armour_class, current_hp, max_hp, hit_dice, level, the ability-modifier accessors, and whatever the getattr chains pull), with narrower protocols where a function needs more (a caster with spell slots, a reader with an inventory). Character and MonsterInstance satisfy them structurally, so no class changes. Annotate the parameters with the protocol and keep the runtime behaviour identical.

Contract-first chunk: write the protocol stubs and a test that asserts Character and MonsterInstance satisfy each one and that pyright accepts every existing call site, then annotate. Widening an object parameter to a protocol is not a breaking change under semver.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions