Is my adaptation of the Battle Master as a Wizard subclass balanced relative to other Wizard subclasses and to the original Battle Master?


Background Motivation

I wanted to create a subclass for Wizard that uses an expendable die resource to augment its magic and benefit its allies, similar to how the Battle Master Fighter expends superiority dice to fuel maneuvers which augments its attacks and benefit its allies.

Design Process

The following were some significant steps and motivations in my design process.

  • I called the subclass the School of Pedagogy because, thematically, a Wizard of this subclass is an academic who studies magic at a theoretical level. I called the equivalent of Battle Master maneuvers “theorems” for the Pedagogy Wizard and the equivalent of superiority dice “savant dice.”
  • I evolved the Pedagogy concept from the Unearthed Arcana Lore Master and School of Invention, but almost nothing from those inspirations remains.
  • I ported the Battle Master subclass features (at 3rd, 7th, 10th, 15th, and 18th Fighter levels) into the chassis of the Wizard (at 2nd, 6th, 10th, and 14th Wizard levels), trying to keep a similar pacing of improvements.
  • I reduced the die size progression and the utility/skill features for the Pedagogy Wizard to include only d8 and d10 savant dice to account for Wizards generally being more powerful than Fighters at higher levels and for Wizards generally having more skills.
  • I ported many of the Battle Master maneuvers directly into theorems with minimal changes to apply the benefits to spells and magical effects. However, not every maneuver was sensible to port, so I excluded some. Then I created original theorems to fill unique magical needs that exist for a Wizard but not for a Fighter.
  • I compared the resulting theorems to all subclass features of other Wizard subclasses to avoid stepping on their toes. Some features and theorems are inspired by class/subclass features from other classes, in which case I tried to avoid impeding on those as well. I specifically avoided duplicating any Sorcerer Metamagic features.
  • For wording all theorems that add or subtract a die on an attack, check, or save, I tried to use wording identical to that used in Battle Master maneuvers, Bardic Inspiration, and the bless and bane spells: if the intent is that you can add/subtract before or after the roll is resolved, it’s explicitly stated; otherwise, you add it when you make the roll.
  • I iterated the subclass many times using feedback from several other DM’s. We will be playtesting the subclass for two Wizard characters in two campaigns (one where I am the DM and one where I play the Wizard), but it hasn’t made it to the table as of this posting.

Text of the Subclass (version 1.0)

The following is the result of my design effort.

Arcane Expertise

At 2nd level, you gain proficiency in the Arcana skill if you aren’t already proficient in it, and your proficiency bonus is doubled for any ability check you make that uses Arcana.

Magical Savant

When you choose this school at 2nd level, you learn magical theorems that are fueled by special dice called savant dice.

Theorems. You learn three theorems of your choice, which are detailed under “Theorems” below. Many theorems enhance a spell or other magical effect in some way. You can use only one theorem per effect.

You learn two additional theorems of your choice at 6th, 10th, and 14th level. Each time you learn new theorems, you can also replace one theorem you know with a different one.

Savant Dice. You have four savant dice, which are d8s. A savant die is expended when you use it. You regain all of your expended savant dice when you finish a short or long rest.

You gain another savant die at 6th level and one more at 14th level.

Theorems

The theorems are presented in alphabetical order.

Applied Studies

When you make an Intelligence (Arcana, History, Nature, or Religion) check, you can expend one savant die to add it to the check. Alternatively, when you or a friendly creature who can see or hear you makes an Intelligence (Investigation) check, you can use your reaction and expend one savant die to add it to the check before or after making the check, but before any effects of the check are applied.

Beguiling Spell

When you cast a spell that forces a creature to make a Wisdom saving throw against being charmed or frightened, you can expend one savant die to make the spell especially beguiling and hard to ignore. Subtract the savant die from that creature’s first saving throw against the condition.

Damping Defense

When a creature damages you with a weapon attack, you can use your reaction and expend one savant die to reduce the damage by the number you roll on your savant die + your Constitution modifier.

Distracting Spell

When you hit a creature with a spell attack, you can expend one savant die to distract that creature, giving your allies an opening. You add the savant die to the attack’s damage roll. The next attack roll against the target by an attacker other than you has advantage if the attack is made before the start of your next turn.

Dual Strike

When you cast a spell with a duration of Instantaneous and it deals damage to a creature on your turn, you can use a bonus action to direct one of your companions to strike in tandem. When you do so, choose a friendly creature who can see or hear you and expend one savant die. That creature can immediately use its reaction to make one weapon attack against the same target, adding the savant die to its attack roll.

Elemental Flux

When you cast a spell that deals acid, cold, fire, lightning, or thunder damage, you can expend one savant die and choose one of the spell’s damage types from that list to substitute for another type from that list for the spell’s duration. The first time you roll damage for the spell using the substituted type, add the savant die to the damage roll.

Focusing Oration

When a friendly creature that can see or hear you misses with an attack, you can use your reaction and expend one savant die to refocus that creature’s efforts. Add the savant die to the attack roll, possibly changing the outcome.

Galvanizing Oration

When a friendly creature that can see or hear you makes a saving throw to end an ongoing effect on itself or to maintain concentration, you can use your reaction and expend one savant die to add it to the saving throw.

Maneuvering Spell

When you cast a spell with an area of effect, you can expend one savant die to direct one of your comrades to exit the area. Choose a friendly creature who can see or hear you in the area. Before the spell takes effect, that creature can use its reaction to move up to its speed, adding the savant die to its AC until it stops moving.

Mental Agility

When you roll initiative at the start of combat, you can expend one savant die to add it to the roll. When you use this theorem and aren’t incapacitated, you can’t be surprised on your first turn in combat.

Merciful Spell

When you reduce a creature to 0 hit points with a spell and the target isn’t killed outright, you can expend one savant die to hold back some of the spell’s energy and merely knock the target out. The target falls unconscious and is stable. You gain temporary hit points equal to the savant die roll + your Wisdom modifier.

Precision Spell

When you make a spell attack against a creature, you can expend one savant die to add it to the attack roll. You can use this theorem before or after making the attack roll, but before any effects of the attack are applied.

Reactive Cantrip

When a creature misses you with a melee attack, you can use your reaction and expend one savant die to cast a damaging cantrip that targets only that creature and has a duration of Instantaneous. Add the savant die to the cantrip’s damage roll.

Stirring Oration

When you cast a spell with verbal components on your turn, you can use a bonus action and expend one savant die to encourage one of your companions with an insightful speech woven into your spellcasting. Choose a friendly creature who can see or hear you. That creature gains temporary hit points equal to the savant die roll + your Charisma modifier.

Swift Spell

When you cast a spell that forces a creature to make a Dexterity saving throw, you can expend one savant die to make the spell especially swift and hard to avoid. Subtract the savant die from that creature’s first saving throw against the spell.

Tough Spell

When you cast a spell that forces a creature to make a Constitution saving throw, you can expend one savant die to make the spell especially tough and hard to withstand. Subtract the savant die from that creature’s first saving throw against the spell. This theorem can’t hinder a Constitution saving throw made to maintain concentration.

Expeditious Research

Starting at 6th level, you can use the Search action as a bonus action.

Improved Magical Savant

At 10th level, your savant dice turn into d10s.

Timely Epiphany

Starting at 14th level, when you roll initiative and have no savant dice remaining, you regain one savant die.

Question

Is this Wizard School of Pedagogy balanced relative to other Wizard subclasses and to the original Fighter Battle Master that inspired it? In other words, can the School of Pedagogy coexist with those other subclasses as a useful, distinct, and coequal option without impinging on their design? Things to watch for…

  • Flawed language with ambiguity or unintended consequences.
  • Features that are not level-comparable with similar features from other classes/subclasses.
  • Features granting benefits that are too powerful relative to existing options.
  • Features that are game-breaking within the game’s existing design.
  • Features that are so niche or unhelpful they would never be chosen or used.

I am not at all concerned with whether the Pedagogy Wizard seems thematically or mechanically similar to the Sorcerer, so any similarity between the concept of theorems and of metamagic isn’t considered to be infringing on the use case of Sorcerers for purposes of my question, unless a theorem directly replicates a particular Sorcerer metamagic option.

(To the best of my ability, I’ve followed the recommendations on Meta for how to present a homebrew balancing question. I’m happy to accommodate actionable suggestions for improvement of the question. However, if I need to iterate the subclass design again after reviewing the answers, that will be done in a separate question. Finally, sorry for the wall of text. I hope it’s easy to follow.)

Is this “Cuetzpali” Race Balanced relative to PHB races?

As background, I wanted to create something akin to a the Lizardmen from Age of Sigmar. Different from the Lizardfolk in Volo’s in that they’re not swamp dwelling savages but have a highly ordered and developed (although strange) social order.

According to Detect Balance it seems pretty reasonable, but I wanted to make sure there aren’t any unintended synergies (or that it’s just out of whack in general).

Cuetzpali

Cuetzpali are a race of man-sized, lizard-like humanoids decorated with a frill of feathers around their neck that sometimes extends down their backs or arms as well. They live regimented lives in vast temple-cities following a rigid caste system which dictates their life path from the moment they hatch from their leathery eggs. They worship the sun as the source of all life and spend significant time charting the motion of the sun, moon and stars as an act of devotion and to determine the caste of newly laid clutches of eggs.

Ability Score Increase. Your Constitution score increase by 2, and your Strength score increases by 1.

Age. Cuetzpali reach maturity around age 10 and often live to be 80 years old.

Alignment. Virtually all Cuetzpali are lawful. Their society is bound by a strict caste system and all Cuetzpali can instinctively sense whether a given Cuetzpali is higher or lower on the social ladder than them.

Size. Cuetzpali are similar in height and bulk to humans. Your size is Medium.

Speed. Your base walking speed is 30 feet.

Cold Blooded. Cuetzpali feel emotions less strongly than warm-bloods. You have advantage on saving throws against effects which cause the Charm or Fear conditions.

Slow Metabolism. Cuetzpali commonly eat things which would be toxic to warm-bloods. You have resistance to poison damage and advantage on saving throws against the Poisoned condition.

Stargazers. Cuetzpali spend significant time observing the heavens and charting the movement of heavenly bodies. You have proficiency with Navigator’s Tools.

Theocratic. Cuetzpali society is based on a deeply theocratic caste system. You have proficiency in the Religion skill.

Languages. You can speak, read, and write Common and Primordial.

Relative Value of Different Consequences

A discussion of handling of mechanics for characters who quickly regenerate their wounds resulted in an idea of implementing regeneration by changing the type and/or number of Consequences a regenerating character has: if it has multiple Mild Consequences and no Severe (or even Moderate) ones, this results in the system naturally producing mechanical effects that closely match what happens in the fiction – character genuinely getting wounded, but being at full or near-full health in a few scenes.

This seems like an elegant ways of making the pacing and mechanics follow the fiction. However, it raises one big question: what is a fair exchange rate between Consequences of different severity levels? Or, alternatively, how much is a Consequence of a given severity worth in terms of other ‘currencies’ of the game?

Before you try to frame-challenge: The answer may be academic for a party that all consists of immortals/werewolves/T-1000s/trolls, but is of interest for a more varied party where some PCs would have such traits and others wouldn’t. It’s certainly a concept that comes up from time to time and that I’ve seen discarded for reasons of lack of confidence about the mechanical utility of such benefits.

Prior research and factors to consider:

It seems that the relative utility of a Mild Consequence hovers around a level of a bit less than 1 Refresh (or 1 Stunt), maybe half of one:

  • In general, a Mild Consequence is about as good as one Invocation for preventing a Take-Out, but it comes with one free Invocation for an enemy. It is unambiguously worse than Armour:2 (which is often priced at a Stunt), since it’s only used once per Conflict.
  • In a campaign with about 5+ scenes and about a couple or more appropriate-type Conflicts per Minor Milestone, it’s plausible to maybe fill and recover a couple of Mild Consequences per Minor Milestone, but that requires lucky timing. (In my experience that never happened even once so far. On the contrary, Conflicts seem rare in games I’ve been in, even in action-oriented games.)
  • A Consequence can be of use as a Success at a Cost and some other similar applications, but those seem rare.

However, even taking that in mind, I find it harder to compare the value of Consequence of other severity:

  • they act to absorb more Shifts…
  • …while still only providing 1 Free Invocation to the enemy;
  • but they are significantly slower to recover from, meaning you can only use them rather rarely.

I’ve seen opinions going in both directions about whether Moderate and Severe Consequences are more or less powerful than Mild ones (and used to hold the latter opinion, but by now am no longer confident in it after seeing the main drawback pointed out to me).

Could anyone please help me evaluate their relative values, whether backed up by mathematically well-founded theorycraft, or by sufficient actual-play experience and practical comparisons?

What is the relative return point of the Banishment spell? (The ‘space it left’)

I’m well aware I can just choose. I’m just looking for discussion.

When a creature returns from the Banishment spell, it returns at the ‘space it left’.

How do you play the reference point to this space?

IE if it is banished from a galloping horse, after a minute the horse will have travelled a long way. Is the return point on the horse? Or where the horse was when the Banishment occurred?

Same thing with being banished from a moving ship. Does the creature return on the ship or on the water where the ship was?

Is my nerfed version of the Healing Spirit spell in line with the relative power level of other sources of healing?

I have concerns about the immense healing potential that the Healing Spirit spell can put out.

As it appears in Xanathar’s Guide to Everything (page 157), the Healing Spirit spell is able to heal any creature that starts its turn within its effect, or passes through it during their turn. In practice, this spell is limited by the mobility of the party that tries to take advantage of it, but in my experience, the spell is still able to dramatically improve the hitpoint recovery of the whole party, along with minimizing the impact of Unconsciousness or Death Saving Throws. In my experience, campaigns where Healing Spirit is accessible tend to trivialize/obsolete use of features like Hit Dice, Second Wind,

For reference, at its base level, it’s capable of healing any creature that runs through it for 1d6 hit points once per turn for 10 turns. So even if you only hit a single creature, you’re still confidently healing an average of 35 hitpoints to a single creature, and much more than that on more than one creature. And all of that scales with the level of the spell. The spell, once cast as a Third Level Spell, is strictly better than the Paladin-exclusive spell Aura of Vitality (also a third level spell), which has action-economy restrictions and does not scale with level, and unlike Aura of Vitality, Healing Spirit is accessible to a full-spellcaster capable of upcasting the spell and casting the spell many more times in a day.

It’s also been my experience that banning “out of combat” use of the spell doesn’t help much, since it only takes a single combat encounter being dragged out to permit optimal use of this spell.

I could choose to ban the spell entirely, but I want to consider a compromise first before I resort to that. So for my campaigns, I’m proposing the following version of the spell designed to keep some of its power as a healing spell while tempering its more ludicrous features:

Healing Spirit

2nd-level conjuration
Casting Time: 1 bonus action
Range: 60 feet
Components: V, S
Duration: Concentration, up to 1 minute

You call forth a nature spirit to soothe the wounded. The intangible spirit appears in a space that is a 5-foot cube you can see within range. The spirit looks like a transparent beast or fey (your choice).

Until the spell ends, whenever you or a creature you can see moves into the spirit’s space for the first time on a turn or starts its turn there, you may use your reaction to cause the spirit to restore 1d6 hit points to that creature. The spirit can’t heal constructs or undead.

As a bonus action on your turn, you can move the spirit up to 30 feet to a space you can see.

The two changes are the following:

  • Instead of being a free action, healing with this feature now requires the use of the spellcaster’s Reaction
  • The ability to gain benefits by upcasting the spell have been removed

So in general, this is a significant nerf to the spell. It becomes unable to be upcast, and it can only heal one creature per turn. It puts the spell more in line with the relative power of spells like Aura of Vitality while still making it accessible very early for low level druids. I think the spell will still be competitive in terms of raw healing output and for helping keep allies alive, while keeping it from trivializing all other possible sources of healing.

Does this version of the spell bring it more in line with the relative power level of other sources of Healing? Or are my assumptions/observations about the power of the original spell off-base?

A data structure for efficiently finding nodes relative to other (ex: if a node is earlier in a list than another node)

Suppose we have N elements, which we’ll treat as a simple object. Is there a data structure I can use that will allow me to see which node appears earlier based on some arbitrary insertion order given a reference to both nodes? I’ll need some kind of data structure $ \mathcal{D}$ , where $ \mathcal{D}$ supports the following operations (assuming $ A$ and $ B$ are node references, and $ A \neq B$ ):

$ \mathcal{D}.addBefore(A, B)$

$ \mathcal{D}.addAfter(A, B)$

$ \mathcal{D}.addLast(A)$

$ \mathcal{D}.earlier(A, B) \rightarrow bool$

$ \mathcal{D}.remove(A)$

I’d like to implement some kind of $ Earlier$ predicate which takes two nodes and returns whether A comes before B. For example, if this was an indexed list and we had the index of the nodes, then it’d be simply:

$ $ Earlier(A, B) \implies A.index < B.index$ $

The ordering is determined by a user who inserts them as they see fit. They are allowed to add either after some node, or before some node, or if the data structure is empty then they can just add it and the element that was added first becomes the only element in the data structure until another element is added.

A practical example of this problem is that a user is pasting files into a directory, but the file explorer lets the user paste files before or after any file in the list. The file explorer must display the files in order that the user requests, so if a list is used to hold the files, then [A, B, C] should render as [A, B, C], and if the user pastes a file D before B, then the list should render [A, D, B, C].

This becomes a problem when I need to insert before another item: I don’t have that luxury since inserting into the middle of a list backed by an array has a big overhead. My next thought was to go with a linked list because I will have references to the two nodes and can quickly insert with my handle to the node. This is $ \mathcal{O}(1)$ for insertion.

The actual problem I have is that insertions are not too frequent, but searching for which node comes first between two given nodes in the data structure is a common operation. This makes the naive $ \mathcal{O}(n)$ search pretty painful when dealing with a lot of nodes in the list as I have to search all the other nodes in the list at the worst case to determine which one is behind/ahead of the other.

My main roadblock is that since the user can insert them in any order (and it needs to stay in the order the user inserts them in), I have to use some data structure that maintains this invariant.

As such, with a linked list I am stuck currently at:

$ $ Earlier \in \mathcal{O}(n)$ $

and iterating over the list is of course $ \mathcal{O}(n)$ , along with removal being $ \mathcal{O}(1)$ since it’s trivial to unlink a node with a reference to it in a doubly linked list.


My solution to the problem:

Now, we can change the data structure if we want, so a linked list isn’t required. The only thing that is required is the ability to let the users iterate over the data structure and get the elements back in the order they placed them in.

This makes me think of whether there’s a tree structure I can use. For example, what if I was to take a binary tree that balances itself such that the search depth is approximately $ \mathcal{O}(\lg n)$ , maybe something like a self-balancing tree. The first thing that jumps to mind is an AVL tree where I’d track the sizes of the trees in balance and then update them. This isn’t quite an AVL tree since there’s no implicit ordering between the nodes, but the idea of self-balancing is something I’d like to exploit to get a good search runtime.

To make this viable, our users will have references to our nodes. This way we can put each node in a hash table and do an $ \mathcal{O}(1)$ lookup to find the node in the tree. Inserting a node before or after it is not too bad since you create a new subtree from the current node by adding a parent node and making the previous node into a leaf and adding the element as another leaf. To make this visually make sense:

    o                   o    / \     add A       / \      rebalance   o   o   ------->    o   o    ---------->  ...  / \      before X   / \        if needed o   X               o   o                        / \                       A   X 

or

    o                   o    / \     add A       / \      rebalance   o   o   ------->    o   o    ---------->  ...  / \      after X    / \        if needed o   X               o   o                        / \                       X   A 

where o is another node (that is either a parent, or a leaf).

A consequence of this data structure is that it is a full binary tree and each leaf is a value we’re storing, and the parent nodes do not store any value.

The cost of adding a node to a self balancing binary search tree is $ \mathcal{O}(1)$ to place it at the node since we assume we can look up the node reference from a hash table, and then $ \mathcal{O}(1)$ to insert it by adding a parent and attaching the two nodes, and then $ \mathcal{O}(\lg n)$ to rebalance the tree. This means insertion is $ \mathcal{O}(\lg n)$ . Not too bad.

Searching for an element to see which comes earlier becomes a “traverse from both nodes up to the root and find the least common ancestor, and whichever comes from the left branch is earlier”, which is $ \mathcal{O}(\lg n)$ . Searching is now logarithmic as well.

As such, this means we now get:

$ $ Earlier \in \mathcal{O}(\lg n)$ $

Further, iterating over the binary tree is $ \mathcal{O}(n)$ since it’s a full binary tree and at worst there should be approximately $ 2n$ nodes to visit in total. Since the naive list solution previously was $ \mathcal{O}(n)$ , we’re looking good.

Finally, removal is probably the same as AVL tree removal and thus also $ \mathcal{O}(\lg n)$ .


But can we do better?

Overall the above solution is decent, but it would be really nice if I could knock the searching down to $ \mathcal{O}(1)$ if possible or something really small like how disjoint sets are $ \mathcal{O}(\alpha(n))$ for some operations and feel effectively constant.

Is it possible to do something like this in $ \mathcal{o}(\lg n)$ time? I am willing to trade away performance on addition, deletion, and iteration to get a better search time, as that is my bottleneck.

I don’t know what other data structures are out there, maybe you know. Or maybe there is some other method I can use that I don’t know about which would allow me to achieve very quick search times. I can augment the data structures, so that is always an option on the table.

I also understand that getting a better runtime might require going to the literature and implementing some exotic data structure, to which the cost of implementing and maintaining it may be more than it’s worth, and as such maybe the balancing binary tree might be the only viable solution since this is not Google-level data sizes and doesn’t need such a solution. Since this is a problem I have in a hobby project, I figure I can try out things with little repercussion.