Can somebody tell me what is wrong with this code?

Place to get help with not working mods / modding interface.
Post Reply
User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Can somebody tell me what is wrong with this code?

Post by DRY411S »

It is bound to be something stupid, but I have been poring over it and cannot see what I'm doing wrong.

I'm trying to change the recipe for the vanilla battery, so that it is hidden. The default is that it is NOT hidden.

At the data stage I have this.

Code: Select all

data.raw.recipe["battery"].normal.hidden = true
data.raw.recipe["battery"].expensive.hidden = true
But if I immediately serpent_block dump the data.raw.recipe["battery"] after this I see that the properties have not changed.
serpent_block dump

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by bobingabout »

when dealing with a difficulty split recipe, some tags go on the normal/expensive tables, where others go directly onto the recipe table.

I am not sure if hidden should be on the recipe table, or the difficulty tables.
Have you tried this to see if it has any effect?

Code: Select all

data.raw.recipe["battery"].hidden = true

EDIT: After looking back at your table block there, it probably should go on the difficulty, but I'll leave this here anyway, it's still worth a try if you haven't already.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by DRY411S »

bobingabout wrote:when dealing with a difficulty split recipe, some tags go on the normal/expensive tables, where others go directly onto the recipe table.

I am not sure if hidden should be on the recipe table, or the difficulty tables.
Have you tried this to see if it has any effect?

Code: Select all

data.raw.recipe["battery"].hidden = true

EDIT: After looking back at your table block there, it probably should go on the difficulty, but I'll leave this here anyway, it's still worth a try if you haven't already.
I have tried the code without the difficulty included, like you suggested, but that wasn't working either, which is when I started to include the difficulty. I have dumped the table block immediately prior to my code executing, and confirmed that normal.hidden and expensive.hidden are both present, and both false. So I really don't understand why my code isn't changing them to true.

Edit: The recipe prototype documentation says that most properties are read-only, so I'm wondering whether I need to do some table.remove, table.insert, data.extend type of thing, though I've no idea how.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by DRY411S »

I've partly fixed this:

Code: Select all

local battery = {}
battery = data.raw.recipe.battery
battery.normal.hidden = true
battery.expensive.hidden = true
data.raw.recipe.battery = battery
SERPENT BLOCK OUTPUT
So it appears that data.raw.recipe.normal.hidden IS read-only, but data.raw.recipe.battery is not.

This problem has therefore moved on from a coding error to what happens at run-time

As soon as the game starts. and from the console I type:

Code: Select all

/c game.player.print (game.player.force.recipes["battery"].normal.hidden)
I get an error about LuaRecipe not containing the key normal. This is what I'd expect because the game has decided whether to use normal or expensive recipes.

BUT, when I type

Code: Select all

/c game.player.print (game.player.force.recipes["battery"].hidden)
I am told at the console that the value is once again false. :(

User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2919
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by Optera »

When I create a new recipe with recipe.hidden = false it will correctly hide the recipe in game.
recipe.difficulty.hidden might be link to recipe.hidden.

Having read only properties during data phase feels odd. Did you try
local battery = table.deepcopy(data.raw.recipe["battery"])
battery.hidden = true
data.raw.recipe["battery"] = battery
table.deepcopy ensures it's a fresh table and not a link to the original. It shouldn't make a difference here but who knows.


Edit just tested it, that doesn't seem to hide the recipe either.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by DRY411S »

I'm starting to lose the will to live on this. The code I posted earlier:

Code: Select all

local battery = {}
battery = data.raw.recipe.battery
battery.normal.hidden = true
battery.expensive.hidden = true
data.raw.recipe.battery = battery
appears to set the normal and hidden flags to true, but as described in my post above, they've been reset to false at run time.

Bizarrely, if I remove the last line on the above code, namely:

Code: Select all

data.raw.recipe.battery = battery
then at run time the flag IS true!

Here's some similar code that throws an error I cannot explain:

Code: Select all

local newbattery = {}
newbattery = data.raw.recipe.battery
newbattery.normal.hidden = true
newbattery.expensive.hidden = true
newbattery.category = "crafting-with-fluid"
newbattery.name =  "assembler-battery"
data.raw.recipe["assembler-battery"] = newbattery
The error message is:

Code: Select all

Mods to disable:Failed to load mods: Prototype name (assembler-battery) does not match the key name (battery).
But I've just changed the name to "assembler-battery"

I am utterly, utterly confused. I think I'm failing to understand something fundamental about either Lua, the factorio data, or both. :cry:

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by DRY411S »

Optera wrote:<snip><snip>
table.deepcopy ensures it's a fresh table and not a link to the original. It shouldn't make a difference here but who knows.
That is probably the fundamental thing that I was not understanding. I think it IS making a difference, especially in my 2nd code snippet. Thank you!

User avatar
withers
Fast Inserter
Fast Inserter
Posts: 125
Joined: Fri Apr 08, 2016 4:54 pm
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by withers »

DRY411S wrote:
Optera wrote:<snip><snip>
table.deepcopy ensures it's a fresh table and not a link to the original. It shouldn't make a difference here but who knows.
That is probably the fundamental thing that I was not understanding. I think it IS making a difference, especially in my 2nd code snippet. Thank you!
I can't answer your original question, it's very puzzling. But to maybe help clear things up for you, when you say

newbattery = data.raw.recipe.battery

That does not create a new table. It just says "newbattery" is a reference to the table that already exists at "data.raw.recipe.battery".

So after this any change to specific variable referenced by newbattery OR data.raw.recipe.battery would change both, since they are both pointing at the same location in memory.

Like you already mentioned, you have to use deepcopy to make a new table.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Can somebody tell me what is wrong with this code?

Post by DRY411S »

Optera wrote:When I create a new recipe with recipe.hidden = false it will correctly hide the recipe in game.
<snip>
That is true unless the recipe prototype has normal and expensive ingredients. Some of the recipes don't have normal and expensive tables in the prototypes, in which case you can just use recipe.hidden. But in my case I am amending the vanilla battery recipe prototype which does have normal and expensive ingredients. Each of the normal and expensive tables have separate hidden properties.
Optera wrote:<snip>Did you try
local battery = table.deepcopy(data.raw.recipe["battery"])
battery.hidden = true
data.raw.recipe["battery"] = battery
table.deepcopy ensures it's a fresh table and not a link to the original. It shouldn't make a difference here but who knows.


Edit just tested it, that doesn't seem to hide the recipe either.
My code is fixed after Optera and withers showed me the way with table.deepcopy. I should have been using this elsewhere in my code.
withers wrote:I can't answer your original question, it's very puzzling. <snip>
It is, and I still cannot explain why it wasn't working. It works now. It's possibly due to not using table.deepcopy elsewhere in my code, but I cannot think how.

So, just to confirm that it IS possible to use data.raw.recipe[name]..., the final working version of the code is this, but using a pointer with a local variable is equally valid.

Code: Select all

-- Hide the vanilla recipe for Chemical Plant batteries
data.raw.recipe.battery.normal.hidden = true
data.raw.recipe.battery.expensive.hidden = true
data.raw.recipe.battery.normal.enabled = false
data.raw.recipe.battery.expensive.enabled = false
Thanks to bobingabout, Optera and withers for helping me see the light and fix this. It was literally keeping me awake at night!

Post Reply

Return to “Modding help”