Thoughts on 'Extending' the BGE API

Howdy guys,

At the moment I’m concentrating on building frameworks:

  • Lighting (Done)
  • Scheduling (Done)
  • Threading (Done except for killing the darn things)
    And currently: Mist

I’d like to discuss what I call ‘Extending the BGE API’

You see, these things have no inherent object. It doesn’t make sense to assign their controls to an object. It also barely makes sense to put entries in the globalDict as, well, they’re part of the ‘Engine.’

So what I’ve done is to extend the API by adding things like:
bge.logic.schedular
bge.render.lighting

They can be imported from any script (eg. import bge; bge.render.lighting.setMaxShadows()) and are thus rather convenient to use. They are also simple to set up as you can just go:


import bge

def myFunct(parems):
    ...

bge.logic.myExtension = myFunct

Or you can put classes in there, or whatever you like.

So here’s the question:
Is this good practice? Are there any downsides to this approach?

globalDict is a puzzle wrapped in a mystery, why one would use is instead of a custom module is beyond my comprehension. +1 for not putting stuff in there.
I miss the purpose of the simple setup. Is that something that I need to write before to use the framework or something else?

Aesthetically, it’s quite fun to add new features to the bge namespace, but in practical terms I don’t think that it is sensible:

  • To use the new features, they must first be added to the bge module’s namespace, which requires an initialization step. Any modules which attempt to use these features before this initialization occurs will experience ImportErrors. Hence, you would need to include a loading scene which modified the namespace before running any logic that might use it.
  • The documentation for bge modules is standardised and regularly updated. If anyone else decided to use this concept, or even your own code and find documentation, it would be confusing that certain features were not mentioned in the official docs.

why not get them trunked?

they don’t seem like they can break anything,

I would use all of them.

  1. Put the initialization code at module level. If any code imports the module, it’ll run the initialization code. Not ideal, but it works OK.


---MyInitializations.py---

import bge

class MyVersionOfLights:

    pass

bge.lights = MyVersionOfLights()

---Elsewhere.py---

import MyInitializations

import bge



bge.lights.whatever()


You could also just have your own module setup (i.e. mymodule.lights) it’s only a slight difference.

  1. Eh, that’s a reason, for sure, but most people aren’t going to see personal project code.

what about a ‘splash’ file that mentions the extensions with a ‘on/off flag’ ?

Doing so defeats the purpose of placing it in the BGE namespace. Whilst it is related, perhaps, it’s not BGE-code, it’s user code, and you’re already defining setup code, and require it anywhere you’re using it. Better to be explicit, and avoid the confusion / unnecessary cluttering. I’ve done this before, these days I think it’s less of a good idea.

I agree with agoose77.

I tried a similar thing before to get a sort of extended bge.

The point is,

  • it is not part of the BGE API (even if it is useful)
  • you need to import it anyway so why not clearly state where it comes from
  • there is no real benefit to have it in the bge name space

Therefore I dropped this kind of design. It was an interesting but not really useful concept.
It might be different if you can manage to get some “installation” (e.g. dropping some .py files into a Python folder) without the need to “initialize” each single using Python code.

Most people end up using:

rend = bge.render

rend.setMousePosition( x, y)

So it really doesn’t matter where your code is imported from.

They will just use:

lights = bge.render.lighting

my_lights = lights.getLights()

Instead of:

import myLightingModule as lights

my_lights = lights.getLights()

Also, if I download a project hoping to help someone who is having trouble with it, or if I want to copy someone’s really nice lighting setup, and I look in the script and find:

my_lights = bge.render.lighting.getLights()

Or some variant of the above like:

my_lights = L.getLights()

I’m going to look in the BGE API and be confused when I can’t find that function.

I already have trouble when Blender sometimes changes names in the API over time so that old files don’t usually work without some rewriting and hunting through the API guide. Last week I was looking for calc_edge_angle() in Bmesh and found that it had been changed to calc_vert_angle() in a recent release. I couldn’t work out why this script that was only a few months old wasn’t working, it was because I was looking for the wrong function.

time ago i had putted something in bge.stuff
to have a “pseudo” easy access, but really is not so . as say Agoose

better use a module(or pakage ) at the root of blender.

with implicit initialization if need

############
#game.py

from .lights import Lights

lights = Lights() #initialized
############

import game

game.lights.off()

this keep the easy access, but is clearly a custom code

Those are some very valid points made. You have convinced me. I’ll go back to modules, the modular way…