Page 1 of 1

cannot read recipe subgroup from data.raw

Posted: Fri Apr 25, 2025 11:40 pm
by scruffyvoltherder
I'm trying to copy recipes in data-final-fixes.lua, and I need to be able to read the subgroup. None of the recipes in data.raw["recipe"] have the subgroup member present. If I deepcopy a recipe, it still has the original subgroup. I can change the subgroup, but i need to be able to modify the subgroup based on the original name.

Re: cannot read recipe subgroup from data.raw

Posted: Sun Apr 27, 2025 4:54 pm
by yaim904
I think I can help you, but I don't understand the explanation.

Can you give me a code or before and after data?

Re: cannot read recipe subgroup from data.raw

Posted: Fri May 16, 2025 12:48 am
by scruffyvoltherder

Code: Select all

local function process_recipe(name, recipe)

    if not recipe.results or next(recipe.results) == nil then return end
    if ends_with(name,"_rcomb") then return end


    local new_recipe=table.deepcopy(recipe)
    new_recipe.name=new_recipe.name.."_rcomb"
    new_recipe.hide_from_signal_gui = false
    new_recipe.show_amount_in_title = true
    
    local sg = new_recipe.subgroup
    -- SG is nil here
    
    new_recipe.subgroup="recipe-subgroup"
    --but i can assign it here. 
    
    new_recipe.localised_name=recipe.name

    data.raw.recipe[name.."_rcomb"]=new_recipe

Re: cannot read recipe subgroup from data.raw

Posted: Sat May 17, 2025 12:54 am
by yaim904
scruffyvoltherder wrote: Fri May 16, 2025 12:48 am
I don't see any error in your code, I think you are missing information.

I suggest changing this line

Code: Select all

    new_recipe.localised_name=recipe.name
To the following line, if you want to assign a name to the object depending on the language and not just the name of the object.

Code: Select all

    new_recipe.localised_name={recipe.name}
Documents

--------------------------------------------------------------------------------------

I think your problem is that you have not created the subgroup.

The following is an example of the code to create a sub-group

Code: Select all

data:extend({
    {
        [ 'type' ] = 'item-subgroup',
        [ 'name' ] = 'recipe-subgroup',
        [ 'group' ] = 'logistics',
        [ 'order' ] = 'a'
    }
})
Recipes can be linked to a subgroup, but the subgroup must be created. The order property will give you the position in which it will appear. Also, note that each subgroup must belong to a group (or you can create your own).

The following is an example of the code of a group

Code: Select all

{
    [ 'type' ] = 'item-group',
    [ 'name' ] = 'logistics',
    [ 'order' ] = 'a',
    [ 'icon' ] = '__base__/graphics/item-group/logistics.png',
    [ 'icon_size' ] = 128
}
This information can be found at

Code: Select all

data.raw["item-group"]
data.raw["item-subgroup"]
13 - copia.png
13 - copia.png (202.35 KiB) Viewed 641 times
--------------------------------------------------------------------------------------
I hope I've been helpful, and if not, I'll look forward to hearing from you.

Re: cannot read recipe subgroup from data.raw

Posted: Tue Jun 10, 2025 9:21 pm
by scruffyvoltherder
I've created a group and subgroup for my new recipes. I don't have any problem assigning them into that subgroup. The problem though, is that i want to create similarly named subgroups inside my group as the original recipe. However, i can't figure out how to get the original subgroup from the old recipe.

Putting the recipe name in brackets doesn't work, i get unknown key errors
trying

Code: Select all

new_recipe.localised_name={"recipe-name."..recipe.name}
works for some recipes, but not all of them.

Re: cannot read recipe subgroup from data.raw

Posted: Tue Jun 10, 2025 9:56 pm
by Lihop
scruffyvoltherder wrote: Fri May 16, 2025 12:48 am

Code: Select all

local function process_recipe(name, recipe)

    if not recipe.results or next(recipe.results) == nil then return end
    if ends_with(name,"_rcomb") then return end


    local new_recipe=table.deepcopy(recipe)
    new_recipe.name=new_recipe.name.."_rcomb"
    new_recipe.hide_from_signal_gui = false
    new_recipe.show_amount_in_title = true
    
    local sg = new_recipe.subgroup
    -- SG is nil here
    
    new_recipe.subgroup="recipe-subgroup"
    --but i can assign it here. 
    
    new_recipe.localised_name=recipe.name

    data.raw.recipe[name.."_rcomb"]=new_recipe
Is this code complete because a final "end" is missing, whatever.
Some of recipe name is based on the product.
With your function, is your recipe fully functional or what is missing ? Only subgroup ? Did you see recipe in game ?

Re: cannot read recipe subgroup from data.raw

Posted: Wed Jun 11, 2025 1:39 am
by scruffyvoltherder
Yes, they do show up in-game. right now i'm just adding the copied recipes into a subgroup called "recipe-subgroup". What i want to do is create subgroups based on the original recipe's subgroup.

for example, if the original recipe had the "circuit-network" subgroup, i want the copied recipe to have the subgroup "circuit-network-rcomb". all of the rcomb recipes are going to sit in their own tab.

The problem is though, that I cannot read the subgroup from the original recipe. If i were to deepcopy the recipe, and not assign any values to the subgroup member, my copied recipe would end up right next to the original. I don't understand how that information can get transferred from the old recipe to the copy when i do a deepcopy, but cannot be read by my lua script.

deepcopying a recipe gives the new recipe the same subgroup as the old one, but if i try

Code: Select all

local recipe_subgroup = recipe.subgroup
local new_recipe_subgroup=recipe_subgroup.."-rcomb"
--check if subgroup for new recipe exists already
--create new subgroup if not
new_recipe.subgroup=new_recipe_subgroup
recipe_subgroup comes back as null, therefore therefore there is no way to derive a name for the subgroup that the new recipe will be in.

Re: cannot read recipe subgroup from data.raw

Posted: Wed Jun 11, 2025 5:11 am
by Lihop
According to your code If recipe_subgroup comes back as nil, you get an error because concatenate nil and string is not possible.(Line 2)
If you get an error when loading, send us the error if it pass can you send us the newly named subgroup

Copying with deepcopy copy all the table, there is no reason you can't access the subgroup or comes back as nil (if it exists)

Re: cannot read recipe subgroup from data.raw

Posted: Wed Jun 11, 2025 9:08 am
by Pi-C
scruffyvoltherder wrote: Wed Jun 11, 2025 1:39 am for example, if the original recipe had the "circuit-network" subgroup, i want the copied recipe to have the subgroup "circuit-network-rcomb". all of the rcomb recipes are going to sit in their own tab.
If you really want to create a new tab (next to the vanilla tabs "Logistics", "Production", "Intermediate products", "Combat"), you don't need an ItemSubGroup, but an ItemGroup. Subgroups are the rows within a tab.

ItemGroup::order determines the position of your tab. ItemSubGroup::order determines the order within a tab (affects the row where the recipe will be listed). RecipePrototype::order affects the order of recipes within a row.

To create a new tab, you must create a new group:

Code: Select all

data:extend({
  {
    type = "item-group",
    name = "my-new-group", 
    icons = { },	-- Insert your icon for the tab here!
    localised_name = {"item-group-name.my-new-group"},	-- Add to locale file!
    localised_description = {"item-group-description.my-new-group"},
    order = "zzzz" 	-- Add new tab towards the end
  }
})
An ItemSubGroup is always associated with a certain group, so you must create your own subgroup:

Code: Select all

data:extend({
  -- Create as many subgroups as you need!
  {
    type = "item-subgroup",
    name = "my-subgroup-a", 
    group = "my-new-group", 	-- Must be the same for all subgroups in the same tab!
    order = "order string" 		-- Lexical order of string determines row within this tab
  }
})
Now you can move your recipes to a new tab by assigning them to a subgroup.


As you've already noticed, RecipePrototype::subgroup may not be set. Notably, this is true for vanilla recipes:
recipe-definition.png
recipe-definition.png (299.47 KiB) Viewed 338 times
(You can open the prototype GUI by hovering the cursor over a recipe icon and using the key combination set in "Settings --> Controls --> Debug --> Open prototype explorer GUI".)


What to do in this case? Well, there already is a hint: the prototype for subgroups is called "ItemSubGroup", not "RecipeSubGroup"! So if you have a recipe that doesn't define a subgroup, its subgroup will be derived from whatever is produced by the recipe (see RecipePrototype::results). If a recipe has >1 results, the subgroup will be derived from what is set as RecipePrototype::main_product.

So to determine the subgroup of a recipe, you should:
  • Use recipe.subgroup, if available. This will be set if the recipe produces nothing!
  • No subgroup yet?
    • recipe.main_product is set (name of an item or a fluid):

      Code: Select all

      local result = data.raw.item[recipe.main_product] or data.raw.fluid[recipe.main_product]
      local use_group = result.subgroup
      
    • recipe.results is set: use subgroup of first result

      Code: Select all

      local result = recipe.results[1]
      local use_group = data.raw[result.type][result.name].subgroup