Installing the server’s custom resource pack is an important part of playing on TheCrucibleMC. Today we’ll be diving into how we manage our assets and handle version control.
Currently, with the intention of this changing, the packs are limited to 1.12.2 versions. This is defined by the pack’s
pack.mcmeta file listing
"pack-format": 3, with each of these pack format numbers representing different version ranges in Minecraft. This can be found on the wiki and the numbers change for major update versions where things in the pack that used to work on older versions no longer work on newer ones. Two major instances of these pack formats changing are from 1.5 to 1.6, migrating a large PNG housing many textures to individual PNG files for each texture, and the 1.11 update which requires all files to be in all lowercase for them to function.
In order to update the pack to work on multiple client versions, we’ll have to accurately determine which client version any player connects with, and feed them the appropriate pack. This is proving difficult and we have not yet cracked this egg. For now, we’re sticking with 1.12.2 for both the server and all clients, as it’s the most reliable modern version that works with larger servers. We’re hopeful that 1.17 or 1.18 will bring back the huge scale that Minecraft used to be able to handle, as 1.13+ has been really hard on servers of larger playerbases. You can follow the adventure of 2b2t or Hypixel and you’ll see they’ve run into the same issues.
Currently, our entire resource pack with every asset is on a private GitHub repository that is accessible by our staff team. Whenever a change is made and the repository is updated into the master, we manually run a Discord bot I coded to pull that repo into a Jenkins server to compile it using a custom Bash script. The Jenkins workflow will dump the old assets, download them completely fresh from GitHub, compile them into a zip folder and it uploads it to our webserver through SFTP. For security, the Jenkins bot has its own keypair and account that only has access to the required folders, and not the rest of the system.
The Jenkins workflow actually uploads it once, and the webserver finds the incoming file named
TCMC_[buildnumber].zip and clones it as
TCMC_Latest.zip so the latest version of the pack is always at the same URL. This URL is not protected as it’s served directly to the client. In order to keep updates working, even while players are online,
TCMC_Latest.zip is run through a SHA-1 hash and the hash overwrites an existing HTML file with the hash contents. When a player logs in, or runs /pack ingame, the command will read this HTML content into a variable and send the pack from that URL with the specified hash. This is important for two reasons.
The first reason is that if the player already has a resource pack in their server-resource-packs folder of their Minecraft installation of the same hash, it will not download the new version as there’s no need to. The pack that’s cached is simply applied and this is much quicker for both the server and the client.
The second reason being if there’s a pack update, the next time they go to download the pack, either on log-in or via command, it will see the hash has changed and disregard the cached version in favor of the updated one. This means we can update something later on and players will still get a seamless experience.
The resource packs being held in a GitHub repository also adds backup security and version control. It’s easy to see our internal changelog and see who updated something, when it was updated, and how to revert it if something goes wrong. If a change is reverted, we can review what happened and ensure similar things don’t happen in the future.