Where I'm At

So far, things have nominally progressed smoothly. At this point, I’ve finished creating the Common cards for the Psychologist and started working on the Uncommon cards. I’ve also patched the main game’s code to assist with implementing a few novel mechanics. Additionally, I’ve utilized interfaces to ensure all of my work is modular and extensible, ensuring development continues smoothly. Overall, the character is coming together nicely, and even during my brief debugging playtests, I can already see exciting strategies forming.

Card by Card

During this article, I plan to detail the development history of four cards I designed, explaining things both from software development and game design perspectives. Even small changes to individual cards can have significant ramifications for the feel of the character overall. That’s especially true regarding Common cards because of how frequently they appear.

Furthermore, although simple cards1e.g., those that only deal damage or grant a static amount of Block are easy to create through copy-pasting with minimal changes, more complex ones often require custom-made solutions. Using Slay the Spire’s advanced functionality necessitates interfacing directly with the underlying code through SpirePatch, an API built on top of Javassist.

Hit the Books

To ensure the relevancy of Doctrines, I’ve created a Common card for each with a minor effect and gains the player of a Doctrine of that type. In the case of Hit the Books, it facilitates the use of Academic Doctrines in an additional way by costing two energy. When it’s drawn, it will tick down any Academic Doctrines the player has by twice as much as usual.

From a programming perspective, Hit the Books is interesting because of the underlying method I use to have a player gain a Doctrine. Using inheritance, I had each of the three Doctrines I created extend a generic Doctrine object. This meant that all the work I did to handle gaining, decrementing, and triggering Doctrines would only have to be done once. Moreover, if I decide to add another type of Doctrine in the future, it will integrate with things seamlessly and won’t require reworking any of my previous code.

A screenshot of a card that costs 2 energy and reads "Deal 14 damage. Gain an Academic Doctrine."

New Leaf

A screenshot of a card that costs 1 energy and reads "Draw 1 card. Discard 1 card. Gain Vigor equal to their total cost."

New Leaf is a workhorse Common card that can fit into a variety of strategies. Even if the player doesn’t have any synergies that directly take advantage of its effects, it can still be a valuable way for them to sift through their deck. However, if the player has a specific use-case for drawing extra cards (such as a way of gaining Academic Doctrines) or for gaining Vigor2Vigor increases the damage of the next Attack card the player uses; then it wears off. (such as Retail Therapy, shown below), it can be incredibly effective.

On the backend, New Leaf requires tracking something that Slay the Spire normally doesn’t track: how much a drawn card costs. This required me to implement a new variant of the “draw cards” action to record that explicitly. This required extensive debugging due to Slay the Spire’s built-in spaghetti-code approach to modifying and discounting the cost of a card. Still, eventually, I managed to get everything figured out. It turned out to be a good exercise in learning the underlying techniques that Slay the Spire uses to manage things, and it helped me a lot moving forward.

Perfectionism

One of my favorite things in a game is when I can take a mechanic that would typically be a downside and turn it into a benefit. Perfectionism is an opportunity to do just that. At first blush, the card provides a high amount of Block but with a catch: unless the player is at full health, they’ll gain Feedback, a negative status effect that damages the player whenever they attack. However, in concert with other cards that allow the player to transform Feedback into a positive effect, Perfectionism can become an efficient Block card with additional upside, turning it into an absolute powerhouse.

Implementing Perfectionism was relatively simple since Slay the Spire’s basic code already provides a way of checking the player’s health level. That said, while testing Perfectionism, I found a bug in how I implemented Feedback; fortunately, it was a relatively quick fix.

A screenshot of a card that costs 1 energy and reads "Gain 9 Block. If you're missing HP, gain 4 Feedback."

Retail Therapy

A screenshot of a card that costs 2 energy and reads "Deal 3 damage 2 times. Spending gold at a shop increases the damage of this card by 1."

From the player’s perspective, Retail Therapy is an attractive card to pick up because it has the potential to grow in power throughout the game. If the player takes it early and manages to visit enough shops, it has the potential to dispatch small foes single-handedly. Furthermore, the fact that Retail Therapy does damage twice with a single card (or thrice after being upgraded) means that positive status effects such as Vigor are extra-useful.

That said, from the programmer’s perspective, Retail Therapy was a pain to implement. I had to use SpirePatch, modifying the game’s bytecode to check when the player makes a purchase. Keeping track of how many times the damage of Retail Therapy has been incremented also posed difficulties since Slay the Spire’s default is to reset each card to its base version after each combat.

But Something's Missing?

You might have noticed that none of the cards I showcased today utilize the Conditioning card I discussed in the previous episode. This is intentional, as I’ve decided to move away from relying on Conditioning as a significant piece of the Psychologist’s design. It’ll still show up, but perhaps only once or twice rather than as a primary theme.

Going Forward

My next step is to continue adding more Uncommon cards to the character. Uncommon cards are where a lot of fascinating stuff happens, at least from a game-design perspective: they show up frequently enough to be relevant but infrequently enough that having a few genuinely wacky designs is perfectly permissible.