Porting Minecraft minigame Bedwars to Hytale (the new voxel rpg game by Hypixel authors).
AI was only used to help me better understand how to use async in Kotlin. All of the remaining code was written purely by hand.
Porting Minecraft minigame Bedwars to Hytale (the new voxel rpg game by Hypixel authors).
AI was only used to help me better understand how to use async in Kotlin. All of the remaining code was written purely by hand.
Wohoo!
I made a Bedwars plugin for Hytale, the new voxel rpg game. Or at least half of it, since I didnât manage to finish it. It was fun, and Iâm looking forward to continue the development.
Definitely debugging weird issues coming from quirks of Hytale being in alpha state, and having to fight some of itâs limitations. The fact that there isnât much documentation also makes thing hard, because you have to figure out a lot of stuff by trial and error.
Definitely the shop UI - I really like how it turned out, despite being made just in the last two days. It uses the UI system to itâs potential, conveing more then a Minecraft chest GUI, while still being quite compact.
Iâm also happy that many things in the project are data driven and can be changed from the asset edit. This even includes things like teams. Ever wanted a Teal or Violet team? Make it.
The end of Flavortown is upon us, and itâs closer than you think, donât look!
looks
Itâs literally 7 hours till end, and it is 12pm in my timezone.
SCREAMS
However I managed to do some quite nice changes in the last two days, so letâs quickly check them out.
Most importantly I managed to finish (or at least make quite functional) the item shop GUI.
Thanks to the Hytaleâs custom UI system it looks much better to its Minecraft counterpart.
I wanted to keep the familiar simplicity of chest guis, while conveying more information.
So I decided on a simple widget for each item composed of itâs price, the resource it costs as a smaller 32x32 slot, and a bigger 64x64 slot displaying the item you are buying. I also made the border of the price icon glow green if you can afford the item to help quickly identify what you can and cannot buy. Additionally when you buy something you get a pickup notification in the corner. Similarly you get a notification if you try to buy an item you cannot afford. The best would be displaying the playerâs inventory under the shop, but Hytale doesnât give you that ability yet, so we must do with what we have.
I also added a shopkeeper npc that opens the shop, which is just a slightly modified klops merchant from vanilla Hytale. Despite that I had to make 3 new boilerplateây classes to open the shop gui from an npc.
Finally I quite a critical bug concerning map loading. The game sometimes failed to load, because sync chunk loading took too long. I had to quickly replace it with async loading.
With that fixed, thatâs it for Flavortown, so thank you for taking the road with me, I hope you enjoyed it!
Log in to leave a comment
âSo, 7,5 hours passed, what did you do?â
âTabNavigationâ
âwhat? like you implemented some advanced ui navigation system?â
âTabNavigation. I implemented TabNavigation. An empty page which has tabs at the top you can switchâ
âWAT?â
No, I did more, but from the time counted here, getting the built-in into Hytale TabNavigation ui component literally took 5 or 6 hours.
Why you may ask?
Well, the tabs are supposed to be set up dynamically from the code based on json, and as it turns out there is no api in Hytale to do that. Hytale is mostly an undocumented project, which means that you discover how to do things by reading existing code of the game, and trial and error. I spent hours trying out different functions and parameters just to add few tabs to the TabNavigationui component provided by the game.<br>
Nothing worked, which drained my motivation, and the real life got busy which made me take a break from the project.<br>
Fortunetely, when I came back few weeks later, I found that some folks in the HytaleModding discord figured out a workaround, which involved calling a private method via Java reflection, and manually assembling the json to be sent to the client. (For context ui is controlled server side in Hytale, and changes to it are sent to the client as a list of commands (like add, append, delete) in json).<br>
After understanding how it works, I implemented my own solution, which instead of messing with json used java reflection to register a custom data class which I namedNavigationTabrepresenting the tab in the api. That made it possible to call the standardsetmethod with aList`, which were then serialized properly by the game and sent to the client, making the tabs finally work.
After that I encountered an another problem. I was hoping to use the textures of items and the game as icons as it is commonly done in Minecraft, but it seems that Hytale is unable to use any textures placed outside of the Common/UI folder in an asset pack for UI, and the icons are located in Common/Icons :(
So I will probably have to use some custom textures, or copy them over to the Common/UI directory.
One more thing worth noting off is that I also refactored the code to make it compile on the latest Hytale pre-releases, which removed all Vector types like Vector3d and Vector3f (classes keeping x,y,z values, used for positions and rotations of everything), and replaced them with their counterparts from JOML (Java OpenGL Math Library).
Thatâs it for today, bye!
Log in to leave a comment
The countdown has got sounds, and now something actually happens after it.
The players get teleported to the islands. This also means a team assigning algorthm is in place. It is not perfect, but it should work pretty well, and it has it already accounted for an integration with a party system.
Any unnecesary marker entities get removed and the generators start spawning resources. They also got a title that displays when an item will spawn (for diamonds/emeralds), and the items now donât stack, so you can clearly see when there is many of them.
Blocks are now protected from destruction, though for now it affects everything including the bed and anything the player places. This will be fixed once I will have other systems required for it in place.
I also have a shopkeepers system work in progress, but time is running out and I didnât manage to finish them, so they will be in the next blogpost.
Log in to leave a comment
After adding a fix to make sure chunks are loaded during validation map editing is mostly finished.
This means we can start working on the actual gameplay.
So, after a bunch of coding, we got an API (and command to invoke it for testing) that creates a new bedwars game, by creating a copy of a map, finding all queue spawnpoints and teleporting players to one of them. The world is automatically managed, and removed after all players leave (because no one wanted to play or the game ended). We also got ourselves a countdown that⌠counts down to the game start.
Log in to leave a comment
Map editing has got an enitre validation system, which ensures that map setup gets completed, before it can be played.
It makes sure that there are at least two different teams placed on the map, and a place for players waiting for game to start is selected. Those warnings can be checked with new /bw map validate command. The player is also warned when leaving the map if it isnât ready to be played.
A Snapper Tool has also been added, which can be used to snap entities to block grid centers and edges, allowing for more precise placement of spawnpoints and generators.
The marker entities for spawnpoints have also been added, and all of them got new textures.
Log in to leave a comment
I added two new assets: BedwarsTeam and BedwarsMap
The first one defines bedwars teams, letting you assign a colour and a name to each of them.
The second one stores neccesary metadata about bedwars maps, such as the amount of teams it can support. It is automatically created when you create a bedwars map with a command. Getting this to work took a lot of struggle and my time. For some reason trying to save the asset to a file was locking up the entire server.
After a lot of debugging, I realized hytalemodding.dev was wrong, and made me think my code is executing async, while it was executing on the world thread (which caused the problem). I sent a PR to them to correct that, and adjusted my code, which solved the problem. I in the end I heavily reworte the involved code. First I removed the use of CompletableFutures, because they annoyed me. Then I made it use Kotlin coroutines, after learning how to use them, which finally made the code more bearable. I also changed the error handling to use a custom exception to contain a formatted, translatable message.
While not very much productive for the features, this session did a bunch of good things for the code, which should accelerate things in the future.
PS: I made the /bw map list command work by using the new map asset
Log in to leave a comment
You can now exit the edited bedwars map, and then return it. This took longer then expected to implement due to some issues with world lifecycle management and teleportation. The code responsible for managing maps also got some better organization.
Log in to leave a comment
A friend said.
I agreed.
I hope he was right.
Kotlin is pretty weird in my opinion, like Java + Python, but it also had to do a bunch of things in its own way, without s clear reason why. But it has null safety without having to write @Nonnull everywhere, and dunks on java getters and setters which are pure boilerplate (and were starting to annoy me). That + a nudge from a friend is enough for me to go for it.
So yeah, I refactored the project into Kotlin and I hope it pays off in the long term.
Note that I deleted some unused files, so the added to removed ratio is off, I didnât save whole 250 lines just by switching to Kotlin.
Log in to leave a comment
Or 10 of them?
I fixed the generators disappearing after server restart.
The culprit of it was NetworkId component, which assigns an unique integer id to every entity, and lets the server communicate to the client which entity it is talking about. The problem? They are manual! You need to assign a NetworkId when you spawn an entity (which I did), but you also need to assign one, once the server loads the entity from storage!
After I added an ECS system to do so, a bunch of generators, which were saved, just not visible, showed up.
Log in to leave a comment
The work on item generators continues, and Iâm baffled to see that this devlog is representing 9 hours of coding - time passes quickly.
There is however a nice list of changes:
/bedwars spawn generator command, instead of using the entity tool, which is a side effect of moving generators to code.Log in to leave a comment
And it is flying away!
But it is working, dropping items as it should.
The reason it is flying away is that entities made with json need a movement type, and by default the âFlyâ type keeps going forward it seems. Iâll find a fix for it.
On the recording items are also spawning in slightly incorrect location, which is already fixed.
The setup is done, so the development can finally take off, and the devlogs will be actually interesting and more frequent now.
We are starting with a /bedwars command fresh from the oven. The command will be used to manage bedwars maps, and to start a game without using the API.
I have not explored Hytale modding much yet, but I do love it already.
I just registered the commands structure, and look what I get for free - an entire help menu for my command that is automatically generated.
Log in to leave a comment
So, how long does it take to setup the dependencies and run something that released 2 days ago in a dev environment?
5min? 10min? 15min?
Yes, it is 15 minutes, unless you are also running your IDE inside flatpak, using the kotlin build scripts for the first time, and trying to follow two different templates at once, which happens to be me.
In that case it takes 2 hours.
And then, the next day I find myself deleting all the changes I made, because a gradle plugin got released in the meantime, which does the same job better.
The plugin had few little things missing, so I spent some time working on it, made a PR, and talked a little with the author.
Today I also made another PR, which instantly got closed, becaused I and the author coded the exact same feature in the exact same time. đ
With all the changes made the gradle plugin has all the features it needs, and thus I present to you:
The smallest, cleanest build.gradle.kts file you have ever seen
Log in to leave a comment
As I am writing this, we are 2 hours apart from Hytale release. This means that the main work will soon be able to take off.
In the time from project start to now, I have made the BedwarsTracker tool (which is also available to try out on github btw.), wrote the code for an item generator, and most importantly spent much time experimenting with json, to get a good hang of what will work well as Hytale Assets for configuring the plugin.
For example teams will be data driven, meaning you can create as many (or few) as you want.
Log in to leave a comment
Iâm creating an exact replica of the Hypixel Bedwars, which means I need to know how fast iron and gold spawns in generators.
I tried to count this by hand but it was very cumbersome and error prone. I also had to sit in the forge which meant so I couldnât defend the bed. So I created a Minecraft mod, that will do this for me.
First I tried tracking items being added to the playerâs hotbar, and it worked, but I still had to sit in the generator.
So with second attempt I started tracking item entity spawns, which didnât rely on the player. After implementing that I could play as long as I didnât go too far away from the forge, because then the items would not spawn client side. The server spawns them back after coming back close, which I also had to account for, to not have duplicated data.
The mod generates a CSV file with raw data, that needs to be analyzed. So I
wrote a python script which:
Seeing a chart lead to an interesting discovery:
Did you know that generators are at least 2x faster during the first 30 seconds of the game? I certainly didnât.
In the end, this yields us the attached charts.
Note: As you can see the algorithm stops working very well after you upgrade the forge, because the data is a bit weird. I might spend some time later to fix that, but for now this is enough.
Log in to leave a comment