Page 1 of 1

Can I take data like recipes from python, lupa?

Posted: Fri Jul 09, 2021 2:17 pm
by danaka1234
Sorry for my poor english.

I want to make tool like factorio-calculator by python 3(using pyqt5).
So I use this code for taking factorio data (like data.raw).

Code: Select all

import os
import lupa

path_factorio = 'E:\\[Working]\\FactorioCalculator\\facback_1.1.26'

list_func = [\
    'function math.pow(num1, num2) return (num1 ^ num2) end'\
    ]
    
path_data = os.path.join(path_factorio, 'data')
#path_data = path_factorio
path_base = os.path.join(path_data, 'base')
path_core = os.path.join(path_data, 'core')
lua = lupa.LuaRuntime(unpack_returned_tuples=True)
lua.globals().package.path += ';' + os.path.join(path_data, '?.lua') \
                            + ';' + os.path.join(path_core, '?.lua') \
                            + ';' + os.path.join(path_core, 'lualib', '?.lua') \
                            + ';' + os.path.join(path_base, '?.lua')
             
#add missing function
for func in list_func:
    lua.execute(func)
    
        
#load core
lua.require('dataloader')
lua.require('defines')
lua.require('core.data')
lua.require('base.data')
It works until v1.0.
But it don't work after v1.1.26.

I am attaching the error message below.
Traceback (most recent call last):
File ".\lua_test.py", line 38, in <module>
lua.require('base.data')
File "lupa\_lupa.pyx", line 317, in lupa._lupa.LuaRuntime.require
File "lupa\_lupa.pyx", line 1306, in lupa._lupa.call_lua
File "lupa\_lupa.pyx", line 1332, in lupa._lupa.execute_lua_call
File "lupa\_lupa.pyx", line 1268, in lupa._lupa.raise_lua_error
lupa._lupa.LuaError: ...io\data\base\prototypes\entity\spidertron-animations.lua:521: module '__base__/prototypes/entity/spidertron-light-positions' not found:
no field package.preload['__base__/prototypes/entity/spidertron-light-positions']
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\lua\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\lua\__base__/prototypes/entity/spidertron-light-positions\init.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\__base__/prototypes/entity/spidertron-light-positions\init.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\..\share\lua\5.3\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\..\share\lua\5.3\__base__/prototypes/entity/spidertron-light-positions\init.lua'
no file '.\__base__/prototypes/entity/spidertron-light-positions.lua'
no file '.\__base__/prototypes/entity/spidertron-light-positions\init.lua'
no file 'C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\core\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\core\lualib\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\base\__base__/prototypes/entity/spidertron-light-positions.lua'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\__base__/prototypes/entity/spidertron-light-positions.dll'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\..\lib\lua\5.3\__base__/prototypes/entity/spidertron-light-positions.dll'
no file 'C:\Users\danak\AppData\Local\Programs\Python\Python37\loadall.dll'
no file '.\__base__/prototypes/entity/spidertron-light-positions.dll'
stack traceback:
[C]: in function 'require'
...io\data\base\prototypes\entity\spidertron-animations.lua:521: in function 'spidertron_torso_graphics_set'
...common\Factorio\data\base\prototypes\entity\entities.lua:15235: in function 'create_spidertron'
...common\Factorio\data\base\prototypes\entity\entities.lua:15531: in main chunk
[C]: in function 'require'
...(x86)\Steam\steamapps\common\Factorio\data\base\data.lua:5: in main chunk
[C]: in function 'require'
There is no problem when running, loading, and saving the game with the data generating the above error.

Can you tell me how to fix the error or a new way to load the data?

To help you understand, I attached an image of the tool I was making.
Image

Re: Can I take data like recipes from python, lupa?

Posted: Fri Jul 09, 2021 5:43 pm
by DaveMcW
Here are the imports I use:

Code: Select all

#load core
lua.require('dataloader')
lua.require('defines')
lua.require('core.data')
lua.require('base.data')

Re: Can I take data like recipes from python, lupa?

Posted: Sat Jul 10, 2021 3:33 am
by danaka1234
DaveMcW wrote: Fri Jul 09, 2021 5:43 pm Here are the imports I use:

Code: Select all

#load core
lua.require('dataloader')
lua.require('defines')
lua.require('core.data')
lua.require('base.data')
Thanks for your reply.
Sorry. There was a typo in the text.
I used the same code as you pointed out, but the code has errors
The code in the body is incorrect code that has been corrected for testing.
lua.require('data') actually loads code.data.
Edited text to avoid confusion.
lua.require('data') > lua.require('base.data')

Re: Can I take data like recipes from python, lupa?

Posted: Sat Jul 10, 2021 4:58 am
by DaveMcW
Here is my working script.

Code: Select all

import os
import lupa

# https://github.com/wube/factorio-data/archive/refs/tags/1.1.35.zip
path_data = '/home/davemcw/Downloads/factorio-data-1.1.35'

lua = lupa.LuaRuntime(unpack_returned_tuples=True)
lua.globals().package.path += ';' + os.path.join(path_data, 'core', 'lualib', '?.lua') \
                            + ';' + os.path.join(path_data, 'core', '?.lua') \
                            + ';' + os.path.join(path_data, 'base', '?.lua')

# add missing function math.pow()
lua.execute('function math.pow(num1, num2) return (num1 ^ num2) end')

# defines
lua.globals().defines = {
    "difficulty_settings": {
        "recipe_difficulty": {"normal": 0, "expensive": 1},
        "technology_difficulty": {"normal": 0, "expensive": 1},
    },
    "direction": {
        "north": 0,
        "east": 2,
        "south": 4,
        "west": 6,
    },
}

# load core
lua.require('dataloader')
lua.require('data.core.data')
lua.require('data.base.data')

Re: Can I take data like recipes from python, lupa?

Posted: Sat Jul 10, 2021 8:01 am
by danaka1234
Thank you for answer.
As a result of running the link and code in the answer as is, the error below appears.
I guess the problem is because the data directory does not exist.

error 1
Traceback (most recent call last):
File ".\test.py", line 32, in <module>
lua.require('data.core.data')
File "lupa\_lupa.pyx", line 317, in lupa._lupa.LuaRuntime.require
File "lupa\_lupa.pyx", line 1306, in lupa._lupa.call_lua
File "lupa\_lupa.pyx", line 1332, in lupa._lupa.execute_lua_call
File "lupa\_lupa.pyx", line 1268, in lupa._lupa.raise_lua_error
lupa._lupa.LuaError: module 'data.core.data' not found:

To make it work as similarly as possible, I've applied the fixes below.
1. Add os.path.join(path_base, '?.lua') to path.
2. Change data.core.data to core.data
3. Change data.base.data to base.data

After applying the above fix, the same error as the first occurs.

I am attaching the modified code for verification.

Code: Select all

import os
import lupa

# https://github.com/wube/factorio-data/archive/refs/tags/1.1.35.zip
#path_data = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Factorio'
path_data = 'E:\\Downloads\\factorio-data-1.1.35'

lua = lupa.LuaRuntime(unpack_returned_tuples=True)
lua.globals().package.path += ';' + os.path.join(path_data, 'core', 'lualib', '?.lua') \
                            + ';' + os.path.join(path_data, 'core', '?.lua') \
                            + ';' + os.path.join(path_data, 'base', '?.lua') \
                            + ';' + os.path.join(path_data, '?.lua')

# add missing function math.pow()
lua.execute('function math.pow(num1, num2) return (num1 ^ num2) end')

# defines
lua.globals().defines = {
    "difficulty_settings": {
        "recipe_difficulty": {"normal": 0, "expensive": 1},
        "technology_difficulty": {"normal": 0, "expensive": 1},
    },
    "direction": {
        "north": 0,
        "east": 2,
        "south": 4,
        "west": 6,
    },
}

# load core
lua.require('dataloader')
#lua.require('data.core.data')
#lua.require('data.base.data')
lua.require('core.data')
lua.require('base.data')
Tried it on at least 2 computers.
Looking at the code you gave, it looks like Linux, is this a problem because it is run in a Windows environment?


DaveMcW wrote: Sat Jul 10, 2021 4:58 am Here is my working script.

Code: Select all

import os
import lupa

# https://github.com/wube/factorio-data/archive/refs/tags/1.1.35.zip
path_data = '/home/davemcw/Downloads/factorio-data-1.1.35'

lua = lupa.LuaRuntime(unpack_returned_tuples=True)
lua.globals().package.path += ';' + os.path.join(path_data, 'core', 'lualib', '?.lua') \
                            + ';' + os.path.join(path_data, 'core', '?.lua') \
                            + ';' + os.path.join(path_data, 'base', '?.lua')

# add missing function math.pow()
lua.execute('function math.pow(num1, num2) return (num1 ^ num2) end')

# defines
lua.globals().defines = {
    "difficulty_settings": {
        "recipe_difficulty": {"normal": 0, "expensive": 1},
        "technology_difficulty": {"normal": 0, "expensive": 1},
    },
    "direction": {
        "north": 0,
        "east": 2,
        "south": 4,
        "west": 6,
    },
}

# load core
lua.require('dataloader')
lua.require('data.core.data')
lua.require('data.base.data')

Re: Can I take data like recipes from python, lupa?

Posted: Sat Jul 10, 2021 8:47 am
by DaveMcW
Now I remember, I had the same problem and fixed it by creating a symbolic link in my home folder. That is why it works on my computer. :)

Code: Select all

mklink /D __base__ "C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\base"

Re: Can I take data like recipes from python, lupa?

Posted: Sat Jul 10, 2021 9:14 am
by danaka1234
Thank you for answer.
It works perfectly fine through that command.
I'll add a link to my script and delete it after loading lua.
Administrator privileges are required, and if there is a way to bypass it, I will add it to this article.
DaveMcW wrote: Sat Jul 10, 2021 8:47 am Now I remember, I had the same problem and fixed it by creating a symbolic link in my home folder. That is why it works on my computer. :)

Code: Select all

mklink /D __base__ "C:\Program Files (x86)\Steam\steamapps\common\Factorio\data\base"