How to structure a game in general?

I’m wrestling with how to balance between bricks and code and parallel tasks.
For example, bricks are object-centric but game code doesn’t need to be. I feel like I have to make an empty called ‘main’ or something with an always sensor and put all my fired code on that. But then the code will either end, or not. If I want to fire a sound that loops forever I can’t use anything that loops in the code or that brick setup can’t fire again, or maybe it will?

I’d like a resource to study this more so I can architect my game. My project is not really object-driven as most of the graphics are from pre-rendered backgrounds (Worlds) although I do plan for water-effects and sprites and such.
Oh…and how much to dwell on the need to spawn threads, especially for timers.
Any suggestions for further reading? I suppose I can just download other games and get a feel but my point-n-click ‘engine’ probably won’t have many parallels since BGE is really meant to be a 3D environment.
thanks

There are timer properties, you can have a property sensor targeting a timer pretty easy.

I would have a “manager” object that loads collections and runs them / pauses them from the outside.

Also ensure “main.blend” is actually just a open game actuator on a empty pointing to your game.blend so it can retain its license and not inovke gpl.

it’s indeed an interesting subject and some deep though on it will push you naturally to think and rethink the architecture of your project.

Depends of lot of the game …

Start simple , and see what will must be the bare minimum to pulse your game like an heartbeat. If you want to script a camera, you gonna have to pulse it at least each time you move your mouse . If you want to setup some animations system, you gonna find some interest in the actuator sensor set on inverse. Some stuff like vertex shaders , no choice, it has to be execute each frame …

In other words, i would not recommend to dump all your code into a single script that is executed each frame (unless it’s some simple game board or something like that) . Ofc, you can have some Empty - God- named empty that will care about lot of stuff, but no need to create an empty for that , the camera or even the player can be the placeholder of such script.

To summary : i would say that you gonna need python to create complexity but you can use bricks to ensure that complexity goes along with simplicity. And yes, you can use python to parameter the bricks rather than using only python which is - on the paper - slower than bricks

At the end you don’t want to write a bible of python code , nor you want to build a wall of logic bricks

Thanks for your replies both of you!
@Blendraptor
The latter is about how I was thinking; I think there are several technical issues driving those thoughts:
-Does it makes sense that there will ever be a python script that doesn’t terminate?
-And if a script does exit, do those variables stay in scope ie a file handle I may want access somewhere else? (perhaps I can save a handle as property but I would have to do something awkward like flatten to a string)

@BluePrintRandom
As for the built-in timer, I can see it’s value since it basically acts like a thread that I don’t have to monitor. However, I couldn’t find anything I can do with a timer, it just takes off the moment it is invoked and no way to pause, change, or terminate. That puts the burden of everything on the code elsewhere. It’s basically a system clock.

ah!

then you could have a dictionary

#set
dict_rates[timer_rate] = rate
#run
for key in dict_timers:
     dict_timers[key] += dict_rates[timer_rate] = rate

(so we have the ability to adjust the rate and get the value)

A python script/module is never terminated , it always sleeps … unless… it’s waken up by one/many sensor(s) that pulse them (positively or negatively) . So yeah better not wake up a script/module each logic tic if that script has nothing to do particular at that time. The best thing to do is to associate a specific task accomplished by a module and identify strictly at which moments in has to be call - and for that choose the good sensor(s) . So basically the worst, is to execute a huge single script and pulse it with an always sensor set with the spamming option on so it executed all the time. Unfortunately a very common bad habit.

the global dictionary is usually used to store permanently all variables . In python , example

### init ##

dct = bge.logic.globalDict
dct['pos'] = Vector(plr.worldPosition)
dct['dlt'] = Vector([0.0,0.0,0.0])
dct['loc'] = [0.0,0.0,0.0]
dct['spd'] = 0

EDIT :
check that actuator brick … it does nothing else than read/write the global dict in a external default file " .bgeconf" you will find next to blender.exe . So you gonna have to - only once - create yourself a global dictionary with python like shown above and save it with that save brick (with that, your .bgeconf file will exists) . After that, in your final game, you gonna be able to import the saved dictionary with the load brick - update its values with python - and save the updated with the save brick

image

The stupid thing is that you can read/save also with python and you gonna need python to update values anyway . … so…

bge.logic.saveGlobalDict() # save globalDict externally
bge.logic.loadGlobalDict() # replace the current globalDict with the saved one

yes str() a numerical value will require to use python too . But do you really have to use strings ? Use integers and use them like index for any dictionary

On the other hand, a cool method I use, is to assign value to a property from a dictionary i created on the fly

player['status'] = {True: "no value found" , plr['hp'] >= 50: "feel ok" , plr['hp'] >= 20: "suffering", plr['hp'] >= -100 : "game over", }[True]

Player status “value” will be the last one which KEY will be evaluated as being equal to True (ofc, you can add more conditions beside plr[‘hp’] … somehow write a if, elif , … , elif , else statement in a single line (but priority is reverse : last value has the last word)

1 Like

ok, some really good info, thanks!

re: the above. To be clear, in one pass of the script I set a variable that is in scope of anything else in that script (not associated with an object). After more ticks it gets called again; can I expect that variable to still exist with the new value? Sure I can force a save somewhere like an object property or the global dictionary but it would be nice if the variable itself and it’s value were preserved between ticks.
One example of this is I added some custom methods to a KX object but when I returned to that object after some ticks those custom methods were gone. I probably needed to create a subclass and associate THAT with a blender object but I’m still learning to navigate the complexities of object-oriented coding.

I do look forward to using the global dictionary for game saves and settings but did see it as useful or intended for tracking values changed in-game (that are NOT preserved between games).

yes, make the test . The global dictionary is meant to be your game “hard drive”

Yes, class and methods have to be defined once at start , … and so, like python libraries, stuff you have created at start ( in a “init script”) have to be imported in “exec scripts”… because otherwise, these will not understand what you talking about … just like “Vector” means nothing for your basic script if you don’t import it prior to its use.

yes, you can store whatever you want in it

use print() … you have to understand what’s happening behind. In my project, i store some debug values along the script and then i print() everything in a single list at the end … perfect to track things in the console : 1 line = 1 script executed

i recommend you to not bother with classes, methods, instantiations and all the OO stuff in your debuts … just use python to create python modules you gonna assign for some controlers . Parameters, functions , actuators parametering … that would be a good start and well enough if your logic brick system is well set.

I mean, you will have already far enough work understanding how things work before you try to add complexity to a game that gonna be very basic to starting with. Once you have total control on your project, take a step back and see if you really need to induce OO.

But well, it’s up to you ofc, if you are more interested to make code for the sake/fun of coding … but in my personal experience, architecture and logics is the base of everything … This made me remind what the creator of Excel said in a documentary : coding <> programming