4
$\begingroup$

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?

$\endgroup$
6
$\begingroup$

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:

enter image description here

to this:

enter image description here

And your final setup will look like this:

enter image description here

$\endgroup$
  • $\begingroup$ That will run it multiple times $\endgroup$ – GiantCowFilms Jul 13 '15 at 16:34
  • $\begingroup$ Go ahead and try. $\endgroup$ – Scalia Jul 13 '15 at 16:35
  • $\begingroup$ Unless TLT is enabled, the always actuator activates once. $\endgroup$ – Scalia Jul 13 '15 at 16:36
  • $\begingroup$ It appears to still be double executing it, but this actually works O.o $\endgroup$ – GiantCowFilms Jul 13 '15 at 16:42
  • $\begingroup$ This solution is right ... if you start with a single scene and this logic is applied to an object, that does not get added again. The scene should not be started again in your game session. $\endgroup$ – Monster Jul 14 '15 at 8:55
1
$\begingroup$

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)

Screen

$\endgroup$
  • $\begingroup$ Somehow it is still not working :/ $\endgroup$ – GiantCowFilms Jul 12 '15 at 14:57
  • $\begingroup$ Does it perform what I said above or is there an error? $\endgroup$ – Lev Jul 12 '15 at 16:42
  • $\begingroup$ It changes the property, but continues to run the script $\endgroup$ – GiantCowFilms Jul 12 '15 at 17:22
  • $\begingroup$ Activate "Tap" in the property sensor and let me know. How did you know it kept running? How many times did it print "potato" in the system console? $\endgroup$ – Lev Jul 12 '15 at 19:44
  • $\begingroup$ it seems to be fixed after I saved the file (odd) however, it is still making to copies, and the refresh rate needs to remain at 60 fps $\endgroup$ – GiantCowFilms Jul 12 '15 at 20:02
0
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Yes, the question was asking how to only send one signal, rather then having to perform the check in python. It's more efficient using logic bricks $\endgroup$ – GiantCowFilms Jul 12 '15 at 22:44
  • $\begingroup$ so does the method with the always sensor work for you ? $\endgroup$ – Toger Jul 13 '15 at 11:07
0
$\begingroup$

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.


Module Mode

runOnceDemo.py

def initialize():
    'call runOnceDemo.initialize from your Python controller'
    pass 

print("This code runs exactly once")

Always -> Python controller Module: runOnceDemo.initialize


Script Mode

runOnceScript.py

import runOnceDemo

Always -> Python controller Script: runOnceScript

runOnceDemo.py

print("This code runs exactly once")

I hope it helps

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.