LearnSpell
Add a spell to an arcane caster's spell book, for a level gain or a mentor's lessons.
Full documentation: LearnSpell. Wire type: learn_spell.
Legal session modes: exploring, town
JSON Schema
{
"description": "Add a spell to an arcane caster's spell book, for a level gain or a mentor's lessons.\n\nLegal in town and while exploring. The book fits, per spell level, at most\nthe caster's current slot count at that level, and it never shrinks, so a\ndrained caster's book may sit over capacity, taking nothing more until\ncapacity catches up. No game time passes: the fiction around the learning\n(the mentor's week, a copied scroll's costs) belongs to the game.\n\nModes:\n `town`, `exploring`\n\nRejections:\n - `session.command.wrong_mode` - an encounter or battle is underway, or the\n game is over.\n - `session.command.unknown_member` - `character_id` names no party member.\n - `session.command.member_incapacitated` - the member cannot act.\n - `magic.book.not_arcane` - the class keeps no spell book.\n - `magic.book.unknown_spell` - `spell_id` names no spell.\n - `magic.book.wrong_list` - the spell is off the caster's spell list.\n - `magic.book.duplicate` - the book already contains the spell.\n - `magic.book.capacity_exceeded` - no open slot at the spell's level.\n\nEvents:\n `SpellBookUpdatedEvent` with\n the added spell. No game time passes.",
"properties": {
"command_type": {
"const": "learn_spell",
"default": "learn_spell",
"title": "Command Type",
"type": "string",
"description": "The wire discriminator. Each subclass fixes it to its own snake_case literal, like\n`\"move_party\"` or `\"open_door\"`, so you never set it yourself: constructing the subclass\ndoes. It's what `parse_command` and the\n`AnyCommand` union read to rebuild the right class\nfrom a serialized mapping, and it stays the same across releases."
},
"source": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Source",
"description": "An annotation naming the authored object (a trigger or quest id) or the game\nsystem on whose behalf the command was issued. Execution never reads it: a stamped\ncommand does exactly what the same command unstamped does. It is logged and replayed\nwith the command, so the log alone answers \"why did this happen\". Absent is `None`,\nand the empty string is not a value."
},
"character_id": {
"title": "Character Id",
"type": "string",
"description": "The arcane caster whose book grows, by\n`MemberView.id`. A class that keeps no spell book is\nrefused with `magic.book.not_arcane`."
},
"spell_id": {
"title": "Spell Id",
"type": "string",
"description": "The spell to write into the book, from\n`load_spells` (see the spell id index). It has\nto be on the caster's own spell list, and the book fits at most as many spells at each\nlevel as the caster has slots at that level."
}
},
"required": [
"character_id",
"spell_id"
],
"title": "LearnSpell",
"type": "object"
}