Posted March 11, 2019 by Joeri
Cantrip is my submission for this year's 7drl.
This is my first jam and also the first game I've ever finished.
My original plan came about when browsing Three Hundred Mechanics in search of inspiration for the upcoming jam and stumbling upon the Collectible Dungeons write-up. From there, my first idea was to make a roguelike where:
I iterated on this idea, but quickly found that the scope of this would probably be too big for me to handle. I would have to design a lot of enemies, room types and different abilities that would all work in a grid world with some AI to boot.
So I started cutting stuff. First, I removed movement, which immediately turned the idea into a 1v1 card battling game (unlikely it may seem, I'd not yet seen or played excellent roguelike card battler Slay the Spire, but my final concept, I now realise, looks a bit similar). I decided I wanted to keep stats in the low digits. The main attack card would do 1 damage, cards would cost 0 to 2 action points. Looking to simplify things further, I considered what to do with health, and decided to remove that as well.
This lead to the game's main gimmick: Damage result directly in discarding random cards, and damage to an empty hand would mean defeat. This lead to a few interesting considerations. Essentially, playing cards costs health, and suddenly passing your turn becomes a tactical consideration. A card like "Leech". which steals a card from your opponent, is hugely powerful.
In order to test this concept and some card ideas, I started a paper prototype and played a few rounds with my partner.
This process was delightful, and brought a lot of new insights. I had an idea for a "Defend" card, which would add a defence point. Those points would be expended when when receiving damage in order to protect your hand. While playing, however, it became clear that gaining defence through playing a card is useless beyond protecting certain cards from being discarded. So after some discussion about this with a friend, I decided to make "Defend" (later named "Shield") into an unplayable card that is always discarded first. This way you have the same effect without expending health, making the mechanic quite useful, and it also improved the usefulness of "Shield bash", which does damage equal to the amount of "Shield" cards in your hand.
Initially I planned on players playing a single card per turn, but that quickly started feeling stale, and I didn't have a way to limit the use of more powerful cards. So I introduced ability points. Players would gain 1 per turn with a maximum of 3, and cards would cost anywhere between 0 and 2 cards.
I also noticed that a game would quickly turn into players trading blows until one of them died, and usually this was the person who went second. Players needed a chance to recover and, of course, a way to not spend ability points. I experimented with a "Rest" mechanic, where you would opt to pass a turn in order to draw an extra card or earn an extra ability point, but that of course turned out to be a really easy way to become invincible. So I decided to make "Rest" a free card that had you draw another card, gain one ability point and then end your turn.
In his book about Spelunky, Derek Yu describes how one thing should always solve multiple problems. I'm by no means able to wield this lesson at will, but I did feel its effects: by reducing systems back into cards, they are able to participate in the entire ecosystem that emerges. "Shield" cards, rather than defence points, remain there to be damaged or fill your hand or used up by other cards. "Rest" becomes a limited, valuable resource.
I still wanted to do something with room cards as a form of player-driven procedural generation of the game's progression. On each new floor you'd receive a bunch of them, including the boss of that floor. Then you'd pick where to go to next from the top 3 room cards of the stack, leaving the decision of when to battle the floor's boss with the player.
Turns out there was not enough time to build that, though. I even almost couldn't submit a successful version of Cantrip -- the final 4 hours of development were a frantic race to implement more cards, decks and enemy types to put at least some meat on the bones of the card battling framework I'd built throughout the week. I had spent a huge amount of time polishing during the middle of the jam, when I should have been focussing on generating and testing content.
But, by the skin of my teeth, it was a success, albeit a completely unbalanced, minimally tested success. I did a small post-launch patch which, among others, fixed "Read mind", which is supposed to copy 2 cards from the opponent's hand, but in the initial submitted version up and copies the opponent's entire hand.
The final version is this:
If you've played the game, thanks so much for taking the time. Any feedback, questions, bug reports, hugs, whatever, let me know.
For those interested, you can find the source code of the GameMaker project here: https://github.com/joeribakker/cantrip