round up fluids reading train inventory

Post your ideas and suggestions how to improve the game.

Moderator: ickputzdirwech

JohnyDL
Filter Inserter
Filter Inserter
Posts: 533
Joined: Fri May 16, 2014 3:44 pm
Contact:

Re: round up fluids reading train inventory

Post by JohnyDL »

If statements by definition involve jump commands which clear the fetch execute cycle and add an extra memory interaction as well as cycles but in most cases a few cycles is more than 1 memory interaction (i think). It might be negligible but it's also antithetical to code optimization that has been the focus of a lot of recent FFFs for very fringe benefits that are primarily related to how people want a mod to work not vanilla.

Zavian
Smart Inserter
Smart Inserter
Posts: 1641
Joined: Thu Mar 02, 2017 2:57 am
Contact:

Re: round up fluids reading train inventory

Post by Zavian »

Depending on how the code is structured you might not need a comparison and a jump.
If we are in a part of the code where we know the fluid is >0, then we can simply do

amount = max(1, amount)
or integerAmount = max(1, (round(amount))

Hardware level max implementations exist. (Or at least they used to exist, but I doubt they have been removed. eg http://x86.renejeschke.de/html/file_mod ... d_168.html ).

If the code is structured such that the max(1, amount) approach is viable then we are potentially only talking about a few extra cpu cycles per circuit connected tank/train per tick, which might be negligible.

Even if the compiler won't generate an assembly lvl max instruction (or if the code is structured such that using max() isn't appropriate), I thought that hardware branch prediction on modern processors is supposedly pretty good, and that might be good enough that the effect of the compare and jump might be negligible.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

JohnyDL wrote:
mrvn wrote:EXCEPT: try to design a station where you unload one fluid and load a different fluid in the same train. E.g. a train with water comes in, you pump it empty and then you pump in steam instead. Not impossible but the logic gets a lot more complex and you need 4 tanks instead of 3.
so long as there was no steam in the train to begin with turn on water pump if steam<=0, turn steam pumps on if water<=0, make sure that the water tanks are empty before the train can arrive with circuit network conditions and put the steam pumps turning on with a delay of some ticks so the water keeps pumping slightly longer than there's '0 water' in the train.

But you can't connect 2 pumps to the same train tank so emptying and filling at the same station should be a mute point.
A fluid wagon has 3 tanks that are normally interconnected. A wagon also has 2 sides. So you can have 6 pumps and connect 3 of them at a time.

With your simple logic I think this might happen:
- the train gets pumped down to 0.4 water
- the steam pumps turn on but can't do anything yet
- water gets down to 0 and 0.4 steam comes in
- steam gets into the water pumps

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

JohnyDL wrote:Yes detecting to so something different at 0<x<0.5 to do something different there rather than at any other time adds clock cycles for every tank and fluid wagon on the map every tick vs being consistent everywhere and taking fewer cycles.

So one way or the other it has to be and ceiling function vs round vs floor each break as many systems as they fix, with the exception that some problems have no benefit being in any of the methods. so why break what people have already made work for the 99% of cases where none is better than the rest or where the current is better than ceiling? In order to fix something for one specific problem that has multiple in game solutions already and that the devs have promised a force fix for when those fail.
Oh come on. Compare the cost of doing that in the cpu instead of fixing it using combinators in game.

And the point of special casing 0<x<0.5 is to not break anything actually used by people and fix what people frequently need. We all agree that ceiling function vs round vs floor each break something. That's why the special case.

JohnyDL
Filter Inserter
Filter Inserter
Posts: 533
Joined: Fri May 16, 2014 3:44 pm
Contact:

Re: round up fluids reading train inventory

Post by JohnyDL »

mrvn wrote:With your simple logic I think this might happen:
- the train gets pumped down to 0.4 water
- the steam pumps turn on but can't do anything yet
- water gets down to 0 and 0.4 steam comes in
- steam gets into the water pumps
My suggestion wouldn't be possible without 2 pumps connected to the same tank so to do it in a way that steam could get into the water pumps you'd need to have the input on one tank and the output on another since it takes 1 ticks to flow between wagons's tanks and a second to flow into the pump and you can disable the water pumps in 1 tick by hooking them directly up to the station output that should be a null issue.
mrvn wrote:Oh come on. Compare the cost of doing that in the cpu instead of fixing it using combinators in game.
Maybe a dozen combinators fixing the issue across an entire save vs the check on every tank that's connected to circuit networks whether they need the check or not to perform their task, which could be orders of magnitude more tanks I mean at my oil set up I compare heavy oil to light oil to petroleum to acid to lube without care of 0<x<0.5 states. So specifically for trains then and not all tanks? Well that's even less consistency for players that will make it easier to understand right?
Zavian wrote:amount = max(1, amount)
Hadn't spotted that, it's quite clever and whether you round inside the max or after the max it's the same speed, still doesn't solve the consistency problem and it still adds more processing than current but that's really clever anyway
Zavian wrote:I thought that hardware branch prediction on modern processors is supposedly pretty good, and that might be good enough that the effect of the compare and jump might be negligible.
Not really it spread out and cheated by hyperthreading if you hyperthread when there's a branch swap to the other thread and use the result for switching back straight line speed on one task you have the same fetch execute delays as in the original x86 line as I understand it.

My problem is just consistency and keeping the code concise and optimised, if you add an exception here where else can you add exceptions in the exact same vein with the same amount of utility, maybe flooring 24999.5<x<25000 so tanks only read 25000 when full? How many tiny exceptions can be thought of with this utility and which can be fudged with some circuit networking and extra planning, where do you draw the line between in and out? If any are out my opinion is they all should be.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

JohnyDL wrote:
mrvn wrote:With your simple logic I think this might happen:
- the train gets pumped down to 0.4 water
- the steam pumps turn on but can't do anything yet
- water gets down to 0 and 0.4 steam comes in
- steam gets into the water pumps
My suggestion wouldn't be possible without 2 pumps connected to the same tank so to do it in a way that steam could get into the water pumps you'd need to have the input on one tank and the output on another since it takes 1 ticks to flow between wagons's tanks and a second to flow into the pump and you can disable the water pumps in 1 tick by hooking them directly up to the station output that should be a null issue.
You can't connect 2 pumps to a single tank and fluid wagon. You would need pipes and then you have much more problems. And for both pumps to be connected at the same time they have to be at different positions.

I talking about: water tank <- water pump <- train <- steam pump <- steam tank

You talk about 1 tick. But what if the steam tank is nearly empty, say 0.4 steam in it. Then 0.4 steam gets transferred into the fluid wagon and stays there for many ticks. Unlikely to happen but not impossible. I'm also not sure what happens when a tank only holds a few steam. How much of that would transfer in one tick to the wagon. So even if the tank has 10 steam inside only 0.4 steam might show up in the fluid wagon for one tick causing the water pump to suck it out.

Overall it seems to risky to me. I would start a timer when water = 0 and switching pumps after N ticks. This would also allow using 3 pumps to empty the water and 3 pumps from the other side to fill in steam.

JohnyDL
Filter Inserter
Filter Inserter
Posts: 533
Joined: Fri May 16, 2014 3:44 pm
Contact:

Re: round up fluids reading train inventory

Post by JohnyDL »

totally agree with you mrvn it could go wrong if you don't lock your station until you have the space for items received and enough product made to refill the train, I don't do much (any) multifluid/multi item trains, I have no need of them.

But the same thing can be achieved with something like this with no chance of contamination in practically the same space without any cross contamination possibilities and no stupid rounding errors.
Capture.PNG
Capture.PNG (423.47 KiB) Viewed 5336 times

Shia
Burner Inserter
Burner Inserter
Posts: 18
Joined: Mon Oct 23, 2017 10:11 pm
Contact:

Re: round up fluids reading train inventory

Post by Shia »

All the "real" situations showed here leads to the suggestion that you do not have the "space" to simple put there 2 stations (one load and one unload).
For 99% of all games, the map is infinite in size (theoretically). So simply split it up and let the train leave on empty cargo the unloading station will work without any leftovers.

For cases where you do not have the space, a train isn't a good solution at all.

It's like "Hey, I've build up something very cool. Plz Factorio make it work."
The game is basically for resource / assembling management, logistics..... To not encounter situations where you can't pump out 0.4 or just input 0.3 is part of the game. There are a lot of good and useful suggestions. But "Pls change math"?
To change the pump so it not sucks in an amount which will left something less than 0.5 but greater 0 seems more suitable to me. Either the pump has enough space to get everything so nothing will be left or change the transferred amount so at least 0.5 will stay in the pipe/train/tank/whatever.

For modders: the train can be read directly and will show values like 0.025364 for fluids. To create a separate output like "Inventory Sensor" to round up values less than 0.5 shouldn't be the big deal. (And there may be already something like this... I don't know)

At least, that's my opinion. Would a small change to the fluid system so such cases doesn't happen anymore be ok for you (and leave math as it is)?

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

JohnyDL wrote:totally agree with you mrvn it could go wrong if you don't lock your station until you have the space for items received and enough product made to refill the train, I don't do much (any) multifluid/multi item trains, I have no need of them.

But the same thing can be achieved with something like this with no chance of contamination in practically the same space without any cross contamination possibilities and no stupid rounding errors.
Capture.PNG
I do that. Although often with some more space, having the next train stop where the fluid wagon of the first one is so the pumps can all be on the same side.

But with such a setup a train can arrive for each station at the same time. So you need enough space before the station to hold both trains without blocking the main track. Having them not overlap takes very little extra space compared to 2 stations + waiting space. Now with 3, 4, 5, ... such stations you can assume not all of them will get trains at the same time so not so much extra space is required if you risk it. More so if the stations are only enabled when they can service a train (or LTN) and the trains will never be stuck at a station.

I have a feature request active for LTN so you could connect the two stations so LTN would handle them as one station for purposes of counting trains.

JohnyDL
Filter Inserter
Filter Inserter
Posts: 533
Joined: Fri May 16, 2014 3:44 pm
Contact:

Re: round up fluids reading train inventory

Post by JohnyDL »

The situation I thought was one train emptying and reloading with a different fluid not multiple trains using the same station, for different things, cause infinite space why not more stations, though yes there are ways to have it all on the same side but I made a mock up that was easy to see what was going on.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

JohnyDL wrote:The situation I thought was one train emptying and reloading with a different fluid not multiple trains using the same station, for different things, cause infinite space why not more stations, though yes there are ways to have it all on the same side but I made a mock up that was easy to see what was going on.
yes, it was, sorry. I still use more space though, so the train has to drive a bit further for loading. But forget about the extra waiting bays, that only applies with separate trains. Actually with one train loading and unloading if you put the stations right after each other you can unload the next train already while loading the previous one.

Still not as nice as with solid goods where you load and unload with filter (stack) inserters in parallel. You can unload/reload a train nearly as fast as just one of them for goods vs. twice as long for fluids (or as long as separate stations, no benefit except for not having to drive to the next station).

User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2915
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: round up fluids reading train inventory

Post by Optera »

JohnyDL wrote:totally agree with you mrvn it could go wrong if you don't lock your station until you have the space for items received and enough product made to refill the train, I don't do much (any) multifluid/multi item trains, I have no need of them.

But the same thing can be achieved with something like this with no chance of contamination in practically the same space without any cross contamination possibilities and no stupid rounding errors.
Image
The drawback of your method with having 2 stops is that i can't bake it into LTN.
While there's no simple and 100% reliable way to unload just one fluid of a mixed fluid train LTN will remain locked to 1 fluid per train.

Zavian
Smart Inserter
Smart Inserter
Posts: 1641
Joined: Thu Mar 02, 2017 2:57 am
Contact:

Re: round up fluids reading train inventory

Post by Zavian »

I've never used LTN, so I could easily be missing something, but would the following work?

LTN sets the train schedule to go to the station, and wait for a circuit signal (that will either never arrive, or be somehow sent via lua). Once the train gets there, and starts unloading, LTN checks the actual fluid contents of the train once per second (getting the actual fluid contents either as a floating point value via lua, or possibly just waiting until the train's contents to no longer list a fluid). When the train is empty LTN then sends the train to a depot, or wherever.

Not sure whether the lua api provides what you would need to implement that, but getting the api extended might be easier than changing rounding.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: round up fluids reading train inventory

Post by mrvn »

Optera wrote:
JohnyDL wrote:totally agree with you mrvn it could go wrong if you don't lock your station until you have the space for items received and enough product made to refill the train, I don't do much (any) multifluid/multi item trains, I have no need of them.

But the same thing can be achieved with something like this with no chance of contamination in practically the same space without any cross contamination possibilities and no stupid rounding errors.
Image
The drawback of your method with having 2 stops is that i can't bake it into LTN.
While there's no simple and 100% reliable way to unload just one fluid of a mixed fluid train LTN will remain locked to 1 fluid per train.
But LTN never unloads one fluid and loads another fluid anyway. It's always Depot -> load -> unload -> Depot. The only drawback is that LTN might send a train to the loading station at the same time as the unloading station so you need to have parking space for two trains.

As for backing that into LTN: Couldn't one connect the two LTN trainstops with a wire so they are in the same signal network and have LTN detect that and consider them a single stop?

User avatar
Jon8RFC
Filter Inserter
Filter Inserter
Posts: 553
Joined: Tue May 10, 2016 3:39 pm
Contact:

Re: round up fluids reading train inventory

Post by Jon8RFC »

Are you talking about something like 0.0 and 0.2 and 0.2 shown in the fluid wagon?

If so, I was weary of posting my "solution" and suggestion for how to correct this. Implementing logic into the trains or stations (however Factorio is programmed) to add on an extra half second or so before disconnecting should fix it, so extra conditions aren't necessary for manually fixing it.

I found that adding an "AND 1 second inactivity" condition to every single train fully empties and fully fills without decimals leftover. The pumps just need to stay connected very slightly longer. Whatever is making the trains move and the pumps disconnect, make them wait an extra 30-60 ticks as part of the game logic rather than conditions.

(I'm glad I happened to see this thread by chance, because I was always worried I'd be ostracized for posting a bug report about it)
Image

Zavian
Smart Inserter
Smart Inserter
Posts: 1641
Joined: Thu Mar 02, 2017 2:57 am
Contact:

Re: round up fluids reading train inventory

Post by Zavian »

@Jon8RFC: That type of setup has already been suggested in this thread. It's brittle in that there is a possibility that the tank you are pumping into might fill up with the train still holding 0.2 fluid. Yes you could probably add more combinators do detect that, and hold the train if the tanks are > 24996 fluid, but I get the impression that Optera wants something simple and reliable that people can use with LTN. I'm starting to think that the best way for LTN to do this is to read the trains contents in Lua.

Shia
Burner Inserter
Burner Inserter
Posts: 18
Joined: Mon Oct 23, 2017 10:11 pm
Contact:

Re: round up fluids reading train inventory

Post by Shia »

Trains just need to be set to "empty" and will not leave until they are empty for real.
The problem is when pumps are connected via circuit network.... they will turn off at <0.5. (at some tests it showed 3 x 0.6 (1.7 for train) and still the station-output was 0). And looking at the Problem: "Wagon pumped out and filled with different fluid" the pumps for output/input will switch prior to an empty tank (and that way, nothing will go in)

User avatar
Jon8RFC
Filter Inserter
Filter Inserter
Posts: 553
Joined: Tue May 10, 2016 3:39 pm
Contact:

Re: round up fluids reading train inventory

Post by Jon8RFC »

I understand that rounding solves one problem and creates another. If inactivity conditions don't break anything for full/empty conditions, I would think that making it transparent to the user and always in effect would be one way to fix it, or at least be a temporary solution (which will probably end up staying permanently).

In actual use, the problem seems to be that fluids aren't being fully transferred, for whatever reason. The result has circuits reading differently and it is already rounding improperly as best I can conclude, because this doesn't happen on single tanks of fluid wagons. Why round it again instead of move that fluid?

Destroying fluids seems like an equally bad approach. Transferring from one fluid wagon to another ends up with 25k and 24.9999k and 24.9999k in the filled tank, with 0 and 0.1 and 0.1 in the empty tank. If you destroy the remainder, then you still have missing fluid in the full tank. I think William Ockham would vote for an inherent and transparent inactivity approach (done in factorio, and without us being able to change it) for full/empty conditions, at least in the interim.
Image

User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2915
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: round up fluids reading train inventory

Post by Optera »

For LTN the current solution is one fluid per train and use wait until empty instead of wait until fluid = 0.
Monitoring train contents is terribly slow and out of the question.

For generally controlling fluid loading and unloading I have not seen a faster and simpler to implement fix than rounding fluids to next integer.

Longbolt
Burner Inserter
Burner Inserter
Posts: 17
Joined: Mon Oct 16, 2017 7:43 pm
Contact:

Re: round up fluids reading train inventory

Post by Longbolt »

Roxor128 wrote:
steinio wrote:
Roxor128 wrote:Seems to me the real solution to the problem should be "Use integers instead of floats for fluid values". Though that would probably be a headache to change.
Yes I thought the same a while ago.
Maybe the developers can provide some insights why they decided for floats.
As a programmer, I can say there are certainly a few reasons to use floats when writing something. The main ones I can think of off the top of my head being these three:

1. Being the computer equivalent of scientific notation, they have a very large range (10^308 down to 10^-308 for 64-bit floats).

2. Algorithms are often easier to implement with floats rather than just integers.

3. Some APIs require their use for certain functions (eg. OpenGL uses them for things like coordinates and colours, and both HLSL and GLSL use them for all colour values).

Hope that helps give a little insight.
Not to mention using integers to represent fluctuating fluid pressure/flow is a nightmare.

Post Reply

Return to “Ideas and Suggestions”