Adds Lua-programmable circuit network combinator. Based on Sandboxed LuaCombinator and LuaCombinator2 mods. Probably won't work in multiplayer games.
Mods introducing new content into the game.
Entities which interact with the circuit network.
Thank you for ota_update_from_uid! In my opinion, its not quite perfect yet though.
What I really want to do is:
if global.version > var.version then
update_ota_from_uid = global.src
end
That way, by changing global.version I can trigger an update remotely. Now, I believe you said something along the lines of you don't want MLCs communicating because thats cheat-y in relation to the circuit network (and its done by other mods). I agree, at the moment I only want two. And I don't want to communicate factorio circuit information. Just Moon Logic specific updating stuff. So would it be possible to limit globals by memory or amount?
A way to implement this without global variables would be to have the ability to update from save slots. So something like ota_update_from_saveslot = 1
This can be placed at the start of a program to keep it synced with the save slot. Although thats not great because then the MLC is updating it code every run so still need to have some version checking. Maybe theres a way for ML only to update if the source code has changed?
My second problem is the fact the updating is tied to the MLC's uid. What happens if I accidentally destroy the source MLC or a biter comes and takes it out? I can rebuild the MLC and replace the code but the MLC will not have the same exact same uid because well its unique. So I would have to go and manually change the source uid on all the target MLCs. Some possible solutions I've come up for this are: have a global variable (global.src in my example above), the save slot idea, or be able to "name" MLCs. Naming would function similar to having a global variable specifying the uid but it wouldn't be as versatile or as powerful as globals would be.
Currently, without some version checking, when ota_update_from_uid is is run, it updates the code correctly and then immediately runs the new code. This makes sense so that the code that is stored on the MLC and what it is actually running never get out of sync. However it leads to an endless loop of updating because currently I don't see a way of adding conditions of when to update.
Ok, I lied. I do see a way of currently doing the version stuff. If I made a circuit network that connected all my MLCs. I could use the signals to specify the version and uid. If you don't like any of my aforementioned ideas I guess I'll have to do that :/ I just don't like it. I am using a MLC is each of my mining outposts so they are pretty spread out.
Or I guess I could install one of the various wireless circuit network mods. However I would prefer if I could find a solution using just Moon Logic and not rely on any other mod.
if global.version > var.version then
update_ota_from_uid = global.src
end
You can do exactly this too, via _api.global - that's factorio mod globals, which go into save and shared by everything.
But yeah, less cheaty way would probably be to use one of the wireless mods and control stuff via in-game signals, not lua hacks.
There's one such wireless mod linked in the description too.
ota_update_from_saveslot = 1
This can be done too - just place like 50 combinators at your base, and use these as "save slots".
You don't even need any kind of globals, just have every other combinator update once per say 60 * 60 ticks from these and only ever edit code on these "save slot" MLCs, not others which would pick up updates from them automatically.
Maybe theres a way for ML only to update if the source code has changed?
Eh, I'd say use _api.global for this if you really want, or any kind of proper in-game communication mechanism (remote network, logistic network signal, or maybe a train transporting an "update token").
Or just don't even bother with these - just update on some interval from aforementioned "gold standard" combinators you have lined up at the base if you have everything templated, and if code is the same, it's a no-op.
My second problem is the fact the updating is tied to the MLC's uid. What happens if I accidentally destroy the source MLC or a biter comes and takes it out?
Yeah, idea here is definitely to use some kind of wireless network, as this goes deeper and deeper into "just give me mod apis and let me make a global factorio mod".
That's not what combinators do, they just work with inputs they're given on the wires and produce outputs to other wires, not have some kind of global abstraction layers and code sharing primitives, with their own flaky and error-prone separate communication mechanisms.
And ofc you can again just use _api.global for that and store whatever you want there, but imo that's way out of scope, and exactly why I don't like direction where LuaCombinator3 mod went, providing modding tool/api instead of an in-game combinator, iirc mod description also mentions this from the very first version.
And also having "gold standard" combinators can fix this "uid changes" thing too - have 50 combinators behind thick walls where nothing can touch them, change code on these, and only use others to update from them.
Thank you for the detailed answers! You've given me some ideas that I think I can work with.
I am using a MLC is each of my mining outposts so they are pretty spread out.
And that's kinda the point of having stuff remote and inaccessible.
You can install teleporter mod, you can have instant remote control over everything, you can make trains go at light-speed, then you can just generate map where all resources are in one place so that you don't have to have anything remote, and then why not just have infinite resources and build what you want where you want, in fact, why not just have one building that builds everything, or why not use /cheat to give you endless amounts of everything directly, etc etc.
I think there's a difference between in-game mechanics and mod api - former are restricted by some set of clear simple and mostly-obvious rules (game mechanics, e.g. data can only go over wires or logistics radios), while latter just blanket-allow you to do anything you want with the game including changing those rules as you see fit.
And you seem to want a more convenient modding API to change game rules - it's there, that secret API via _api, feel free to use it, but I don't see any reason to expand on it in the mod. Even current OTA thing is a hack outside sensible game rules, and ideally should be done by serializing stuff via signals, or by transporing an "hdd" item, but that's just tricky to implement.
Oh, also, one thing I kinda like for remote control that's outside of base game rules is ciruit network button mods - Switch Button and Pushbutton. To e.g. start or toggle something on/off from the map without wires, instead of having to go there just to push the button.
These can probably be used for an "update button" too, in various ways.
convenient modding API to change game rules
I am all about convenience. However, I do not really want to change the game rules.
You can install teleporter mod [...]
Those are unfair comparisons. I wanted MLCs to have access to item stack sizes because that information is readily available to me. If I have access to that information, in my opinion, it just makes sense that a lua combination has access to it also. Similarly, with the updating, I can manually update each MLC and given that they are running code, they should, again in my opinion, be able to update themselves. Now, I will grant you that the wireless/ota aspect of the updating is OP and not in line with the base game. But eh, the updating only effects the code. It does not change anything outside the MLC, mainly what the MLC is connected to. So, it cannot really influence the game all that much. Then what is the purpose of updating if it has so little effect? Pure convenience and for organizational purposes. Right now, I am using each MLC for the same purpose and I do not like the idea of MLCs getting out of date.
You can remove the update function if you do not like it. I have found a way to implement the same thing using _api. And with _api.global I can make global functions! Which makes updating less important to me.
Thank you for your time.
You can remove the update function if you do not like it.
Nah, I think it makes sense to have some kind of update for a smart combinator, even if it's mostly a hack.
And with _api.global I can make global functions!
No no no, don't do that, factorio will strip all functions from there when you load the game!
You can't store lua functions there, unless you mean just their code strings.
You can't store lua functions there, unless you mean just their code strings.
For reference and rationale, see the end of FFF here - https://www.factorio.com/blog/post/fff-349
Iirc current factorio issues some kind of warning in the log and deletes them from there when you load the game, but does not actually prevent you from storing them there in the first place, so things will break later.
You can do what this mod does and store these funcs as strings though, and load() them locally after game is resumed.
I have found a way to implement the same thing using _api. And with _api.global I can make global functions! Which makes updating less important to me.
But yeah, this thing in general is what I meant by changing game rules and basically making a mod.
Don't think it needs any kind of justification or rationale - it's a single player game, and you always play it by your own rules, I just don't want the scope of this mod to focus on that use-case much, for some reasons already mentioned.
And indeed as luck would have it, it's trivial to just expose full factorio lua-api for those who want it, so that they can go in that direction regardless.
I tried 'update_ota_from_uid' but it only updates when I open the GUI, which means I need to open all the combinators one by one to update them.
(I tested the wood + 1 example, after I change the source combinator to wood +2, the other combinator do not automatically increase the interval to 2, instead they still do +1, only after I open the GUI of them, they start to do +2)
Is there a way to update them automatically after I change the source combinator?
I tried 'update_ota_from_uid' but it only updates when I open the GUI, which means I need to open all the combinators one by one to update them.
It was totally a bug - as this change updates undo history, it was checking for whether gui was open, which prevented it from working without it.
Should be fixed in 0.0.61, thanks for reporting.
Is there a way to update them automatically after I change the source combinator?
Should work now, though now that I think of it, if you set that on every tick, it'd be highly inefficient, as it should re-parse the code.
Gotta add a check for whether code is the exactly same and skip the update if that's the case.
Should work now, though now that I think of it, if you set that on every tick, it'd be highly inefficient, as it should re-parse the code.
Fixed in 0.0.62, now you can write something like:
out, delay = {['signal-red']=1}, 60
ota_update_from_uid = 31
...on the original uid=31 combinator, and copy-paste that to any others, and they should all auto-update efficiently, skipping doing anything if it's their own uid or same exact code anyway. It's functionally same as before, but just doing a bit less work with this simple use-case.
Thanks for the quick response and fix!
And the improvement in the last update sounds really nice since I'm doing same UID check on the source combinator to skip updating otherwise I can't edit the code on the source combinator because the updates just refresh the editor constantly.
I'm doing same UID check on the source combinator to skip updating otherwise I can't edit the code on the source combinator because the updates just refresh the editor constantly.
Didn't even think about, but yeah, sounds pretty bad.
Guess you might be the first actual user of this feature, given how many bugs it had :)