Space Engineers

Space Engineers

Not enough ratings
'Lean' Refinery Script v1.6
   
Award
Favorite
Favorited
Unfavorite
File Size
Posted
Updated
12.847 KB
May 5, 2015 @ 1:36pm
Jul 26, 2015 @ 10:33am
11 Change Notes ( view )

Subscribe to download
'Lean' Refinery Script v1.6

Description
Demand-Based Intelligent Load-Balancing

You're mass-producing armour plates but all your refineries are busy with platinum ore. Most of the time that's fine, but right now you need iron. There's lots of ore available, but it'll take another hour for the refineries to clear the platinum ore they've already got and the furnaces are working on cobalt.

This script solves your problem.

Running every few seconds, it gives the refineries and furnaces just enough work to handle before it runs again, analysing how many ingots you have and distributing the right ore to fill the gaps in your production. Dynamically adjusting for changes in demand, it ensures that your refineries are producing the materials your assemblers need right now.

This script might be useful for you if:
  • You want to get all of your refineries working together when necessary, instead of having five munching on a huge platinum reserve while the other five are struggling to keep up with immediate iron and silver demands.
  • You tend to pool your storage (ie. all ore in one big pile of containers, all ingots in one big pile of containers).
  • All your assemblers pull from the shared pool of ingots.

Basically if your system looks like: Ore Containers -> Refineries/Furnaces -> Ingot Containers -> Assemblers


How to use it

You will need: 1 Timer block, 1 Programmable block, a lot of ore containers called 'Unrefined Ore', a lot of ingot containers called 'Raw Materials', a lot of refineries/furnaces called anything you like. You will also need a Conveyor Sorter set up to drain ingots out of the refineries and into the ingot storage.
  • Install the script in the Programmable Block.
  • Set up the timer to run the programmable block, and to 'Trigger Now' on itself.
  • All the refineries and furnaces you want the script to manage should have 'Use Conveyor System' turned OFF. This is very important! They should also start out empty or nearly empty; the script won't mess with refineries which have enough work to get on with.
  • Assemblers can be in cooperative mode or running individually, it doesn't matter. But they should probably have 'Use Conveyor System' turned ON unless you have another script feeding them resources, because this one only looks at what they're using.
  • Trigger your timer block to start everything up. Switch it off and on again to stop the script.
If you're not running in Realistic mode, you will need to configure the script slightly. This is done by editing it and looking for lines which look like:

public float RefinerySpeedFactor { get { return 1; } }
public float AssemblerEfficiencyFactor { get { return 1; } }

For each setting, change the 1 to a 3 or a 10 depending on your world setup.

Below these lines there are some other things you can change if for example you want to use different names for your ore containers or ingot containers. You can even specify multiple container names for each category, or use the same names for both. Note that uppercase/lowercase differences are significant though.

Uranium

By default the script will not attempt to refine Uranium. If you want to give it control over this, look for the following line and change 'false' to true':

public bool EnableUraniumManagement { get { return false; } }

Assemblers don't consume much Uranium compared to other resources. If you want to boost the amount of Uranium the script should maintain in your ingot storage, adjust the line which looks like:

MinimumStockpileOverride = 0f

(This is somewhere around line 193. You can add similar lines to the other material definitions to boost their minimum stockpile too.)
For example, to try to maintain 50 ingots in storage, change it to look like:

MinimumStockpileOverride = 50f

Stone

Gravel is used for precisely one blueprint: Reactor Components. The rest of the time, stone in the ore storage is a bit of a nuisance. Therefore this script does not handle stone. If you need gravel, you can 'override' the script's control of a refinery temporarily by simply dropping a load of stone into that refinery. That refinery will then be ignored until it runs out of work again. This can be done with other ores too.

Troubleshooting

My refineries keep running out of stuff to do!

This might be because your game mode is set to refine stuff faster than the script expects. Try adjusting RefinerySpeedFactor.
If you're running the script every few seconds using a timer, instead of setting up a 'Trigger Now' loop to run it constantly, then it could be timer lag. Try using high-precision mode (new in v1.2) or increase IntervalOverlapSeconds to something higher than 2.

This doesn't work with my super-fast refinery mod.

Unfortunately the game does not expose information about refinery speeds and efficiencies in a form that scripts can use, therefore all these numbers currently need to be hardcoded into the script. Currently it only knows about refinery types present in the unmodded game files.

You can teach the script about new refinery block types by adding new RefineryTypes around line 235. The name of the refinery type must be the SubTypeId of the block.

This doesn't work with the ore type introduced by my favourite mod.

As for refinery types, so for ores and ingots. This information needs to be extracted from the game files by hand and coded directly into the script. The material types are defined around lines 160-200 and new ones can be added easily. The values for processing speed are based on the 'blueprint' values, ie. they assume a refining speed and material efficiency of 1. As of v1.4 the script can understand ore types which produce multiple ingot types.

Don't see your problem here? File a bug report in the comments!

Scalability

I'm currently using this on a ship with 40+ ore containers, 40+ ingot containers, 70 Arc Furnaces and 36 Refineries. No slowdown or lag has been observed. I have done my best to avoid O(n^2) algorithms where possible, so increasing the number of refineries/furnaces or containers should not affect performance unduly. Runtime is usually between 4ms and 80ms for me.

There is room for improvement in scalability terms but the trade-off is increased complexity, so I've avoided spending too much time on optimisation. But if you find your game is struggling to cope with this script, please file a bug report!

How it works

The script determines the maximum amount of each ingot your assemblers 'could' pull if they were all manufacturing the right (wrong?) blueprint and uses that to prioritise them.

For example, one assembler can consume 600kg of iron ingots per second when building gravity generator components, but never more than 15kg/sec of silicon wafers (glass). So it aims to maintain 40 times as many iron ingots as silicon wafers, because they can be consumed 40 times as fast.
As long as there is enough of every ingot type to satisfy the absolute largest request by all assemblers simultaneously, your production will not stall.

In practice you need a lot of refineries to keep an assembler fully fed, but this script does at least guarantee that all refineries are busy producing something useful even if it can take a while to update.

Alternative Sources

Steam Workshop doesn't seem to offer the ability to review script code before downloading it. I dislike not being able to casually browse code so here's a pastebin of this script: http://pastebin.com/Azycyche

Planned Updates

Version 2 will change (again) how the game data is entered into the code, allowing the efficiency cap to be properly dealt with and simplifying the process of making the script aware of mods and fixing non-ingot refinery outputs. I will also drop support for legacy mode in v2.
Popular Discussions View All (6)
0
Jul 7, 2015 @ 4:25pm
Known Bugs
Alex
0
Jul 7, 2015 @ 10:57am
Tech Notes: Refineries, Blueprints and Speed
Alex
0
Jun 13, 2015 @ 1:42pm
Adding new ingot types
Alex
31 Comments
7-2A Jun 12, 2016 @ 6:43am 
At what line(s) is
public float RefinerySpeedFactor { get { return 1; } }
public float AssemblerEfficiencyFactor { get { return 1; } }
located I can't seem to find them.
YENDOR MOSREH Dec 14, 2015 @ 7:51pm 
could you get this to run the whole station, making parts melting ore controling reactors and solar panels to turn off reactors if there is sun , and could you intergrate short range security drones that the base uses to get fuel or ore or to kill invaders like spiders
Alex  [author] Oct 7, 2015 @ 12:36pm 
Yeah, the threshold is a bit tricky. I never really expected it to be run at such a clock rate; I generally clock it at whatever the target interval is, usually ten seconds.

I should really dust off v2 and try it again. Keen have apparently merged some of lord-devious's programmable block fixes which might make it more tractable.

Is dropping low-precision mode in v2 a deal-breaker for anyone? It would demand a timer running on a trigger loop because the script would actually be depending on being called 60 times a frame. The effect on game performance should be effectively zero, but you'd need an extra timer block.
WJSabey Sep 30, 2015 @ 5:42am 
I think 3 seconds is too high for the high-precision threshold. I run all my scripts off a one second timer, which caused this to keep feeding my refineries not quite enough ore, even with overlap at 2s. When I figured it out, I changed the threshold to 500ms. This eliminates false-positives, and should still be sensitive enough to detect per-tick running.
Alex  [author] Sep 1, 2015 @ 4:11pm 
That is to say, the codebase changes warrant a major version increment but the actual user-visible changes are minor. There's not really any point waiting for v2 when v1.6 does the job :) V2 is more of a refinement really.
Alex  [author] Sep 1, 2015 @ 10:05am 
I'm not going to bother releasing script version 2.0 until Keen have fixed the programmable block compiler/ILInjector, since v2.0 won't really provide enough new functionality over the current v1.6 to make it worth the difficulty of making it run against the current API...
Alex  [author] Aug 13, 2015 @ 10:50am 
SE v.1095 affects ingot use and likely will change the rate at which different materials get consumed. I'll take a look at this over the weekend and see if the changes are significant enough to warrant updating the script.

Script version 2.0 is mostly working now, but SE's programmable block is being difficult and throwing ridiculous exceptions for perfectly valid code, so progress is slow and aggravating.

I'm looking at changes to the scheduling algorithm to take into account how rapidly assemblers consume certain things compared to how fast refineries produce them, which is something that's been bothering me about the current design: the iron stockpile rarely changes even when churning out iron-heavy components while the entire platinum or silver stockpile vanishes in seconds when bulk-manufacturing thrusters or reactor components. Realistically the only solution to this is to have a seriously huge number of refineries, but I think I can improve the situation with some work.
Alex  [author] Jul 7, 2015 @ 2:57pm 
Looks like I broke Minimum Stockpile in 1.4 too...
Alex  [author] Jul 7, 2015 @ 10:41am 
Efficiency cap bug applies to Iron and Stone and relates to the use of multiple Effectiveness upgrade modules on refineries processing these materials. The script may overestimate how rapidly ingots are being produced. Since Iron has a high bias anyway this probably won't be a problem in practice.
Fixing it seems difficult without adding yet more information about the game files to the script and requires another internal API change.
I'll sort it out in version 2.
Alex  [author] Jul 7, 2015 @ 6:51am 
There is a bug in the blueprint scoring in 1.4, again relating to iron bias. It scores Iron much higher than other resources because it is produced so much faster...

I'm going to revisit the scoring algorithm and post a new version later. I'll fix the efficiency cap bug at the same time.