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.
Okay, the thing about all the inputs is I'm trying to calculate the stack size of items. I have another mod that can do this inefficiently. Would it possible, in moon logic, to be able to query an items properties. So something like:
item = getItem("coal")
stack_size = item.stack_size
Hah, actually quite trivial, just need to expose "data" table there, which has all factorio prototypes in it, and it's already read-only too (factorio can only update prototypes when starting the game).
"data" table
Correction, it's apparently game.<something>_prototypes tables at runtime.
Correction, it's apparently game.<something>_prototypes tables at runtime.
Added these as "game.proto.<soemthing>" in 0.0.25, and there is a whole bunch of these tables:
https://github.com/mk-fg/games/commit/76c64c2#diff-d3a920a78dd8391b24690fec36a2cbeaR245-R250
They are linked from factorio LuaGameScript - https://lua-api.factorio.com/latest/LuaGameScript.html - and you can find full info on each prototype type there.
For example, if you are interested in stack size of wood, then:
So guess you do local wood_stack = game.proto.item.wood.stack_size
local variables appear to not be to be shown in the environment variables windows.
387.769 Error ParallelScenarioSaver.cpp:114: Saving scenario failed: The mod Moon Logic (0.0.25) caused a non-recoverable error.
Please report this error to the mod author.Error while running event Moon_Logic::on_save()
LuaCustomTable cannot be serialized.
I got this error when I was testing local wood_stack = game.proto.item.wood.stack_size
but I don't think it is what directly caused the error because it is working now...
local variables appear to not be to be shown in the environment variables windows.
That's perfectly normal, they should not be.
But yeah, setting something from those prototypes to global I guess won't work, as these are indeed saves into save game and are not true lua objects, not really in-game objects, and game will refuse to serialize them.
So if you do wood = game.proto.item.wood
, guess you'd get that error.
But pretty sure game.proto.item.wood.stack_size
is just an integer, so should be fine.
Guess it'd be another "secret feature" then, so that people don't break their game needlessly :)
So if you do
wood = game.proto.item.wood
, guess you'd get that error.
To be clear, issue here is that by that line above, you are essentially putting C++ LuaItemPrototype reference into global.vars table, which ends up in a save file, and factorio doesn't allow saving (serializing) those objects, so just be careful what you put into these vars.
And I'm not sure if it's fixable in any reasonable manner, other than just being careful, as if Moon Logic strips these from save, your code will break once you save (or load), which is better than a crash, but still stupid.
Copying all these prototypes into lua objects is a bit bonkers, and they do change with mods too.
Hence the "secret feature" verdict - it's a nice idea, but probably not worth implementing in a rather foolproof way, so should probably be hidden.
hmm I'm trying to run game.proto.item.wood.stack_size
but where wood is a variable
item_name = "wood"
item_proto = game.proto.item[item_name]
stack_size = item_proto.stack_size
item_proto = nil
This doesn't cause a programming error and I thought I cleared the customtable stuff but I am still getting the error on saving. So is there a way to make it into a one liner? (I'm a lua noob)
You mean game.proto.item[item_name].stack_size
?
Though idk why game tries to serialize the item_proto value after it's been set to nil, weird...
Also, I'd suggest using "local" for everything, above seem to be all globals, and if you're handling prototypes, it gotta be easy to make a mistake with these.
Locals shouldn't end up in a resulting global environment, and mod code can't even see them.
Also wrt locals, I think you should be able to do e.g.:
...
local resulting_item_count
do
local proto = item_proto game.proto.item[item_name]
... -- do anything you want in here with locals only
resulting_item_count = ...
end -- all locals within this block get dropped here
... -- do stuff with resulting_item_count here, or guess you can use it as global
But anyway, good illustration of why standboxing from actual factorio API is pretty much necessary in such mod.
sorry I thought I tried game.proto.item[item_name].stack_size
thanks
Though idk why game tries to serialize the item_proto value after it's been set to nil, weird...
I think I now understood (though too lazy to actually test), that your issue was item_proto = game.proto.item[item_name]
line immediately causing an issue. Because that line should set value in "global.vars", and guess factorio checks and raises error right there.
And yeah, fix for that would definitely be "just use locals everywhere" - it's actually very uncommon to see non-locals in lua, as it's incredibly hard to reason about one giant global state, and very easy to do so with just couple locals that lua immediately forgets once specific small code block - function, loop, if, etc - ends.
I was only not using locals (hopefully) temporarily for debugging purposes because locals don't show up in the environment variable list
I am still getting the LuaCustomTable cannot be serialized error... even though I haven't done the proto stuff yet in the save (I haven't been able to save since I first did it). I completely restarted the game. I removed all MLCs. I don't even know how that is possible?
okay disabling the mod allowed me to save
I completely restarted the game. I removed all MLCs. I don't even know how that is possible?
Restarting factorio shouldn't change much, it should load same mods on start and then load same game state from the save.
Removing MLCs though should indeed clear all state associated with them, so not sure where that weird ref might've ended up either.
But guess it's a stern reminder not to expose too much of the internals haphazardly.
For something like stack sizes, maybe simplier way would be to make a small local stacks = {wood=25, ...}
table for a couple items that you track there, and use that instead of going to the complicated mess of prototypes.
okay sorry but I am STILL having problems with this lol
I disable ML, I save the game, I re-enable ML, I load into my save, I am able to save. I place a MLC, I do nothing else. I try to save, I get the LuaCustomTable error. And removing the MLC doesn't help. Only thing that fixes it is disabling the mod.
For something like stack sizes, maybe simplier way would be to
You know what they say never spend 6 minutes doing something by hand, that you can spend 6 hours failing to automate it. This is factorio after all.
Hm, guess I'll try removing these prototypes from environment just to be safe, not sure if it'd help though.
But then again, don't know why this thing would happen either - might be something simple that I'm missing, or something really weird, or anything in-between really.
Wonder if https://mods.factorio.com/mod/gvv might also help, actually, though I haven't used it myself - it seem to allow exploring what exactly you have in mod globals, so you might be able to see that weird reference in there. I'll add a bit of code that activates tracking in that mod, if it's enabled.
gvv mod is indeed very neat and easy to use - just type /gvv console command and explore away:
Added its activation in 0.0.27.
Didn't remove prototypes from the lua env for now, but maybe you can check what is stored in this mod's globals and find if these prototypes somehow ended up there?
Can't really imagine how, but can't really figure out what's going on here anyway, so what do I know.
Wait, no, I can totally reproduce this issue here.
Just never tried to save since adding these stupid things.
Will fix by removing, should probably work.
EDIT: yup, totally works.
0.0.28 should fix that save issue. Fixed it for me.
Fix is to just not reference these prototypes tables in a file-wide locals.
I don't understand why that's the issue, as afaik factorio should not save or care about these in any way.
And in fact mod definitely has to re-initialize them on every load, but for some reason storing these particular values there is still a problem. Oh well.
fine! I'll just hard code the values like a caveman!
thanks for trying :)
and gvv is awesome
fine! I'll just hard code the values like a caveman!
Well, if you want to go caveman, just make a bunch of wooden chests, put one full stack of everything you can find around the factory into these and connnect them all with a wire :)
I actually considered that! A slightly more dynamic solution would be to limit a chest to one slot and fill it with the item I want to check the stack size of. But eh thats not very elegant.
Something just occurred to me. How is it that gvv is able to view the LuaCustomTable stuff without causing issues where as in moon logic just exposing the proto stuff causes problems saving?
Well, accessing that stuff from the mod is definitely not an issue.
Thing that was done for exposing these tables was to put them into a local sanbox_base_env ...
table here - https://github.com/mk-fg/games/blob/3f7be54/factorio/Moon_Logic/control.lua#L72-L112 - and that apparently was fatal all by itself for saves, as it crashed for me without anything touching those values there.
There's probably a perfectly reasonable explaination for it, but I think it's not very relevant, given how hazardous that stuff is for randomly thrown-together poorly-tested not-well-thought-out one-off code snippets, which these combinators are kinda for.
Should be possible to add some kind of "EXPOSE EVERYTHING" mod option, but dunno if I'd ever bother enabling it myself, given how much trouble it might cause for not much worth :)
And again, proper fix I think is to "sanitize" these tables, i.e. iterate over all those 20-40 tables of 1000s of things (entities, items, recipes, techs, sounds, effects, sprites, tiles, etc) - or maybe some subset of them - and keep lua definitions which you can dump or access freely, unlike internal factorio C++ interfaces.
E.g. printing some LuaItemPrototype would just give some unhelpful {userdata}
, which seem to be a bug all in itself within the scope of this mod.
But given concrete "I'm too lazy to put stack size constant for couple items - but apparently not lazy enough to go read up factorio lua-api docs" use-case, that seem to be either a lot of junk data to copy and code/complexity to process it, and/or too specific to bother with, really.
Actually, given that "remote" is already there, maybe won't be that bad of an idea to put a proxy to all factorio api as an "_api" into that env or something, but not suggest for anyone to ever use it. And it won't hold any references to factorio types, just a proxy table.
Will probably add and test tomorrow, and you should be able to get to those prototype tables from there, as well as "remote" and all other APIs, with same caveat that any wrong value there will insta-crash the game, ofc.
randomly thrown-together poorly-tested not-well-thought-out one-off code snippets
I feel personally attacked
But given concrete "I'm too lazy to put stack size constant for couple items - but apparently not lazy enough to go read up factorio lua-api docs" use-case
oof. and again lol
Actually, given that... ...insta-crash the game, ofc.
I understand all these words individually and yet I don't really know what you just said
you should be able to get to those prototype tables from there
That would be awesome! Thanks for working on this. Yes, admittedly the use case for this is pretty small. But if it works it will save me like two whole seconds! Although I could probably come up for more uses than just getting the stack size. You could do stuff with recipes and well every property of items In what way specifically and what purpose that would server, I don't know. I'm sure it will be cool though.
Added in 0.0.32.
insta-crash the game, ofc.
My mistake here - I thought that you can't trap errors from using factorio APIs via lua pcall(), i.e. if you do something bogus like game.delete_surface(1)
, it'd crash the game with a "mod error" window, but apparently that's not the case - it raises regular lua errors, which are trapped and highlighted as usual.
So it's much safer to use than I thought, but still allows to do many game-breaking things, of course.
All factorio global objects should be present there, I think - script, game, remote, defines, settings, rendering, global, etc.
For item stack size, you'd want to use something like local wood_stack = _api.game.item_prototypes.wood.stack_size
, with same docs for it all as mentioned above.
thanks! Its working and no crashes so far!