Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Spell Item Schema #12

Open
akrigline opened this issue Mar 18, 2023 · 7 comments
Open

Create Spell Item Schema #12

akrigline opened this issue Mar 18, 2023 · 7 comments

Comments

@akrigline
Copy link
Contributor

akrigline commented Mar 18, 2023

Playtest Packet 2 describes "Spell"s which would be best implemented as an Item type. I'm going to bring some knowledge from the 5e system and make note of what shortcomings were felt by people who wanted to extend the spellcasting system

Compiling as much knowledge up front as I can about this topic because it will be a doozy.

Descriptive Text

description: HTML;
spellCircle: 'arcane' | 'divine' | 'primal' | 'wyrd'; // this selection should be extensible by modules
spellRing: number; (0 can represent cantrips, max of 9 should not be assumed, often this is expanded beyond 9)
spellSchool: 'one of the options'; // this should be extensible by modules

Origin

Something we were lacking in 5e was a way to mark where the spell came from.
E.g. a Cleric/Druid might prepare different spells for each class, but there should be a way to differentiate them.
Similarly, some items might have spells embedded in them, and ideally the system supports annotating this.

Components

5e ended up making these extensible by modules and turning them into checkboxes in the item sheet.

Target -- common item concept

A little convoluted and probably generalizable with other combat items.

Spells can affect specifically some kinds of things (all creatures, allies, enemies; sometimes also objects sometimes not objects, sometimes 'magical effects', only the caster, n creatures/allies/etcetcetc)

Then, they can affect a kind of area (within a cone/sphere/box/line, a specific selection of creatures within range)

And lastly, they have a range for when the origin of that kind of area begins (self, n ft)

target: {
  creatures: {
    number: number;
    type: 'allies' | 'any' | 'enemies' | 'self';
    alsoAffectsObjects: boolean;
  },
  area: {
    type: 'target' | 'cone' | 'sphere' | etc
  },
  range: {
    value: number;
    unit: 'ft' | 'mile' | etc; // remember metric is probably a thing
  }
}

Attacks or Saves -- common item concept

Complicated, there's probably different 'kinds' of attack rolls (weapon attack, spell attack at minimum), saves can target specific attributes, saves can be based on a specific ability score for the character.

Damage -- common item concept

Complicated, but worth building in the idea of damage types and damage groups early

Duration -- common item concept

duration: {
  type: 'instantaneous' | 'time' | 'other'

  // if time is the type
  timeValue?: number;
  timeUnit?: 'minutes' | 'hours' | 'days'; // etc.

  // if 'other' is the type
  // stuff like "until the start of your next turn" or "until the end of their next turn", etc...
  // unsure how to represent this, an enum?
}

Casting Time -- aka "Usage Time", common concept

For spells this is pretty clearly one of:

  • Action
  • Bonus Action
  • Reaction
  • Ritual
    But some features or items take 'minutes'/'hours'/etc, so we could generalize this as "usage time"
usageTime: {
  type: 'ritual' | 'action' | 'bonus action' | 'reaction' | 'special' | 'time'

  // if time is the type
  timeValue?: number;
  timeUnit?: 'minutes' | 'hours' | 'days'; // etc.
}
@cpcodes
Copy link

cpcodes commented Mar 20, 2023

I don't know if you are entertaining feedback here, but as far as the duration data structure, it should probably be stored internally as rounds (or instant, which might be different than 0 rounds), then converted for display if necessary. Any spell that provides a duration in its stat block in minutes/hours/days/etc. would simply be converted in the data to rounds.

Also, for targets, how would you handle something like vampiric touch where there are two different targets that receive two different effects? I assume a primary and secondary effect (or just an array of effect entries with no hard coded limit of total number), each with their own target settings, but I just wanted to bring it up since you were brain storming.

@cswendrowski
Copy link
Contributor

I don't know if you are entertaining feedback here

We are! Feel free to pitch ideas on Discord as well

Round based duration could work fine, although some GM's might change how long a round is - unsure here, @akrigline thoughts?

how would you handle something like vampiric touch where there are two different targets that receive two different effects?

I think it might make sense to have both self, for things that should apply to the source Actor, and targets, which is an array of targeted Actors

@akrigline
Copy link
Contributor Author

akrigline commented Mar 21, 2023

I've never heard of alternate round timings, if it's a thing it's not common.
I do wonder though if "duration" really means anything for a spell, or if there should always be an Active Effect for any spell which isn't instantaneous, and then that effect should store its expected duration?

The alternative is to either sync duration to a spell's effects on every change, or have the effect somehow inherit its duration from the parent spell.

Upcasting does sometimes affect duration, so that'd be a point in favor of putting it on the spell, and having the effect 'inherit' that at cast time. That would also allow some sort of metamagic mutation of spells to work... Hmmm.

@akrigline
Copy link
Contributor Author

Also, for targets, how would you handle something like vampiric touch where there are two different targets that receive two different effects?

Vampiric Touch is an interesting one, Fire Shield, Shadow Blade, also

These could be thought of as Spells which grant Effects that grant "powers", where "power" is a generic "thing that can be done."

So the "Vampiric Touch" spell would have a target of self, but the effect it imparts could create a new 'power' which has the right targeting logic inside it.

@akrigline
Copy link
Contributor Author

stored internally as rounds

There's one hiccup for this I just realized, there's a lot of mix and match in 5e between "until the start of your next turn" or "the end of their next turn" or etc etc etc, which is hard to express as a number of rounds, or even a number of turns.

I think something more than a simple number might be a good play, but I'm not sure how best to express that.

maybe "endTime" which describes this:

  • undefined -- indicates nothing special
  • end-of-target-turn
  • beginning-of-target-turn
  • end-of-actor-turn
  • beginning-of-actor-turn
    (actor here indicating the creature who did the action, cast the spell, used the feature, etc)
duration: {
  rounds: 1,
  endTime: 'end-of-target-turn',
}

@cpcodes
Copy link

cpcodes commented Mar 21, 2023

I think that you might be on to something with the spells simply creating Active Effects that hold a duration. Having the expiration set in terms of rounds (or seconds, if @cswendrowski's concern about variable round durations bears out), with an additional hint for beginning or end of turn (and whose turn) as you specify should cover the vast majority of circumstances. The only remaining hiccup I see is when position in the initiative order changes. I know that in 5e, they very specifically left out the delay action and modified readying an action in order to make the turn order immutable. So long as BF keeps this philosophy, this is good, otherwise you might need to keep the initiative number with the effect as well so that it ends on time regardless of where the caster/target moves to in the initiative order.

@akrigline
Copy link
Contributor Author

Updates for this, i've started knocking out the bits piecemeal:

Targeting Data Model: #15

Duration Data Model: #18

I'm working through "Usage Time" or "Activation Time" next

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants