My young daughter is enjoying Minecraft, but somehow the vanilla game doesn’t cut it anymore. I am a gamer and a techie, which motivates me to find ways to spice up my own Minecraft experience while joining her in a game.
For her, the answer (on Java Minecraft at least) is to catch and train up Pokemon in the context of Minecraft. This makes the game way more fun for her, and makes it a more interesting challenge for me. Particularly since my client of choice is a Meta Quest 3, and I play Minecraft in VR via QuestCraft.
Not only that, but we had been utilizing Aternos for free servers, and while they are a solid choice for trying out Minecraft in multiplayer, they decidedly aren’t the right fit for a long term server. So I invested some time in finding a free solution that would be reliable and easy to maintain.
I resolved all of my pain points with the following architecture.
Then again, if you are already familiar with the concept of Infrastructure as Code you may be able to dive right in. Up to you!
Disclaimer: This infrastructure utilizes a Pay-As-You-Go account setup. Only follow this guide if you are ok with the possibility of incurring costs on Oracle. This setup is completely free, but I won’t be held responsible if you end up with a bill when something went sideways. I had to pay about a dollar to Oracle while exploring and learning how this worked.
git clone https://github.com/saranicole/minecraft-oci-k8s.git
cd oci-free-cloud-k8s/terraform/infra
If you haven’t registered for a Pay as You Go account on Oracle, do that now. Sign up at https://signup.cloud.oracle.com and add a payment method to convert it to Pay as You Go. Without doing this payment method step, your resources will never get created (the terraform will hang). Make sure you have the oci command line tool installed and authenticated as well – see https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm .
compartment_id = << Tenancy OCID >>
region = << Region >>
ssh_public_key = << SSH Public Key >>
kubernetes_version = "v1.35.0"
user_ocid = << User OCID >>
fingerprint = << API Key fingerprint >>
private_key_path = << Path to API Key Secret File >>
bucket_namespace = << Storage Namespace >>
enable_minecraft_port = true
Parameters Explanation: compartment_id – this is your tenancy ID. Retrieve it by clicking the profile dropdown, selecting “Tenancy”, then copying the first “OCID” value.
region – the region where you provisioned your account, this should be reasonably closest to you. See https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm for a list of available choices. Try to avoid going with Ashburn since it is the most popular and has a chance of not being able to provision resources
kubernetes_version – This is the Kubernetes Cluster version. See https://kubernetes.io/releases/ for the available versions. v1.35.0 was the latest at the time of writing.
fingerprint – This is the fingerprint given to you when you created the API Key
private_key_path – this is the file path to the location where you saved the private key part of the API Key. Something like $HOME/my_secret_key.pem . Note this is not an SSH private key
bucket_namespace – this is the Storage Namespace again
enable_minecraft_port – set to true if you plan on using this as a Minecraft server. This will open up port 25565. If you want this for some other purpose, keep this turned off using false .
Run the init first to confirm that Terraform is working and make sure to inspect everything it will create.
terraform init -backend-config=backend.conf
Then run the plan
terraform plan
It should output something like this:
data.oci_containerengine_node_pool_option.node_pool_options: Reading...
module.vcn.data.oci_core_services.all_oci_services[0]: Reading...
data.oci_identity_availability_domains.ads: Reading...
oci_identity_tag_namespace.k8s_node_pool: Refreshing state...
...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
~ update in-place
Terraform will perform the following actions:
# oci_core_security_list.private_subnet_sl will be created
... yadda yadda
If there are any errors due to missing information, make sure your files are all filled out correctly.
Once the plan succeeds with no errors, you can apply the Terraform.
terraform apply
Enter “yes” when it prompts you.
It should finish like this:
Apply complete! Resources: xx added, 0 changed, 0 destroyed.
It will also create a .kube.config file that you will need for further provisioning and to access the cluster with kubectl.
After everything is running for a day, make sure to visit https://cloud.oracle.com/account-management/cost-analysis to make sure everything is truly running without any costs, or that any cost you did get is within your expectation.
Congratulations! You now have a Kubernetes cluster running on Oracle Cloud. Check out the next post in this series to install Minecraft on this cluster.
If you already have a Kubernetes cluster that’s perfect, if not you can follow the previous post to get one for free on Oracle Cloud.
If you are not using Oracle cloud you will need to modify the minecraft/_terraform.tf file slightly to use whatever storage backend you want for the terraform state file.
git clone https://github.com/saranicole/minecraft-oci-k8s.git
cd oci-free-cloud-k8s/terraform/minecraft
You will need to create a backend.conf file, a general.auto.tfvars, a minecraft.auto.tfvars file and possibly an oracle.auto.tfvars file. Depending on how you want this to end up you will put different contents into these tfvars files.
If you are using Oracle Cloud, create the oracle.auto.tfvars file.
oracle.auto.tfars
compartment_id = << Tenancy OCID >>
region = << Region >>
ssh_public_key = << SSH Public Key >>
user_ocid = << User OCID >>
fingerprint = << API Key fingerprint >>
private_key_path = << Path to API Key Secret File >>
bucket_namespace = << Storage Namespace >>
If you want a vanilla Minecraft server, use the structure below and tweak as needed (making sure to change accept_eula to TRUE):
# Change this to TRUE
accept_eula = "FALSE"
world_version = "26.1.1"
server_type = "VANILLA"
fabric_loader_version = "0.18.6"
difficulty = "easy"
whitelist = "<< YOUR MINECRAFT USERNAME >>,<< SOME OTHER MINECRAFT USERNAME >>"
ops = "<< YOUR MINECRAFT USERNAME >>,<< SOME OTHER MINECRAFT USERNAME >>"
motd = "Welcome to Minecraft on Kubernetes!"
mod_urls = [
"<< MODRINTH JAR DIRECT DOWNLOAD URL >>",
"<< SOME OTHER JAR DIRECT DOWNLOAD URL >>"
]
download_world_url = "<< DIRECT DOWNLOAD LINK OF ZIP FILE CONTAINING WORLD DATA >>"
rclone_dest_dir = "<< OBJECT STORAGE BUCKET SUCH AS S3 OR OCI BUCKET NAME >>/<< OBJECT STORAGE BUCKET PREFIX SUCH AS 'worlds' >>"
enable_oci_backup_bucket = false
enable_oci_load_balancer = false
rcon_password = "<< SUPER SECRET PASSWORD >>"
If you want Cobblemon, particularly cobblemon on Meta Quest, you will need to use contents like the following:
minecraft.auto.tfvars
# Change this to TRUE
accept_eula = "FALSE"
world_version = "1.21.1"
server_type = "FABRIC"
fabric_loader_version = "0.18.6"
difficulty = "easy"
whitelist = "<< YOUR MINECRAFT USERNAME >>,<< SOME OTHER MINECRAFT USERNAME >>"
ops = "<< YOUR MINECRAFT USERNAME >>,<< SOME OTHER MINECRAFT USERNAME >>"
motd = "Welcome to Cobblemon on Kubernetes!"
mod_urls = [
"https://cdn.modrinth.com/data/MdwFAVRL/versions/Ygf8KJFC/Cobblemon-fabric-1.7.0%2B1.21.1.jar",
"https://cdn.modrinth.com/data/P7dR8mSH/versions/yGAe1owa/fabric-api-0.116.9%2B1.21.1.jar"
]
download_world_url = "<< DIRECT DOWNLOAD LINK OF ZIP FILE CONTAINING WORLD DATA >>"
rclone_dest_dir = "<< OBJECT STORAGE BUCKET SUCH AS S3 OR OCI BUCKET NAME >>/<< OBJECT STORAGE BUCKET PREFIX SUCH AS 'worlds' >>"
enable_oci_backup_bucket = false
enable_oci_load_balancer = false
rcon_password = "<< SUPER SECRET PASSWORD >>"
If you are using Oracle, you will want to change both enable_oci_backup_bucket and enable_oci_load_balancer to true.
In the case of Oracle the rclone_dest_dir will be “minecraft-backups/worlds”.
Run the init first to confirm that Terraform is working and make sure to inspect everything it will create.
terraform init -backend-config=backend.conf
Then run the plan
terraform plan
If there are any errors due to missing information, make sure your files are all filled out correctly.
Once the plan succeeds with no errors, you can apply the Terraform.
terraform apply
Enter “yes” when it prompts you.
It should finish like this:
Apply complete! Resources: xx added, 0 changed, 0 destroyed.
QuestCraft! It’s awesome and I highly recommend subscribing to their Patreon. To emphasize a point they make many times over, you need to own Minecraft Java Edition in order for this to work, and you need access to your Microsoft login in order to log into Minecraft.
The basic installation instructions are available at https://github.com/QuestCraftPlusPlus/QuestCraft . You will need to follow these instructions and start a single player world on version 1.21.1 first in order to have the folder created that you need to place the mod jars into. You will also want to download this jar file https://files.xrcraftmc.com/QuestCraft/Cobblemon-fabric-1.7.0%2B1.21.1.jar which is the fixed Cobblemon mod which ONLY works with Minecraft version 1.21.1 . Make sure your server is running Minecraft version 1.21.1 as well, they have not yet released a more current patched version. Everything Minecraft 1.21.1!
Drag the jar files you downloaded earlier into this folder:
Cobblemon-fabric-1.7.0 1.21.1.jar from the QuestCraft folks
Fabric API at 0.116.9
Quest Rebound
owo-lib
Now you should be able to connect to a Cobblemon server!
How to Battle Wild Pokemon and other Cobblemon Stuff
You will quickly find that Cobblemon relies on keybinds that are unavailable in QuestCraft. Worry not! You can use Quest Rebound to overcome this barrier.
Instructions on using Quest Rebound are quoted from the modrinth website:
Quest Rebound – Rebinding Instructions
Add this mod to your QuestCraft instance as normal and start your game. In the game, you can go to Options -> Controls -> Open VR Bindings Menu to change your keybinds.
To reset your keybinds, delete the interaction_profiles directory from your instance root.
You *must* restart your game in order for key rebinds to take effect.
Specifically for battling wild Pokemon, you can rebind “Throw Selected Pokemon” to your left controller’s x key. Make sure to uncheck its current function checkboxes before checking the Cobblemon function box.
Personally I find the left x button a good choice because its default function is to dash forward a bit, which I do not need as much as I need to battle wild Pokemon.
You could try binding the Throw action to your radial menu, but the problem is you have to interact with a Pokemon to trigger it, and left clicking the radial menu while you’re facing the it will harm the Pokemon!
So instead, bind the action to your x key, then when you want to battle a wild Pokemon, face it and press x on your left controller, and you will get the battle menu.
The “Open overlay” and other controls are fine to bind to the radial menu. To do this, click “Options”, then “VR Settings” then “Radial Menu”. Click the number that appears in the center and you will get more blank radial tiles. Click one of these tiles and you will get a bunch of actions you can assign to the tiles, including Cobblemon-related actions.
To use the radial menu once you’ve assigned it, click the y button on the right controller and it will open.
Happy Cobblemon’ing! I’m in the QuestCraft Discord server, user “saranicole1980” so feel free to ping me there if you have any questions!