Categories
devops virtual reality

How to play Pokemon in VR Minecraft

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.

Server side:

A Kubernetes cluster on the Oracle free tier, with the itzg minecraft chart installed and modded with Fabric and Cobblemon, all applied using Terraform

Client side:

PC-side – Modrinth client for my daughter (playing Java edition Minecraft on an Ubuntu PC) also modded with Fabric and Cobblemon

Meta Quest (VR) – Sideloaded Questcraft with the patched Fabric installer

And for good measure, I also discovered how to battle wild Pokemon in VR with this mod https://modrinth.com/mod/quest-rebound (which needs this mod https://modrinth.com/mod/owo-lib as a dependency).

Want to try your hand at this yourself? Check out this three part tutorial series!

Create a Kubernetes Cluster on Oracle Cloud for free using Terraform

Create a Modded Minecraft Server on a hosted Kubernetes Cluster

Connecting to a Cobblemon Minecraft Java Server in VR

Categories
devops kubernetes Uncategorized

Create a Kubernetes Cluster on Oracle Cloud for free using Terraform

Credit: I forked this repository https://github.com/nce/oci-free-cloud-k8s in order to create this infrastructure on Oracle Cloud. Thank you to https://github.com/nce for the awesome Terraform bootstrap!

Parent Article: How to play Pokemon in VR Minecraft

If you are starting from scratch with Terraform on Oracle, I recommend you check out their tutorial series https://developer.hashicorp.com/terraform/tutorials/oci-get-started to get familiar with the concepts.

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.

Check out my repository https://github.com/saranicole/minecraft-oci-k8s with git. You will be making use of the infra directory in this guide, so change into that in your terminal:

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 .

Manually create a single bucket in Oracle Cloud to hold your Terraform state – see https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/managingbuckets_topic-To_create_a_bucket.htm . Name it “terraform-states” or similar – this name will need to match the “bucket” parameter in backend.conf . Note the “Namespace” in the bucket details – you will need that for you backend.conf file.

You will need to create a few files to make this work.

In the infra directory:

backend.conf

general.auto.tfvars

Example backend.conf ( replace <<Storage Namespace>> with the namespace you retrieved when you created the bucket ):

namespace = "<<Storage Namespace>>"
bucket    = "terraform-states"
key       = "infra/cluster.tfstate"

Example general.auto.tfvars

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

ssh_public_key – This is the public (non-secret) component of an API Key. See https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm for an explanation of API Key authentication. Create one at https://cloud.oracle.com/identity/domains/my-profile/auth-tokens and make sure to save the private key so that you can authenticate to Terraform using the oci command line tool

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.

user_ocid – This is the OCID under “User Settings”. Copy the value from https://cloud.oracle.com/identity/domains/my-profile/details

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.

Create a Modded Minecraft Server on a hosted Kubernetes Cluster

Categories
devops minecraft

Create a Modded Minecraft Server on a hosted Kubernetes Cluster

Previous Post: Create a Kubernetes Cluster on Oracle Cloud for free using Terraform

Credit: This guy is the man, https://github.com/itzg . He maintains https://github.com/itzg/minecraft-server-charts/tree/master/charts/minecraft which is just an epic Minecraft Helm chart.

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.

So change:

backend "oci" {}

to something like

backend "s3" {}

Or whatever your preference might be. See https://developer.hashicorp.com/terraform/language/backend if you need guidance on how to choose and what it means.

Check out the repository https://github.com/saranicole/minecraft-oci-k8s with git. We will be using the minecraft directory.

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.

backend.conf

namespace = "<<Storage Namespace>>"
bucket    = "terraform-states"
key       = "infra/minecraft.tfstate"

general.auto.tfvars

chart_version = "5.1.2"

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.

At the end you will see:

Outputs:
  + my_minecraft_server_ip = "xxx.xxx.xxx.xxx"

This is your Minecraft server ip address! Connect to port 25565 with this directly, or create a friendly DNS name in your preferred way.

If connecting with the ip address you can type in these numbers in this format:

xxx.xxx.xxx.xxx:25565

I recommend https://www.duckdns.org/ as a convenient way to give your Minecraft server a friendly url.

Way to go! You now have a Minecraft server in your preferred configuration set up on your Kubernetes cluster.

Interested in more? Take a look at the last blog post in this series:

Connecting to a Cobblemon Minecraft Java Server in VR

Categories
minecraft virtual reality

Connecting to a Cobblemon Minecraft Java Server in VR

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!

Also, grab the Fabric API jar at 0.116.9 – https://cdn.modrinth.com/data/P7dR8mSH/versions/yGAe1owa/fabric-api-0.116.9%2B1.21.1.jar and https://cdn.modrinth.com/data/nOK0dI1c/versions/rKDl7Dxe/request-1.0.0%2B1.21.1.jar and https://cdn.modrinth.com/data/ccKDOlHs/versions/JB1fLQnc/owo-lib-0.12.15.4%2B1.21.jar while you are at it. These are the Quest-Rebound jars which enable battling Pokemon. You will need to install all of these mods in your mods folder on your headset.

Once you have successfully connected to a single player world, you will need to back out of the game and connect to the headset using SideQuest again.

Click the folder on the top bar which is how you can navigate the Quest’s directory structure.

………………………………………. This one
…………………………………………….

Then you will want to navigate to:

Android > data > com.qcxr.qcxr > files > instances > 1.21.1 > mods

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!