Moon Logic deprecated

by mk-fg

Adds Lua-programmable circuit network combinator. Based on Sandboxed LuaCombinator and LuaCombinator2 mods. Probably won't work in multiplayer games.

Content
2 years ago
1.0 - 1.1
4.97K
Circuit network

i [fixed] Access item information

4 years ago

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

4 years ago

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).

4 years ago
(updated 4 years ago)

"data" table

Correction, it's apparently game.<something>_prototypes tables at runtime.

4 years ago
(updated 4 years ago)

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

4 years ago
(updated 4 years ago)

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...

4 years ago

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 :)

4 years ago

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.

4 years ago
(updated 4 years ago)

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.

4 years ago
(updated 4 years ago)

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)

4 years ago

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...

4 years ago

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.

4 years ago
(updated 4 years ago)

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.

4 years ago

sorry I thought I tried game.proto.item[item_name].stack_size
thanks

4 years ago
(updated 4 years ago)

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.

4 years ago

I was only not using locals (hopefully) temporarily for debugging purposes because locals don't show up in the environment variable list

4 years ago

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?

4 years ago

okay disabling the mod allowed me to save

4 years ago

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.

4 years ago
(updated 4 years ago)

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.

4 years ago

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.

4 years ago
(updated 4 years ago)

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.

4 years ago
(updated 4 years ago)

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.

4 years ago
(updated 4 years ago)

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.

4 years ago

fine! I'll just hard code the values like a caveman!

thanks for trying :)

and gvv is awesome

4 years ago

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 :)

4 years ago

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?

4 years ago
(updated 4 years ago)

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 :)

4 years ago

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.

4 years ago

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.

4 years ago

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.

4 years ago
(updated 4 years ago)

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.

4 years ago

thanks! Its working and no crashes so far!

New response