Overview
Datapacks are a recently introduced, powerful tool for creating highly customized mechanics in the vanilla game of Minecraft. The game allows you to place a folder with custom .mcfunction files within your world folder that executes in-game commands. I have created a base system for an RPG-like game within Minecraft with a focus on spells. Here I will show some of the spells I created in this datapack and talk about challenges I faced while developing them. Additionally, I’ll talk about some of the design that went into the ideas for these spells.
Although the datapack is not finished, a lot of the core mechanics are in it. I originally built this datapack as the base for an adventure game inside of Minecraft. Unfortunately, I have no plans to finish the datapack or map right now.
A look at an .mcfunction file
execute as @a[nbt={Inventory:[{Slot:-106b,tag:{rightClick:blink}}]},scores={rightClick=1}] if score @s blinkTimer > @s BLINK_TIME_MIN at @s run function cheese:spell_casting/
cast_spell_blink
Just to give an example of what it is like to write datapack functions, I give this snippet of an mcfunction file from the project. As these are all based on in-game commands, the programmer has to think I bit differently on how to structure everything. This particular example is what checks for the casting of the blink spell. I first check to see if the player is holding a certain item (the spell tome) in a certain slot in their inventory (the offhand), and then I check a variable called rightClick that is set in a scoreboard command. This tells me if the player has right clicked the blink tome. Then I check if the blinkTimer variable is greater than the minimum blink time—to see if they recently casted blink—and if so then I run a separate function file that does the actions required for blinking.
The item held in the player’s offhand (carrot-on-a-stick) is what detects these right clicks. That is what you will see in the following gifs.
Flower Fan
The flower fan spell casts 5 “flowers” in front of the player and bounces off of walls. The power of the spell is relatively weak, but covers a lot of area. This is meant to be one of the most basic spells that the player can get, and would likely be used the most frequently.
The biggest challenge with the flower fan spell was getting the “flowers” to bounce against walls. Since there is no way to do operations with variables inside of Minecraft commands, I had to find some way to make the flowers rotate based on the direction they were fired. I ended up having to check many different directions and changing the rotation based on the direction.
Lightning
The lightning spell is straightforward. It summons a lightning bolt in the direction the player is facing. I wanted this spell to be one of the spells that the player would use most often, so I also give the player a speed boost if they hit an enemy with the spell. It’s a low-damage spell, but it’s useful for its utility.
The lightning spell with the resulting speed boost.
Dark Flood
The dark flood spell is one of my favorites. Upon hitting an enemy, it summons a “rainstorm” over their head—damaging them and setting the “wet” status. A wet enemy takes more damage from the lightning spell. I was hoping with this system that players would try to combo their spells with one another.
Rock Shield
This spell quickly summons a rock wall in front of the player, blocking incoming enemy attacks. It can also be cast below the player so they can quickly get up to high places. I faced a similar issue with this spell as the flower fan. Since Minecraft structures cannot be rotated, I had to create a separate rock wall for each direction the player might face, and copy the rock wall from a place in the world to in front of the player.
Casting a rock wall in front.
Casting a rock wall below.
Blink
The blink spell allows the player to move forward a short distance. I wanted there to be some amount of thought with blinking, so I incorporated a system where the player must time their blinks in order to get the most possible distance. After a player uses a blink, there will be a sound that lets them know they can blink again. If they try to blink before this chime, there will be a penalty where the player must wait a little bit before blinking again. I hoped this system would give a simple dash a bit more depth.
One challenge I faced with the blink ability was wall collisions. Initially, I just teleported the player forward a small amount, but this would cause the player to go through walls. So I ended up doing a raycast using an entity before the player blinked to see if there was going to be any problems with the collision. If there were, I would teleport them as close as possible to the point of collision.
What I learned
Customizing Minecraft was when I first started to become interested in game design. It’s a simple way to program mechanics in a familiar environment. While it can be difficult to work with, I feel that at the base level designing datapacks shares a lot of similarity with mechanic design in games.