shapez.io
shapez.io copied to clipboard
[BUG] Splitter behaviour with patterned input
This is more of a game design issue than a programming bug.
Because the balancer has very simple behaviour of simply alternating each input, if the input you are providing to it has a pattern you get the surprising behaviour of sorting the input rather than splitting it. For example, if your input is composed of left and right semicircles alternated (so LRLRLR... etc.), a balancer will give you a lane of L and a lane of R.
This is a bit annoying because it makes simple mechanical setups to produce every simple results from a shape much more frustrating to build, and this is something you'd probably want to do towards the start of the game. If the balancer actually split in this case, you could do something like:

but that setup doesn't reliably produce up or down semicircles.
I don't think this warrants an issue: it would be cool and all if it worked, but this just isn't something you can cleanly implement into the game
If I understand the desired behavior right, that each distinct input shape should be split onto the output belts separately and independently of any other input shapes, then I think the only way to implement that would be for each and every balancer to keep a list of all the shapes it has seen, and where that shape was last sent. That list could very quickly grow very large, which would make the game take a lot of memory, and probably slow things down significantly. Therefore, I don't consider this feasible.
Also, that behavior would break the balancer for a different use case, where the two output belts need to have the same number of items on them (regardless of what those items actually are). With the asked-for behavior, if the incoming items arrived in a bad order, it would try to put all (or most) of them on just one output belt, leaving the other empty. As-is, the balancer has a simple behavior that is easy to reason about - it balances the output belts (not the items) such that they are filled at the same rate (as long as they are not full, and assuming a constant input rate).
Honestly, I don't really see why you would want some-of-everything like this on one belt to start with, especially early-game when you don't have the filter and thus can't sort the shapes onto their own belts for further processing. I suppose that could just be different play styles making me miss the obvious, though...
Assuming you do actually want this, current early-level game mechanics already allows making reliable machines for it without too much trouble (assuming you don't need equal proportions of each shape). Here's one I threw together at level 5, partially based on your design:

It only uses each balancer as either a merger, or a splitter of a single shape, thus avoiding the problem of which shape goes where. It's admittedly 3 times as wide as yours, and uses more buildings, but it's not hard to construct. Leaving out the left- and right-side split+rotate+merge blocks makes it not do the top and bottom half-circles, just the left and right ones, but still reliably.
If I understand the desired behavior right, that each distinct input shape should be split onto the output belts separately and independently of any other input shapes, then I think the only way to implement that would be for each and every balancer to keep a list of all the shapes it has seen, and where that shape was last sent. That list could very quickly grow very large, which would make the game take a lot of memory, and probably slow things down significantly. Therefore, I don't consider this feasible.
That's actually how splitters used to work in Factorio (see the discussion at the bottom of this Friday Facts), but they changed it to work more like the way they work currently in Shapez. I appreciate that the things you can pull off in a C++ engine you've developed from scratch for your game are different to what you can pull off in Javascript, though; I'm not sure if there's another way to deal with the issue. It's just something that came up when I tried playing the game that is, I think, an issue.
To try to explain the process that led to me wanting this behaviour:
- I noticed that lots of different cuts/rotations of shapes are required for upgrades and stage progression. I don't know what ones I actually need.
- I have the idea to generate all the configurations of a shape - and later all the configurations of all the colours of a shape via a similar setup - because then I can just feed whatever I want into this "make all the simple variants" machine and build lots of them, getting everything I might need for upgrades and stages.
- The machines in Shapez perform an operation that makes sense for arbitrary inputs, so it made sense to me to combine the output cases.
The problem is exacerbated by there being so many machines that produce two outputs at the same time. If the left/right item ordering from the cutter was random - or even just alternated - this would be much less of an issue. But I imagine people rely on the deterministic behaviour elsewhere?
Thinking about it, this would also be a problem if you had two fully-compressed inputs, one of item A and one of item B, and you wanted to make two outputs both containing a balanced mix of A and B.
Aaah, for upgrades and such, piping the mixed output directly into the hub. I didn't consider that.
The screenshot suggests you're at level 8, so a minor spoiler warning for this paragraph... before too long, you'll find that the shapes for the later upgrades and stages get more complicated to make, in such a way that this approach would be of limited use, and the deterministic behaviour becomes important. Basically, some machines have multiple inputs (similarly to the painter that you already have), and you end up needing to control which partial shapes go where, so merging them all onto one belt can make things harder instead of easier. However, the idea of building several copies of a machine you design once is a good one.
Regarding Factorio, I haven't played it myself, but I assume they wouldn't change how their splitters work for no reason - which suggests that the behaviour was less than ideal for some reason. Also, just based on that thread, it seems like Factorio has (on purpose) a fairly limited number of different entities that their splitter needs to work with - while Shapez.io has a lot of different shapes (I think it's somewhere around 2^85, or a 4 with 25 zeroes after it).
I think that number is one of the main differences between Shapez.io and most other factory builders - as far as I've seen, they tend to have designed items (with designed-in names, interactions, etc.). Shapez.io instead has just a few basic building blocks, and lets you combine them in arbitrary ways, letting combinatorics do the rest.
Its size is also why it's not practically possible to store state for every shape - and illustrates why it's risky to even just store state for only those shapes the balancer has seen. While most balancers would probably only ever see a few distinct shapes, others (e.g. ones on the way to the hub) can easily end up seeing many. (Actually, the hub already stores a value for every distinct shape it has seen, which caused a problem (since fixed) with very slow loading times after someone accidentally delivered a lot of different shapes (their make-anything machine instead made some of everything). And that was with just one building storing it, it would be amplified by a lot if several buildings did that.)
Regarding the A-B evenly mixed belts, that's not particularly hard to do when you have the tunnels, just split each belt in two with a balancer each, then use another balancer for each output belt to merge one from each input. Using a single balancer can work, at least sometimes, but it's less reliable - a hickup in any of the belts can affect the output you get.