I want to run a python script, once at the start of a game in the BGE. I tried various sensors, but they all sent more then one pulse/contentious stream. I only wan't to run my script once, right at the beginning, and then be done with it for good. How can I do this?
Often times to control parts of the game that are kinda background or sidework, we add empties. Invisible empties can be used for playing sounds, loading levels, spawning bad-guys, or running pythn scripts.
Create an empty that will run your script if it doesn't need to be on a specific object (a jeep for example ;) add an always sensor to it, and then connect it to a python controller, set the controller to run your script, then enable the little marker next to the name of the controller, setting it to be a startup script. the symbol will change from this:
And your final setup will look like this:
Check the following image. I use a property named "run_once". The script runs as long as the property is 0 and prints "potato" and the LogicTicRate. Also I have an actuator that sets the "run_once" property to 1 when the script runs for the first time, so it would never run again. I don't know if that is practical but I just thought of it.
Also you might notice that it prints "potato" 2 times. This happens cause of the logic tic rate, meaning the times per second the logic brick sensors are being executed. You can change this time with the command I put in comment in line 4. I haven't played with it, but I'll have too soon enough. You might not have a problem with it, but if you do check this (set logic tic rate)
The way how and when scripts are executed is a bit confusing at the beginning. Sensors send singnals when they change their states.
For example if you have an collision sensor which is attached to a script. than this script will be executed twice when the sensor detects a collision. once when it changes from false to True and again when it changes from True to False. But if you just use an always sensor (without tigger mode) than the script schould be executed only once, at the first frame because the sensor will never change again (always True).
Another methed is to write an init function inside of your script.
own = bge.logic.getCurrentController.owner
if not "anyPropertyWhichDoesntExistInThisObject" in own:
own["anyPropertyWhichDoesntExistInThisObject"] = True
#here you now can write your initialisation code which wont be executed again
If you want to make sure you execute code exactly once in a game session I suggest to use a Python module. A Python module acts as singleton (which means there exist only one instance at the time). It also survives any scene changes. You can take advantage of the fact that module level code is executed exactly once, at module load time. Modules gets loaded with the fist access to them (via call or via import)
This should work unless you unload/reload the module - which is very unlikely.
def initialize(): 'call runOnceDemo.initialize from your Python controller' pass print("This code runs exactly once")
Always -> Python controller Module: runOnceDemo.initialize
Always -> Python controller Script: runOnceScript
print("This code runs exactly once")
I hope it helps