Distributable build: not finding a mouse cursor

My distributable builds – whether self-contained installer or .p3d for web-player – seem to be failing to find the cursor that I want to use in my game.

Said cursor is loaded successfully when the game is run from my IDE, I believe. When I check the log (with the self-contained installer, at least; I don’t see mention of it in the web-player log, but – as another topic of mine may show – the web-player may not be getting that far) seems to indicate that it’s failing to find the cursor file. A check of the contents of the .p3d showed that the cursor was present in the root directory of the .p3d, as I recall.

Why is it failing to load the cursor?

Are you loading it explicitly, or via a cursor-filename config setting? You mention an error message, what is the message exactly?

On Windows, you have to extract the .cur file to disk, because Windows can only load a .cur file from disk (not from within the p3d file). You can do this with file(‘foo.cur’, extract = True) in the pdef file.

David

Hmm… I haven’t been using a pdef at all (I’ve been using packp3d), let alone extracting the cursor file, I believe – that seems likely to be the problem. Thank you!

Looking at the manual, the ppackage system – which I gather to be the way to include a pdef file in my build sequence – looks trickier than the quite simple packp3d.

First of all, what are the keywords to the “config” method in a pdef file?
Do I have to include “panda3d” in my call to “require”? (It looks like it, but that seems odd – surely it would be taken as read that I want to use Panda?)
How do I specify the directory that I’m building from if I’m not working in that directory, as I might with packp3d’s -d parameter?

Between this and a related post by someone else on another forum, it really occurs to me that we could use some streamlining – or at least clarification – of our build system, especially the web version, if that’s intended to be the primary distribution method. There are manual pages, but they don’t seem to provide everything that seems important. While at least some of this might be found by examining the appropriate python files, that’s not terribly user friendly, especially for people just starting out on developing with Panda.

I think that it’s a very good idea that building be easy – something that you can do with a single command (and just that command) for a simple project, and some config settings and one or two commands for something of medium complexity, perhaps. As was pointed out to me, the easier it is to produce a build that will work on someone else’s computer, the more likely it is that the developer will do so early and often, and the more likely they are to get a lot of feedback, and early – something that can be invaluable to a project.

However, I realise that this calls for someone to actually do the relevant work. I’m no expert at the building of distributables, as we’ve seen of late, and have other projects besides – as I imagine is true of most on this forum. I don’t know what to suggest, and I don’t mean to bring anyone down (I’m truly sorry if I have), just to point out something that seems to me to be a problem.

I certainly agree that the whole p3d system could use some more thorough documentation. It’s extremely powerful and fairly complex; but it’s also one of the more recent additions to the manual, and as such has had less time for volunteers to refine it. If you’re interested in being one of the volunteers, we’d certainly appreciate the contributions. :slight_smile:

packp3d is basically a simplifying layer on top of ppackage. Anything you can do in packp3d has a direct equivalent in ppackage, but not necessarily the other way around. Thus, ppackage is both more powerful and more complex.

The keywords to “config” are the same keywords that you’d specify with the -c parameter to packp3d. Usually, you don’t need to specify any. I don’t know whether the full set that you can specify has been documented anywhere yet, but some of them are:
display_name - this is the name displayed by the p3d system while the package is downloading
version - this is the version string used by the p3d system
hidden - set to True to suppress the splash window and the default Panda window
platform_specific - set to False to prevent the automatic platform-dependent code from activating, so that platform-specific dll’s will not be included even if the p3d system thinks they should be, and the resulting p3d file will not have any platform-specific suffixes in the filename.
keep_user_env - set to True to make the user’s full runtime environment variables available to the p3d file. The default behavior is to suppress most of the environment variables except those that are actually necessary to run Panda, as a sort of security precaution for users

You do need to include “panda3d” in your require parameter, for at least the p3d file and anything else that contains panda3d code. packp3d does this automatically, but ppackage doesn’t. There might be cases where you don’t want to include panda3d, for instance if you are building an auxiliary textures package meant to be loaded by a variety of different modules.

You specify the root directory with dir(‘directoryName’). packp3d’s -d parameter corresponds to dir().

David

Ah, fair enough – that seems fairly straightforward.

Another question, if I may: what are the pdef equivalents to packp3d’s “-e” and “-n” parameters? (Those that allow for the inclusion of additional extensions.)

From what I’ve seen in packp3d.py and Packager.py, it looks as though I’m supposed to append my additional extensions to “binaryExtensions” (for compressible file types) and “uncompressibleExtensions” (for, well, uncompressible types) – but I’m not sure of how to do that from my pdef file: packp3d seems to create a Packager object, but I don’t see any suggestion that that’s valid in either panda3d.pdef or the manual, there doesn’t seem to be a “self” object for me to get a reference from, and I don’t see a relevant-looking “do_” method in Packager.py…

(These correspondences between packp3d parameters and ppackage methods are, I think, one of the more important things to get into the manual.)

Heh, that would seem to call for figuring out how to use it first! :stuck_out_tongue:

(I might at the least update the “pdef syntax” page with some of what I’ve learned once I do have this figured out, however.)

You can write Python code in your pdef file (the file itself is actually just read by the Python interpreter), and the variable packager is predefined, so you can extend binaryExtensions and uncompressibleExtensions with a line like this in the top of your pdef file:

packager.binaryExtensions.append('xcf')

David

Hmm… I seem to be doing something incorrectly, because it doesn’t seem to be working. In particular, I’m now seeing two problems:

First, and perhaps most alarmingly, I’m seeing this error:

Second, regarding the extensions, the expected files don’t seem to be ending up in the resultant .p3d. Oddly, I am seeing the cursor file that I want included, and the font file, but none of the others. I considered that perhaps those two were included by virtue of being in the root directory, but a quick test with a .lvl file (one of the extensions that I want to include) seems to reject that.

For reference, my pdef looks like this at the moment:
(I originally had the extension appends within the class declaration, but moved them outside of it in an attempt at solving the continued absence of the files that they’re intended to include.)

packager.binaryExtensions.append("lvl")
packager.binaryExtensions.append("map")
packager.uncompressibleExtensions.append("ttf")
packager.uncompressibleExtensions.append("mf")
packager.uncompressibleExtensions.append("cur")

class MoonP3D(p3d):
    require("morepy", "openal", "panda3d")
    
    dir("../MoonDemo/")
    
    config(display_name="To Light a Candle")
    
    setVer("0.1.0")
    
    file("hand.cur", extract = True)
    
    sign("candlecert.pem")
    
    mainModule("main")
    module("core.*")

Ah, I seem to have found the solution to the latter issue, at least: it seems that there’s a setup method that’s to be called after making such changes. Whether this does in fact work I’m not sure – I haven’t tested it yet.

(The former problem – the failure to import “core” – remains, I fear.)

Hmm, the “couldn’t import core” message is being displayed by ppackage, as it’s reading your pdef file? Maybe you need to ensure that Python can find core at that time, for instance with code like this at the top of pdef:

import sys
sys.path.append('../MoonDemo')

David

Hmm… I’ve discovered this thread, from 2011, in which rdb indicates that the error is normal – does that still hold?

(I’m afraid that my working Windows test computer – the other Windows test computer that I have available seems to have some problem with Panda programs in general, regarding which I might start a new thread soon :confused: – is off for the night. I’ll hopefully test on it in the new day and discover whether the game runs…)

Yes, the message about panda3d.core being missing is normal; and I don’t even see it any more (which is its own problem, I know). Sorry, I misunderstand your question; I’d thought you had your own module called “core” which it wasn’t finding.

But yes, there are plenty of frightening-sounding error messages generated at p3d creation time. The problem is that Python doesn’t make it easy for us to figure out which modules are actually needed at runtime and which aren’t (put the panda3d.core message is its own, separate little bug). Still, error messages aside, the key question is always whether the p3d file runs.

David

Ah, fair enough, and my apologies then. I’ll hopefully get back to you on that in the new day, then!

Well, the good news is that it does indeed run under Windows; the bad news is that I still don’t seem to be getting my cursor (in the web-build, at least; I haven’t tried an installer-build recently, I don’t think): specifically, I seem to be getting an error that reads: “:display:windisplay(warning): Could not find cursor filename hand.cur”. My pdef file does include the line “file(“hand.cur”, extract = True)”, I believe.

If you analyse the contents of the .p3d file using “multify -tvf somefile.p3d”, does it appear to list the hand.cur file?

Yup, it does seem to be there.

Is there a way to check that it is, in fact, extracting the cursor? If it is, given that it’s currently kept in the root of my project directory, should I be applying a directory offset of some sort when loading it (that is, should I be loading something like “Filename(’<some_dir>/<some_other_dir>/hand.cur’)” instead of just “Filename(‘hand.cur’)”?

In case it’s relevant, I’m loading the cursor in the init method of one of my primary classes, using the following:

        winprops=WindowProperties()
        winprops.setCursorFilename(Filename("hand.cur"))
        base.win.requestProperties(winprops)

Perhaps the directory it’s extracted to is not in the model-path for whatever reason?

Hum, on hindsight, the extract parameter isn’t supported for p3d files, since they don’t have an extract directory in the same sense that packages do. This has been a bit of a problem with other kinds of p3d features that would be nice to extract, like dll’s and the such.

Hm. Well, in the meantime, there exists a workaround: you have to put some or all of your application in a package, and then reference the package with a p3d file. I realize this is a terribly clumsy workaround if all you want to do is change the mouse cursor; my apologies.

David

I suppose the best solution here is to change winGraphicsWindow to load the cursor into a buffer via the VFS, and then call CreateBitmap instead of LoadImage.

Ah, I see – thank you.

I’ll confess that I am surprised: what have others done in previous projects? Surely this isn’t the first time that someone has wanted to load a cursor in a distributable build? Have they all used the package solution, or perhaps a software cursor?

Hmm… Looking at the Python reference, I take it that winGraphicsWindow is a C+±side class; thus I take it that I’m not in a position to add that to my own project without rebuilding the engine on my side. Ah well – I do hope that such a fix is included in a future release, in that case. :slight_smile:

This issue should be fixed now in the latest version of packp3d and pdeploy.