Minecolonies & Waypoints & Tons of Fixes

in utopian-io •  6 years ago 

Hey everyone, I had a really productive weekend after the end of the semester and I got a lot of old bugs flattened out and things added to the mod.

Waypoint rendering:

First of all, I added back the waypoint rendering. Minecolonies adds waypoints on structures like streets and lamps etc. to help the pathfinding of the citizen. We do this since Minecraft pathfinding is very costly and, therefore, we added our own system based on waypoints which we deploy all over the colony. But, unfortunately, after updating a few of our rendering classes our all system to render these points didn't work anymore and we had to rewrite it.

For this, we have a client event handler class.

Which in turn has to subscribe to the render event which is being called every render tick on the client.

From there, we check if the user wants to render a structure with a waypoint in it atm. And, if so, if this structure belongs to the waypoint group (infrastructure) and if it is inside a valid colony.

Now, we calculate the relative position of the player entity in relation to which we will have to render the waypoints.

Then, we instantiate a structure template of the waypoint itself (Only needs to be done once per client session for performance reasons).

Afterward, we only have to run through all waypoints within a colony.
Calculate the relative position compared to the player.
And call our template renderer for each of this positions and offsets.

Fixes:

Now, while I was debugging the colony I ran into a whole bunch of fixes all over our systems. I spent 2 full days debugging a colony flattening out all bugs which annoyed me on the way.

As small visual bugs as too long lists:

As guards teleporting on roofs because they are stuck, which I prevented by limiting the y difference they can teleport.

As fixing an issue where citizens should sleep during barbarian attacks but they didn't obey because we handled it in the AI and not in the decision if they should sleep or not.

So I added the above to the sleep decision and removed it from the AI.

I also fixed the death penalty of citizens when barbarians are close:

If a citizen gets killed by a player in a colony the happiness of the colony falls to 1, but sometimes they are killed by accident while fighting the barbarians, so they shouldn't affect the happiness so strongly.

The problem was that a new citizen with the wrong position had been taken to check the position and not the citizen we were executing this in.

We also had to make sure that the horde is calculated correctly as barbarians might not be killed and might despawn.

Therefore, we added a cleanup task to the method which checks if the entity still exists.

And finally, what took me weeks to figure out:

Request System fixes:

Minecolonies is built on top of a complex request system which allows workers to do asynchronous and synchronous requests (blocking and non-blocking).

Now, I fixed one small bug, which triggered two other bugs which I resolved afterward.

I had placed a cook which requested food, but although there was food in the warehouse the deliveryman didn't deliver it.

I debugged this and found out that the request only tries to resolve exact quantity matches.

Therefore, I removed the exact quantity match of all requests.

etc...

Unfortunately, sometimes workers like the cook and smelter executed async requests and got stuck in an infinite resolving loop.
I only recently found out that this happens because their building tries to resolve their requests.

After I had deployed the above fix this started happening really often and I found out this was caused by the following:

The cook wants to have at least 120 food at all times at his building to be able to supply all possible workers
The cook will request 64 food since he has less than 120.
The cooks building notices it has 20 food which is not enough, but since it doesn't need to resolve it exactly it will tell the cook that it can solve the request.
The cook will then try to pick it up and notices he hasn't enough and he creates another request which in turn the building instantly accepts.

After I found out how this was happening I figured that buildings actually do not need to resolve non-blocking requests since all over our code, the AI actually checks if the buildings have enough and then requests if not, or retrieves from the building if it has the required item.
This means the building resolver should skip these.

Therefore, I added a check to the building resolver to avoid resolving asyn tasks:

if (building.getCitizenForRequest(request.getToken()).isPresent() && building.getCitizenForRequest(request.getToken()).get().isRequestAsync(request.getToken()))
{
    return false;
}

and I added to the resolver that the async task list is filled before sending the request to the system to be assigned to a resolver.
(Else the resolver wouldn't be able to detect it).

/**
     * Create a request for a citizen.
     * @param citizenData the data of the citizen.
     * @param requested the request to create.
     * @param async if async or not.
     * @param <R> the type of the request.
     * @return the Token of the request.
     */
    public <R extends IRequestable> IToken<?> createRequest(@NotNull final CitizenData citizenData, @NotNull final R requested, final boolean async)
     {
        final IToken requestToken = colony.getRequestManager().createRequest(requester, requested);
        if (async)
        {
            citizenData.getJob().getAsyncRequests().add(requestToken);
        }
        addRequestToMaps(citizenData.getId(), requestToken, TypeToken.of(requested.getClass()));
 
        colony.getRequestManager().assignRequest(requestToken);

And then to the calling methods, the boolean if async or not:

But the happy end was not quite there yet.

After deploying this I noticed that the loop was broken but that the worker requested it and the request was only once checked against the resolvers and then never again touched.
I debugged the retrying resolver for a while until I noticed that it didn't have a correct instance of the request manager to reassign the request.

What I quickly fixed by assigning a valid one before each call to the resolver.

Our players are pretty psyched by the new update since it will make minecolonies way more stable and the cook finally a reliable provider of food in their colony.

I hope you enjoyed this little update. Until the next time!

Pull requests:
https://github.com/ldtteam/minecolonies/pull/2630/files
https://github.com/ldtteam/minecolonies/pull/2627

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  
  • Great work, beautiful code.
  • Did that issue get resolved?

return OreDictionary.itemMatches(getStack(), stack, matchMeta);
Please revert this Change. This contraticts the other behaviour of Stack.

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? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Yeah, we discussed this over Discord.
The function has two possible returns, and the second return was already matching it independent of the stack size, and he hadn't seen that.

Great work as always. Keep them coming, they’re a joy to review.

Thanks, I'm always glad to get some time to work on this project.
It's starting to get really exciting because it's getting really stable and really close to a propper release.

Mine Colonies is an awesome mod, need to start a new world with my son and give it a go again.

We've had a bunch of progress in the last months, it should be quite a smooth experience now

I am not a dev myself, but it's always really entertaining for me to read such posts here, thanks a lot for sharing!
I've actually been doing some "historical" gaming posts lately, covering noteworthy games released in certain years (just made two about 93 and 2000) and I was wondering if you also work on any projects of your own?

As you are Debugging it will certainly solve your problem.Eager to play it when completed. @raycoms

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

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

Vote for Utopian Witness!