Packp3d and Pandai problem

Hi,

I have created a simple script using PandAI to move my characters point-and-click style. When I pack the script using packp3d and run the output file, the window never opens and it just silently terminates. Checking the logs I found the following (in p3dsession.log):

:AppRunner: Total Panda3D disk space used: 248 MB
:AppRunner: Configured max usage is: 2048 MB
Traceback (most recent call last):
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\showbase\Messenger.py", line 415, in __taskChainDispatch
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\showbase\Messenger.py", line 473, in __dispatch
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\p3d\AppRunner.py", line 745, in __startIfReady
  File "VFSImporter", line 153, in load_module
  File "D:\b\workspace\SpeedStrat\src\main.py", line 1, in <module>
    from speedstrat.Application import Application
  File "VFSImporter", line 153, in load_module
  File "D:\b\workspace\SpeedStrat\src\speedstrat\Application.py", line 8, in <module>
    from panda3d.ai import *
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\bin\panda3d.py", line 145, in __getattr__
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\bin\panda3d.py", line 122, in libimport
ImportError: DLL loader cannot find libpandaai.
:task(error): Exception occurred in PythonTask Messenger-default
Traceback (most recent call last):
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\p3d\AppRunner.py", line 636, in run
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\task\Task.py", line 502, in run
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\task\Task.py", line 460, in step
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\showbase\Messenger.py", line 415, in __taskChainDispatch
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\showbase\Messenger.py", line 473, in __dispatch
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\direct\p3d\AppRunner.py", line 745, in __startIfReady
  File "VFSImporter", line 153, in load_module
  File "D:\b\workspace\SpeedStrat\src\main.py", line 1, in <module>
    from speedstrat.Application import Application
  File "VFSImporter", line 153, in load_module
  File "D:\b\workspace\SpeedStrat\src\speedstrat\Application.py", line 8, in <module>
    from panda3d.ai import *
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\bin\panda3d.py", line 145, in __getattr__
  File "C:\buildslave\release_rtdist_win32\build\panda3d\built_cmu\bin\panda3d.py", line 122, in libimport
ImportError: DLL loader cannot find libpandaai.
Failure on startup.

Anyone have any experience with this? It seems like it cannot load libpandaai, but I can confirm libpandaai.dll is in \Panda3D-1.7.2\bin\ folder.

When packaging your app try:
packp3d -r ai

as per this manual page

Hope this helps,
~powerpup118

Yes, thank you, it is working perfectly, and of course I am a bit ashamed I overlooked that page (though I remember reading it some weeks before :slight_smile: ).

Unfortunately, I have a new problem. PandAI pathfinding uses csv file to store navigation mesh. I have created this file and stored it in my application’s “/data/levels/” directory. I also store levels there which are plain .txt files. When packing I am using “-n txt -n csv” args and my levels are loading fine using standard open call:

levelfile = open('data/levels/'+name, "r")

They haven’t loaded before I added the -n argument so I know that was the problem.
However, csv file is not loading correctly, p3dsession.log says:

error opening navmesh.csv file!

The code for this is:

self.AIbehaviors.initPathFind("data/levels/navmesh.csv")

I know I am screwing something up with my paths, but am just not sure what. Any ideas?

Hm I guess this is caused because file opening is actually not done in Python at all, but in c++ in pathFind.cxx file using ifstream. I must admit I am a bit over my head here, not sure how dlls resolve paths in p3d packed files. I have checked my file with multify and csv is definitely in there.

Hi, that makes complete sense.

Panda only replaces the Python hooks for open() etc calls in Python.

I would bet it might be really hard to do that in C++, then again…

Anywho, you should just pass the real path to panda ai instead.

For instance:

self.AIbehaviors.initPathFind(base.appRunner.multiFileRoot + "/data/levels/navmesh.csv")

That means, in reality, that you want a file inside the p3d itself.
Of course, base.appRunner.multiFileRoot only exists when running in a p3d, so you could use:

csv = 'data/levels/navmesh.csv'
if base.appRunner:
    csv = base.appRunner.multiFileRoot + '/' + csv

And I’m pretty sure that should work, if you’ve any problems let me know (since I never tested this actually)

Hope this helps,
~powerpup118

Hey,

thank you very much for the reply, I already began thinking about doing changes to pandai lib :slight_smile:. Your message gives me hope that this can still somehow be resolved.

Unfortunately, using base.appRunner.multifileRoot did not work - it points to /c/Users/ognjenk/AppData/Local/Panda3D/start
and I do not have csv file there. Now, if there is no way to access file in p3d from c++, I guess the workaround would be to copy the navmesh file to multifileroot at the start of the script and then use your line to read it when initiating AI.

Is that something that sounds like it might work? Or any other solutions are much appreciated!

Hmm, it sounds like PandaAI might be failing to use the Panda VFS to open and read files internally. If so, the C++ code will need to be corrected before you can use it within a P3D file.

David

Ok, thank you, I was afraid of that.
I will try to work around the issue and maybe get in contact with PandAI developers to see if they can change their loading code.

Ok, to let you know, I have worked around this issue by doing:

if self.appRunner:
    fin = open('data/levels/navmesh.csv', 'r')
    fout = open(self.appRunner.multifileRoot + '/navmesh.csv', 'w')
    for line in fin:
        fout.write(line)
    fin.close()
    fout.close()

and then when initializing AI:

csv = 'data/levels/navmesh.csv' 
if self.appRunner:
    csv = self.appRunner.multifileRoot + '/navmesh.csv' 
    csv = Filename(csv).toOsSpecific()

self.AIbehaviors.initPathFind(csv)

Thanks everyone for the help!

Your fix could actually be a bit slow, going line by line in a python for loop.

And actually, even though your code says ‘for line in’ you’re never actually using ‘lines’ split by the ‘\n’ character, instead you are copying byte-by-byte in a for loop.

For a bit of a ‘faster’ method, you should instead just copy all of the bytes in the file directly.

if self.appRunner:
    fin = open('data/levels/navmesh.csv', 'r')
    fout = open(self.appRunner.multifileRoot + '/navmesh.csv', 'w')
    fout.write(fin.read()) #- Copy all bytes directly instead
    fin.close()
    fout.close()

Depending on how large your file is, it could speed it up by a few seconds even! :wink:

~powerpup118

For the record, the syntax “for line in fin” is a special Python convention that actually walks through the lines as read from the file, and is equivalent to “for line in fin.readlines()”. It doesn’t go byte-by-byte.

In any case, the file would have to be very large indeed for this operation to detectably slower than read() followed by write().

David

Ah, you are correct! I was wrong.
Thank you for teaching me a little bit more python magician’s moves 8)

~powerpup118

Well I am pretty new to Python and Panda3d so I am glad for any hints you throw my way :slight_smile:
The file is not that big, around 300k and loading and saving times were not that long to be noticed.