Released: Factory Farming

Now at release candidate 4, there have been a number of additional quality-of-life suggestions and fixes

  • Fixed bug getting stuck walking after an auto-save
  • Updated sound effects on options which don't toggle any more
  • Demolition with 90% cash-back mechanic is replaced with Deconstruction -> this returns buildings/crops/utility items to the player's inventory
  • Prices also update in the shop or sales with crank buy/sell multiplier
  • Buy/sell multiplier resets on exit of the shop / sales, and no longer cycles
  • Made the screenshot and load procedures asynchronous (generation and saving were already asynchronous), added progress display to saving/loading/generating/screenshotting.
  • Removed auto-save on lock and exit, could not guarantee save within the allotted 10s window.
  • Optimised sprite creation for cargo
  • Finished game balance changes and text
  • Updated some conveyor belt graphics for better clarity

I also already binned the "Desire To Move" system I posted about a little over a week ago in favour of a slightly faster and hopefully an overall better solution.

The quick recap of the problem to solve is how to move cargo from A -> B, and from B -> C when A and B are both occupied and C is clear. It works when we first move from B -> C, then move from A -> B, but what about if we happen to iterate over A before we iterate over B? What if it's not A -> B -> C but is instead A -> B -> ... -> X -> Y where there is cargo everywhere except for Y?

The new solution is to harness the power of recursion! If A wants to move to B, but B is blocked by another cargo, then A attempts to call B's update function (there is still code in place from before such that each entity will only run its update function once per tick). B can then try move its cargo into C, or if C was also blocked it could recursively call C's update function, which could call D's etc. etc.. This cascading call will snowball down the conveyor belt until it reaches a dead end, or it reaches a point where the cargo can move into an empty space. At this point the stack unwinds, and as it does so each of the cargo move forward one tile into the newly freed space.

I need to figure out what the stack size is on the PD, but I also set a hard-limit at a recursive call of 128 levels deep which should be pushing something like 1 kB on the stack. Hopefully safe, to be tested...

This alternate approach came with additional bonuses:

  • I could also wire in sources and sinks of cargo to the system. Sources (harvesters, factories) are able to start a recursive call into a chain of conveyors in order to try and free space to place a new item. Sinks (sales depot, factories) are able to receive (but nor propagate) recursive calls - allowing them to consume a cargo and leave space for another to be moved onto the tile.
  • Conveyor splitters only cycle through their outputs if the output is free, but it was hard to know if a given output was free (for the same reason as above). Now after a splitter has moved an item, it can make a recursive update call down the next output in order to check if it is free or not. This makes the splitters work much more "as expected" rather than often taking more than one item before moving to the next output.

It also has at least one downside, a recursive chain starting off-screen (where the updates are infrequent but large) can end up cascading down and finding an empty spot on-screen, causing the visible end of the stack of cargo to lurch forward by one tile! So far this has happened pretty infrequently, though I'm considering what I can do to keep this recursive update method only operating on the off-screen parts of the factory...

My non-device testing suggests this solution is around 1/3 faster than maintaining and reverse-iterating over an array of conveyors whose cargo wants to move, but cannot due to being blocked. With this solution there is no additional chunk of code of logic to be processed after the loop over buildings, but each building can now receive multiple update calls in a given tick (even though they will only action the first, and will return quickly for the later ones).

RC4 is currently under testing over on the discord, with the goal of better stress testing the megafactory on-device. The megafactory was the next thing to be made after the factory posed above on Oct 19th, I wired the screenshot feature into autosave for this one to get a nice time lapse.

factory_farming_timelaps

6 Likes