Skip to content

SpellCastEvent

A spell was cast and its memorized copy spent.

Full documentation: SpellCastEvent. Wire type: spell_cast.

Default visibility: player

Message codes: magic.cast.cast, magic.cast.no_effect

JSON Schema

{
  "$defs": {
    "Visibility": {
      "description": "Who is allowed to see an event.\n\nEvery event has one of these two values, and the split exists because B/X keeps some rolls behind the\nreferee's screen. Filter a log on it before you show anything to a player, or call\n`GameSession.view`, which builds the player's and the referee's\nviews for you. A narrator playing referee reads both.\n\nThe values are the lowercase strings and they serialize into every event, so a renamed value is a\n`schema_version` bump.\n\nExamples:\n    ```python\n    from osrlib.core.events import DamageDealtEvent, HitPointsReportedEvent, Visibility\n\n    log = [\n        DamageDealtEvent(target_id=\"monster-0001\", amount=5),\n        HitPointsReportedEvent(target_id=\"monster-0001\", current_hp=2, max_hp=7),\n    ]\n    shown = [event.code for event in log if event.visibility is Visibility.PLAYER]\n    assert shown == [\"combat.damage.dealt\"]  # the goblin's remaining hit points stay hidden\n    ```",
      "enum": [
        "player",
        "referee"
      ],
      "title": "Visibility",
      "type": "string"
    }
  },
  "description": "A spell was cast and its memorized copy spent.\n\n`cast_spell` and\n`cast_from_scroll` emit this. What the spell then did arrives as the\nevents beside it: saving throws, damage, conditions, effects, healing, deaths.\n\nA cast that found nothing to work on reports the no-effect code and still spends the copy. Refusing the cast\ninstead would tell the player which targets were eligible, and B/X doesn't give that away for free.",
  "properties": {
    "code": {
      "title": "Code",
      "type": "string",
      "description": "What happened, as two or more lowercase segments separated by dots and namespaced by subsystem, like\n`combat.attack.hit`. This is what you branch on and what\n`format_message` looks up. Anything else raises a validation error."
    },
    "visibility": {
      "$ref": "#/$defs/Visibility",
      "default": "player",
      "description": "Player visibility: casting a spell is done out loud."
    },
    "event_type": {
      "const": "spell_cast",
      "default": "spell_cast",
      "title": "Event Type",
      "type": "string",
      "description": "The wire name for this event type."
    },
    "caster_id": {
      "title": "Caster Id",
      "type": "string",
      "description": "The entity id of the caster."
    },
    "spell_id": {
      "title": "Spell Id",
      "type": "string",
      "description": "The spell's content id, like `\"magic_missile\"`."
    },
    "mode": {
      "title": "Mode",
      "type": "string",
      "description": "Which of the spell's modes was used, by the mode's own name. A spell with several modes, like one that\ncan damage or heal, names the one that resolved."
    },
    "reversed": {
      "default": false,
      "title": "Reversed",
      "type": "boolean",
      "description": "True when the spell was cast in its reversed form."
    },
    "target_ids": {
      "default": [],
      "items": {
        "type": "string"
      },
      "title": "Target Ids",
      "type": "array",
      "description": "The entity ids the spell was aimed at. Empty for a spell that targets no creature."
    },
    "manual": {
      "default": false,
      "title": "Manual",
      "type": "boolean",
      "description": "True when osrlib didn't resolve the spell's effect, because the mode is one the rules leave to the\ntable. The copy is spent and the outcome is yours to narrate from the spell's printed text."
    }
  },
  "required": [
    "code",
    "caster_id",
    "spell_id",
    "mode"
  ],
  "title": "SpellCastEvent",
  "type": "object"
}