TL;DR
Allow mods to exercise significantly more control over the circuit network, effectively allowing complete control over how entities and the circuit network interact.What ?
Three major changes to the modding API and featureset of the game, which do not add a lot of overall complexity to the engine or core game, but expose a lot more of it to modders. Each change could be implemented independently, but I believe all three are needed to truly unlock maximum potential for modders. I've included a sample API spec (not necessarily complete) alongside each feature to enable more precise discussion, but I don't expect the final API would necessarily conform to this.- Mods would be allowed to define custom wire types, to allow adding more overlapping circuit networks to the game. E.g. blue wires, purple wires, etc. A mod could define a wire type for internal use between entities (especially hidden entities) it creates, to allow a mod to essentially create private circuit networks.
Sample specification - Mods can directly add, modify, or remove connection points on entity prototypes. This would allow the mod to link entities to the network that otherwise wouldn't be able to.
Sample specification - Mods can specify the control behaviors of entities directly, and set some parameters. Existing control behaviors are made more granular so that this is more useful. Additionally, a new control behavior is added allowing a mod to control behavior directly.
Sample specification
Possible issues ?
I don't know if it would be too much of a mess for backwards compatibility; I don't know how much it matters given that it would be a significant overhaul and the results would probably be majorly positive. Attempts to retain backwards compatibility, like with `circuit_connector_id`, could prove problematic. I've tried to write the sample spec in a way that respects performance costs, but I'm not the sort of player who builds factories for which UPS becomes a serious problem and I don't know the engine, so I don't know for sure.Why ?
There have been frequent requests for more advanced behaviour be given to circuits, such as separating wire control or more machines connected and controlled. There are mods that give this advanced behaviour, but they frequently require using additional hidden entities with lots of scripting or constructing extra entities nearby.The specific thing that sent me on my quest to trying to learn about modding and circuit networks was measuring flow through a pump, as a way to determine directly if the fluid supply to a train was too low (the workaround I'm currently using is measuring the last tank before the loading pumps; another one would be to compare values for the train on different ticks).
I think one of the major impediments to bringing this into the base game (forgive me if I'm wrong) is that there are so many parameters and so many options that it's hard to decide what to implement. This proposal is intended to open up this design space for modders, so that the best ideas can be coded, reviewed, and iterated in the community before inclusion in the core game.
Here's a list of things this enables or simplifies, which features are required for them, and how:
- (#2) Separating wire control can be done, even to some extent for pre-existing control behaviours, by hiding their existing connection point plugged into them, and replacing it with another connection point in the same position. The GUI is modified by the mod to allow selecting individual wire outputs for individual controls, and then script adjusts connections between the visible connection point and the hidden one accordingly. #3 is required to be able to separate behaviors onto different networks where one entity has effectively multiple.
- (#2, #3) New behaviors can be directly added to entities, even those that cannot currently be connected to the circuit network, by adding connections with appropriate behaviors. With #3 alone, existing behaviors can still be recombined without too much extra effort. Examples include toggling furnaces or assemblers or reading their contents, reading flow rate from pipes, etc.
- (#2, #3) New combinators can be created directly, such as a time-delay combinator, a selector (use one input to choose one of multiple outputs to send a second input through to), or a filter combinator, without needing multiple entities or excessively complex scripting.
- (#2, #3) Many mods like Shortwave and LTN can be made simpler by not requiring hidden entities, instead using multiple connection points on its stops.
- The weird multi-position distribution thing for connection points is to allow modules that add wire types not have to worry about the positions they connect to, and modules that add power poles not to have to worry about new wire types, without creating an awful result. By having the game distribute them during loading, it makes it so that if a module adds blue and purple wires, the game will select one wire to go with red wires and one to go with green wires. The requirement of determinism makes it unlikely that you get a royal mess where wires criscross over different kinds of poles. An alternative would be to simply say that there are only three wire connection slots and each wire type has to pick one, but this way lets modders add more if they like.
- Built-in control behaviors are retained to avoid incurring performance cost and exposing proprietary source by moving them to the lua.
- The mod control behavior is distinct, as opposed to relying purely on events, to make exporting behaviors easier, to parameterize them, to increase performance by avoiding the need to test event filters for entities that have no custom behavior, and to avoid giant fights over the behavior-toggling GUI.
- Splitting existing built-in behaviors and allowing multiple per entity is done to make them more reusable and modular, and to create logical progression towards the creation of more built-in simple ones such as for reading parameters not currently exposed on the network. In particular, this allows modules to take advantage of existing C++ code to add existing behaviors to entities that do not have them. There would be many immediate improvements that could be considered
- I tried to avoid setups that would require the base game to add hidden connection points to things. For instance, read_logistic_contents would be enough to implement a logistic input to another connection by adding a hidden connection point and using that.
- Callbacks are used so that scripts cannot modify the values of signals directly or at weird times during processing, but only at the appropriate time in a tick.