-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
general issue with resource routing to buildings #490
Comments
Maybe automatically decrement the requested counter by one every so often? And decrement it by two every time a resource is delivered?? Or, it may be possible to scan every single flag and serf to find resources in transit and update all building requested counts to match those destinations. It seems that the game does try to account for every resource, and if one is lost it calls cancel_transported_resource for dest. @Vershner mentioned that in the original Settlers1/SerfCity game there is a known bug where building a warehouse can result in resources becoming unroutable from castle/warehouse to buildings, and only directly routable resources can then be moved (i.e. unknown_dest). I wonder if this is all related Hmm... maybe the issue is that when flags fill all their resource slots, and serfs start moving those resources to the next flag over to clear space... that the requested resources are still technically en-route but so far backlogged as to be worthless? I am going to try two things...
It seems reasonable to set some kind of fallback where if a resource was requested long ago and hasn't arrived yet, to assume it will never arrive and request it again. And if it finally arrives later, send it back if there is no room. I was doing some testing with detecting missing transporters on flags, and realized that the only safe way to do it is to figure out how many tiles away the inventory dispatching the serf is, and adjust the acceptable wait time based on the distance. This approach would also work for requesting resources. If the castle is a hundred tiles away, the building should wait 5x longer before giving up than if the castle were twenty tiles away. |
I think the game really did lose track of the requested resources. I don't see a single dest = <flag of iron mine> anywhere in the save game file. And if I demolish all the roads and flags with piled up resources the iron mines still never get any food. |
I wrote some code to search all flags and all transporting serfs for food resources with transporting dest of a mine flag, and it rarely equals out. For the "broken" mine no resources are found, as I suspected. For a new mine I can find the resources, but often I see some are unaccounted for, or many more are destined for the mine than the requested count! Maybe my approach is wrong, but I am thinking some kind of timeout is needed to cancel resource requests that are never fulfilled. |
In my fork I have implemented timeouts for resource requests, and transport prioritization of resources that are destined for a non-Inventory. This effectively fixes the issues described above with little change in the way the game plays. I would prefer to make resource tracking perfect, if possible, so that this is not necessary. But I am not sure if it is possible. Maybe at some future time. |
thank you for such a detailed analysis! as to the original bug, why not do a bookkeeping pass once a couple of seconds to see if real resources en route match to ordered resources for each building. Such a pass will not substantially harm performance. or this pass could be ordered only when a resource went missing or was derouted (taken back into a warehouse due to a congestion at the flag - I am not sure if the resource loses its original dest in this case, but I think it does) There is actually a way of tracking the resources in real time with very little additional performance penalty by ensuring that the game has proper logic for "resource routed" and "resource destroyed or derouted". |
I believe that either one of two approaches will work
My retry logic so far seems to be working fine, because I have forgotten about its existence. Another option to retrying would e for all resource buildings to simply always demand more resources until they are full. Maybe somehow rate-limiting the request rate. This might make more sense if tracking all the resource timeouts becomes a bottleneck. |
allready known for me, solution is rework of resource requesting-delivering loop: tlongstretch can u paste here what u did (if u) allready implement or link to filename/rows, ill update my code, ill try to use your solution as start point |
@p1plp1, the code to do this is scattered around across various functions, however I believe I've noted them all in the comments. If you check out the feature_addition branch of my code at https://github.com/tlongstretch/freeserf-with-AI-plus/commits/feature_addition and search the actual code for 'resource timeout' you'll see the resource timeout stuff. the prioritization of non-stockpiled resources is simpler, inside Flag::prioritize_pickup : void for (int i = 0; i < FLAG_MAX_RES_COUNT; i++) { other_end_dir[dir] &= 0x78; |
@sternenzaehler, when I tried adding a function to track the resources en-route to a given building, it showed unpredictable results. I didn't spend a lot of time on it, but it made me think trying to track all resources using the current routing scheme is difficult |
Of course both ways would work and your preferred way would work too. not getting a resource because of a bug is bad and must be fixed. But not getting a resource due to a congestion is part of a gameplay, we just need to be aware that fixing this would constitute a gameplay change. |
I agree that is not an easy task. But maybe it is easier if we only track the cases where a resource is destroyed - there are only so many such cases (flag deletion by user, flag deletion due to land acquisition by the enemy, flag with resources ceded to enemy, road deleted under the carrying serf (by user or by the enemy), warehouse burnt down with that resource already in the outqueue but not yet out). If all resource destruction is accounted for then a resource wont get lost (provided there are no other bugs). |
I believe that the game properly accounts for resources being lost, at least in most cases, and preperly re-sends them. I suspect Freeserf is more buggy than the original game and loses more resources. And I agree with you that using resource prioritization to manage congestion is a gameplay feature, but in my eyes it seems to result in even more "cheating" in that the player can simply delete flags with resource congestion, and delete buildings that aren't getting built and re-place them. My intent is to document all of these changes and make them checkbox-optional and not on by default. But when I play, I will be using them :) |
This makes me think of another possible "cheating" solution... have a "okay to dispose of these resources" list that Player can adjust much like other Res priorities. So if a Flag's slots are all full, and a Serf would otherwise have to carry those resources to a nearby flag to clear space, if the carried resource (or maybe even one already at the flag) is on the Purgeable list, the least important one will be disposed of. Some micromanaging is fun, some is annoying... I'm going to try playing around with it and see |
I saw an issue in one game where an iron mine wasn't being sent food despite having the highest mine-food priority and the nearby stock having tons of stored food. Upon investigation I think I found an issue with the core building resource requesting logic:
If I modify this bit of code:
To this:
It will start receiving food again. However, if I am understanding the 'prio' bit-math, it will still be (de)prioritized as if it were nearly full.
Something either needs to track and detect every resource en-route to a building and decrement the requested value if that resource is lost, or buildings need to be always requesting resources and if/when too many arrive they just let them be sent back. Maybe throttle the number of resources destined for each building so it doesn't get too many in-flight resources, or have some check that periodically resets the requested counter to zero?
I see there is a Building::fix_priority function
that is called when schedule_unknown_dest_cb is used (routing "routable resources" directly from producers to requesting buildings, rather than pulling from a stock) but I am not sure if this is relevant to the issue I'm describing.
I don't know if this is a Freeserf issue, an original SerfCity/Settlers1 issue, or if I'm misunderstanding another issue.
The text was updated successfully, but these errors were encountered: