Structure Backend Rework

in #utopian-io5 years ago

Hi everyone, on the way of working towards bringing Minecolonies to the newest Minecraft version we decided to rework some things around our Backend first to make the actual process smoother.

A while ago another coder reworked a part of our backend to include his "Blueprint" format to decrease the file size of our jar since the templates we were using were relatively big.
In this context, he fiddled them in while our main system would still load them as templates.
Nevertheless, this is a dependency on the Minecraft libraries we don't actually need.

Besides that, due to many small ports between system, our handling got really complex.

We got a Structure class which loaded a StructureWrapper, loading the StructureProxy, loading the Structure which contained the Template.

All of this I wanted to make straightforward by only having 1 Structure Class which contains the Blueprint.

Now, this took me many hours and seeing the changes in code is quite difficult due to the immense quantity of changes.

Utilities:

One of the first things I did was creating a few utility classes to reduce the size of the classes.

One example is the BlockInfo class. While Minecraft has its own BlockInfo it contains a lot of information we don't need and fills up the memory unnecessarily.

Similarly, the placement settings object which I also found uncomfortable to handle.

Besides that, I moved all methods related to loading Structures from files to the StructureLoadingUtils.

Everything related to placing Structures.

And, everything else which didn't fit in the previous two went into the general structure utils.

Blueprint changes:

The blueprint file needed some additional love as well since it would be used instead of the template now.

For performance reasons I transformed the palette array (containing the different blocks) to an ArrayList

And the one-dimensional list of entities and tile entities transformed into a three dimensional to be able to iterate it quicker when placing them in the right order.

On load, I would then load the tileEntities in the three-dimensional structure.

And the same thing for the entities.

Besides that, I needed an extra method to construct a blueprint slowly from a list of blocks.

I would do this by having a method to add a blockState at a position.
I would check if the block is in the palette and else add it and then add it to the structure.

To make sure we get the entities and block info as a list for rendering them (not placing) I also had to create a method transforming the arrays.

And finally, I had to add a way to rotate and mirror it.

First I would transform the size and create placeholders for the data in the structure.

Then I would rotate and mirror the blocks themselves and store them already.

Then, in the next, main step we run through the entire structure, transform the position of each block, entity, and tileEntity and fill it in the placeholder lists we created earlier.

While we're at it we store the offset position of the block we rotate it around.

The proxies:

Now, as I earlier said we would restrict it to one proxy class to the blueprint which is the Structure class.

This class would contain everything related to placement progress.

As well as the world, position, blueprint and progress.

Finally, there was one type of class missing.

The type of class allowing me to place a structure instantly.

The instant placer holds a structure to store the progress and takes care of caching all these things accordingly.

The Aftermath:

But the biggest task was still to come, after reworking all of this I had to refactor the entire code to accept the newly created utility classes and proxies.

Also, I removed all the code at the places where we were trying to supply double compatibility.

And Minecolonies?

On the side of Minecolonies, we also had to adapt things to guarantee compatibility.

So I had to adapt it to all the places.

All other 200 places are hidden since I don't want to overload the blockchain =P

This will make porting easier but also make it much easier to take care of structure handling in general since we don't have to do:

structure.getStructureWrapper().getStructureProxy().getStructure().getTemplate()

I hope this will make things much easier in the long run.
I am enjoying it already.

Pull Request:

https://github.com/ldtteam/Structurize/pull/23
https://github.com/ldtteam/minecolonies/pull/3411

Repository:

https://github.com/ldtteam/Structurize
https://github.com/ldtteam/minecolonies

Sort:  

Thank you for your contribution! This looks like a big chunk of refactoring- need to add some tests to your new classes and code changes.

You might want to extract this into a variable i.e. the isBluePrintMissing may be costly to run twice. Also, I have seen thise appearing more than once - which hints a code smell.

You may be able to unroll the loop i.e put the if outside the for loop to achieve a better performance here.

I have seen code moving around and other bits of refactoring, as I have a bit concern that: does it break existing tests, if there are any?

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thanks for the review, I was mainly changing some backend and then refactoring so I didn't want to focus on fixing code smells or performance issues which would be difficult to review.

It actually broke here and there some small things which we detected and fixed relatively quickly afterward.

In terms of tests, we have basically no unit tests at all with Structurize since most things are almost impossible to simulate as we would have to mock the entire Minecraft world.

Thank you for your review, @justyy! Keep up the good work!

Hi @raycoms!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hi, @raycoms!

You just got a 9.64% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.

@raycoms You have received a 100% upvote from @botreporter because this post did not use any bidbots and you have not used bidbots in the last 30 days!

Upvoting this comment will help keep this service running.

This post has been included in the latest edition of SoS Daily News - a digest of all the latest news on the Steem blockchain.

Hey, @raycoms!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.18
TRX 0.16
JST 0.031
BTC 63619.61
ETH 2698.75
USDT 1.00
SBD 2.59