Minecraft PC IP: play.cubecraft.net

Redned

code breaker
Team CubeCraft
💻 Developer
Apr 24, 2020
86
723
164
Pronouns
He/Him
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.

1760463949802.png


The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.

👀 If you want to hear more about how we added Bedrock support into our server, implemented custom items, entities and blocks on both Java and Bedrock, let us know!

1760464231404.png

First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

1760464534119.png

As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
1760464585846.png

Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

1760464644276.png

SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

1760464788194.png

The code used to render the Loot home menu in the Bedrock module.


1760464939373.png

The code used to render the Loot home menu in the Java module.

1760465131405.png

And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

1760465231225.png

This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

1760465308827.png

BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.

1760465644457.png

As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
 

klisee

Novice Member
Jul 3, 2021
7
19
54
Kliseexcala
klisee.com
Wow, this is a really interesting thread. It makes you realize how much goes on behind the scenes that we, as users, never see. The amount of time, devs and money that must have been required for this had to be massive

Fortunately, it all worked out well and now we can enjoy CubeCraft on the latest versions. I would honestly love to see a dedicated thread about the migration from OVH to CDN77, covering the infrastructure changes and the challenges behind it all
 

Mr Jii Gamer

Dedicated Member
Jun 10, 2022
1,431
1,670
209
Algeria
youtube.com
Pronouns
He/Him
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
Oh using java in bedrock i thought you use js or c++🤔
 
  • Heart
Reactions: Redned

Flxen

Dedicated Member
Oct 20, 2020
259
1,021
204
19
México City, México
Pronouns
He/Him
We really needed a Behind The Cube about this update, people weren't aware of how massive it was, and it's really impressive that the “translator” is no longer used.
I didn't expect bedrock support to be so native, very impressive, and congratulations on your efforts!
(Enrojecido = Redned)
 

d1kkeroan

Member
May 18, 2025
1
0
2
15
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
 
Last edited:

Snigdo69Zerus

Member
Feb 10, 2024
24
50
19
Bangladesh
Pronouns
He/Him
Wow, this is a really interesting thread. It makes you realize how much goes on behind the scenes that we, as users, never see. The amount of time, devs and money that must have been required for this had to be massive

Fortunately, it all worked out well and now we can enjoy CubeCraft on the latest versions. I would honestly love to see a dedicated thread about the migration from OVH to CDN77, covering the infrastructure changes and the challenges behind it all
I never thought, that much hard to update server to new versions. Great Developer/Staff❤ Redned
 
  • Heart
Reactions: Redned

ペッか♡

Member
Jul 16, 2025
60
49
19
24
Pronouns
She/They
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
This is what non-devs don't see
 
  • Heart
Reactions: Redned

notekproo

Member
Mar 16, 2025
11
37
14
Hiroshima, Japan
Pronouns
He/Him
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
This is a great story! Thanks for sharing it!
 
  • Heart
Reactions: Redned
Oct 10, 2024
36
29
24
Sri Lanka
Pronouns
He/Him
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
let's goooooooooo ❤️
 
  • Heart
Reactions: Redned

coolzombiee

Dedicated Member
Jun 20, 2024
927
2,307
219
Unknown
www.youtube.com
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
Wow this is amazing hearing about what is actually happening behind cube and how it actually worked, can’t wait until skyblock!
 

bubbles5804

Novice Member
Aug 18, 2023
83
84
34
england
Pronouns
He/Him
We really needed a Behind The Cube about this update, people weren't aware of how massive it was, and it's really impressive that the “translator” is no longer used.
I didn't expect bedrock support to be so native, very impressive, and congratulations on your efforts!
(Enrojecido = Redned)
Hello CubeCrafters!

Welcome back to Behind the Cube! We've been on hiatus for a while and been busy cracking out other updates over the last few years, but today I want to step back a couple years to our 1.19 server update. This was our biggest, most ambitious update we've ever performed on the network. This has allowed us to deliver far more feature-complete updates across both networks simultaneously, and completely transformed our developer experience.

This edition will dive deep into the internals our server update to 1.19, some the challenges that we encountered during our migration, and some ✨ spicy ✨ changes we’ve made on the tech side that have greatly improved our updating process. This is a juicy one, so grab a bowl of popcorn 🍿 and let’s dive right in!

👀 The 1.19 1.18 update…?


As many of you may be aware, we initially communicated our goals of updating the network to 1.19 waaaaay back in September of 2022, however in actuality, work began far earlier, prior to 1.19 even being released. Updating nearly 10 Minecraft versions was no easy feat, and required a lot of background planning and backend work.

For a bit of background…


Previously, our server platform was running on a 1.9.2 Spigot jar we updated to 1.12 and modded Bedrock support into back in 2021. Some of you may recall our Translator system we discussed in our Feelin’ Lucky Behind the Cube which sat on top of our BungeeCords. This system allowed us to support Bedrock Edition users on our existing Java infrastructure.

As we grew throughout 2020 and 2021, it became a major technical challenge for us to maintain as we started implementing native Bedrock features that are now integral to our server, such as resource packs, custom entities and custom items / blocks. We decided to go the route of removing the Translator, and turning our Java server into a full-on Bedrock server.

Moving away from our Translator proved to have a large number of benefits, including reducing player latency by 50ms - 100ms across the board. However, this came with the downside of maintaining a significant amount of code in our server software.

Updating to 1.18…


Rather than going the route of updating our 1.9-but-really-it-was-actually-1.12-server jar to 1.18, we decided to start fresh by forking Paper 1.18. The first commits to our new CubeTap project (internally known as CubeTap Junior) were in March of 2022.



The first few months of work primarily revolved around getting our new CubeTap version up to speed with our 1.12 version. We also took the opportunity to redesign core parts of our Bedrock support, such as moving to Bedrock’s server-authoritative inventory system, implementing chunk caching, and adding proper custom blocks. We also added new APIs to integrate nicely with these systems.



View attachment 241182
First look at chunks rendering for Bedrock Edition on our new software.

📔 Updating CubeCraft!


Much of the work to update the CubeCraft codebase began in July of 2022. For those of you who have worked with Spigot or Paper before may know that in 1.13, there were massive, backwards-compatible breaking changes in the Bukkit API. The internal NMS code also saw major changes, going from being heavily obfuscated to fully deobfuscated using Mojang’s code mappings. Additionally, from 1.13 - 1.18, huge amounts of the server code was rewritten.

While most of these changes were positive, essentially most anything using NMS was going to break (and boooyyy did we use a lot!) and most all 1.13+ Bukkit plugins were going to no longer be functional.

After some time, the first project we completed updating was GameFramework, which is one of our core frameworks that all our games are built on top of.


First look at a simple TNT Run game running on a local server using GameFramework.

Getting GameFramework to work was a massive milestone and meant that within a short period of time, we could actually start testing CubeCraft code on 1.19! 🎉

Within just a few weeks from this point, we had many of our other core libraries updated, such as Loot, Armoury, Play Again, etc. and by early August, had a version of Survival Games running for Java Edition 😮

View attachment 241183
As bug free as you get…

At the speed things were going, it looked as if we were going to have 1.19 out by December, just in time for our 10th anniversary! Right? Right..? Well, we’ll see… let’s not get too ahead of ourselves

🤔 What did we want out of this update?


As work continued to get all our code updated to 1.19, a question arose: what did we want to get out of this update?

I think the obvious answer everyone arrived to was: offer new features and to build potential for future content. While these are and have always been at the root of any content update at CubeCraft, we were starting to see major technical debt problems arise on our existing network.

At the time, our codebases for both Java and Bedrock were very disjointed. We maintained four separate Git branches for each project:
  • production - Contains all code live on our Java Edition server
  • production-mco - Contains all code live on our Bedrock Edition server
  • master - Contains all code live on our Java Edition development server
  • master-mco - Contains all code live on our Bedrock Edition development server
This is on top of the fact that some of our core libraries had separate versions for games using GameFramework and ones not yet migrated. This meant that there were not only 4 branches, but 8.

This ultimately meant that if a bug fix was found in team handling for instance that was present on both Java and Bedrock, that would mean a commit fixing the issue would need to be pushed to eight branches (╯°□°)╯︵ ┻━┻

Also at the time, our update process typically involved us writing the code for Java Edition first, testing it, and then merging it into our Bedrock branches, often encountering multiple merge conflicts, then updating or removing any features not relevant to Bedrock, and testing again. This is also the reason that in times past, we often released all major content updates for Java first (or even exclusively in some cases), then later Bedrock. This made any major update incredibly cumbersome and often led to very "Java-first" updates that disregarded features on Bedrock.

Since we were already making major technical changes, we decided now would be the best time to reconsider how we conducted our updates on a technical side.

🖥️ Modularising the code


Shortly after getting Survival Games functional on our Java Edition development network, @rubik_cube_man, @Alemiz, @Austin and I sat down and discussed plans on how we wanted to approach this problem. We decided that modularising the code was the best approach, creating a common module for all common code, then separate java and bedrock modules for features that vary for each platform. Rather than maintaining 4 branches, we would only need 2: one for production code and one for development code.

We then pitched the idea to the rest of the dev team and decided on a course of action.
View attachment 241184
Initial slide from our pitch deck in August of 2022

Modularising all our Bedrock and Java code together essentially meant that all updates we did would only ever need to be written once, rather than one time for Java, then tested, then updated in bits and places for Bedrock (or in some cases like MinerWare, substantially), then tested again, then finally released. We could instead streamline the process and do simultaneous testing on both platforms, allowing greater flexibility between updates and the ability to offer much more content. These changes also meant that general bug fixes in the game logic only needed to be written once, rather than individually for each platform.

View attachment 241185
SkyWars project layout today.

While the results of this modularisation have been incredibly beneficial for us today, it took us a long time to get there. There was a large amount of scope creep, unexpected challenges and many, many delays.

😟 Delays and challenges…


As we began to modularise our codebase and integrate everything together, we began to realize that many of our core libraries needed massive rewrites to cooperate well with both Java and Bedrock, or needed to be rewritten from the ground up. Systems such as our menu library, game voting system, loot, and other similar systems needed massive overhauls.

Here is a quick look at how we now create menus on our network now using the UI library we wrote as part of this migration:

View attachment 241186
The code used to render the Loot home menu in the Bedrock module.


View attachment 241187
The code used to render the Loot home menu in the Java module.

View attachment 241188
And in our common module, we can have a common open method, even if it is rendered differently on both platforms 🎉


In other instances, we found that simply having a feature switch for the player platform in the common code would be sufficient, as demonstrated with the following code:

View attachment 241189
This is a method in our floating text library, which instructs the system to use Text Display entities for Java, but Armor Stands for Bedrock, as Text Displays do not exist on Bedrock.

As amazing as these new libraries were from a development perspective, they required significant time investments to design, iterate upon, and eventually adopt across the board. For menus, CubeCraft has over 100 hundred different menus across both Java and Bedrock, whether it be the loot menu, VIP Levels menu, SkyWars features or Parkour map selection, and as you can imagine, migrating every one of them took quite a long time.

Menus were just one part of this - we also ran into various other challenges implementing platform-specific features, such as chest skins into the game. Despite the fact that we have code split up between two modules, all of the actual chest and loot table code is in the same place. We had to modify the core system responsible for this so chest skins could work fine on Bedrock without breaking Java Edition.

Our loot system needed to have significant refactors as well to support loading both Java and Bedrock loot in the same system. Certain features such as VIP Levels were only ever present on Bedrock, and required large changes to the core loot library to ensure it fit in well.

Additionally, Skyblock, one of our most technically challenging games to maintain at the time, was still using our legacy game library and needed a migration to GameFramework on top of being updated to 1.19 and integrating with our new systems. Skyblock also relied very heavily on obfuscated NMS code to function.

View attachment 241190
BlockLightStone? Don’t they know it’s called Glowstone! Silly Bukkit using 2010 names!

Skyblock was by far one of the most technically challenging games to migrate and required a lot of QA to ensure features like generators migrated over properly. The custom Skyblock world format we use needed updating to support newer game features. Migrating systems such as generators and entities away from NMS and into proper APIs added additional overhead too.

And to top it off, these migrations were only the first part of the update. Most games were still awaiting a content update too! 🤯

Unfortunately, these delays and the challenges we encountered meant that we would not have a release out before our birthday celebration :sadcat:

💡A light at the end of the tunnel


whew, okay, let’s fast forward a bit 😅

As we crunched through the migration and started to build new content on top of the all the new systems and APIs available to us, we found that our ability to deliver updates has drastically improved. No longer were we limited by legacy codebases, limited APIs and old versions. As we got towards the end of March, over three months after our initial target, we found ourselves ready to start preparing for a soft launch on Java Edition.


As we did our soft launch on Java Edition in the beginning of April, we were immediately hit with stability issues and memory leaks. While we certainly expected a number of bugs and bumps at the beginning, many of the issues we encountered were only evident at scale. Thankfully, we were able to resolve most of these within just a few days and in the span of a few weeks things seemed to be pretty in a fairly solid state 🥳

And that concludes this edition of Behind the Cube! As a team, we learned a whole lot during this migration and truly learned what it was like to push CubeCraft to it’s limits! We appreciate all of you who supported us through the migration and shared feedback, constructive criticism and simply just played on the server!

Looking back on this years later, we see the value this migration has provided for us, whether it be all the modern features in Skyblock, or games like Pillars of Fortune which give you random items from even the latest versions. Until next time 🖖
W when will it be released
 
  • Heart
Reactions: Redned
Members Online

Members online

Latest profile posts

qaliNx wrote on Capitan's profile.
Thank you for everything <3
Brent // Brentsycle wrote on Siza's profile.
Thanks you for the follow :D
Am4er wrote on Dogking7001's profile.
Happy birthday!
Thunder wrote on Siza's profile.
Thanks for the follow!
Siza wrote on Brent // Brentsycle's profile.
Hey thanks for the follow!
Top Bottom