Important! Please read the announcement at http://myst.dustbird.net/uru-account.htm
Also! Please read the retirement announcement at http://myst.dustbird.net/uru-retirement.htm

Random Sounds

From UamWiki

This tutorial is for adding Random sounds in your Age.

By random sounds we mean sounds like: the bahro screams you heard in the city. Bird song, like I put in Eder Bahvanin. Thunder in Myst from Myst V.

This tutorial assumes that you already know how to put in normal sound emitters in your Age.


Put In The Emitter

In my RAD Age, Eder Bahvahnin, I have 9 sound emitters for the random bird song that you hear in it. None of the emitters are 3D sounds, so where I put them was no big deal. I could have put them all in a row next to each other on one side of the Age if I had wanted to. What I did was spread them around. That has no affect on where you hear the sounds or how loud they are.

However, you might be putting in a sound that while random, does need a directional source. Let's say it's a broken piece of machinery. You want a random sound to happen while the machine runs. In that case where you put it, and some of your 3d flags will be important.

The other thing you need to consider is: how many different sounds will the random sound be? Here's why you need to think about that: your sound emitter can only play one sound. One sound emitter can NOT play a multitude of different sounds. So if you have 5 different random sounds, you will need 5 different emitters. One for each sound!

I had 9 different bird songs, so that's why I had to put in 9 different emitters.

For this tutorial, I'm going to talk about just 1 emitter, but realize that if you have more than one sound, you'll need to put in more than just that one emitter and do the same thing for each.


The ALCScripting

Okay, now that you've set up your sound emitter, and gotten your sounds set up. Here is the ALCscript you'll need to put in:

RndBirdEmt:
   type: soundemit
   sound:
      flags:
        - localonly
      file: bahvforestbird01
      volume: 0.5
      type: SoundFX
   logic:
      modifiers:
        - tag: RandResp
         actions:
           - type: pythonfile
            ref: $Pyth_Random
      actions:
        - type: pythonfile
         ref: Pyth_Random
         pythonfile:
            file: BahvahninBirds
            parameters:
              - type: responder
                ref: $Resp_Random
              - type: string
               value: RndBirdEmt
              - type: int
               value: 1
              - type: float
               value: 20
              - type: int
               value: 20
              - type: sceneobject
               ref: scnobj:RndBirdEmt
        - type: responder
         tag: Resp_Random
         responder:
            states:
              - cmds:
                 - type: soundmsg
                  params:
                     receivers:
                       - 0011:RndBirdEmt
                     cmds:
                       - play
                       - setvolume
                     volume: 0.5
                  waiton: -1
               nextstate: 0
               waittocmd: 0
            curstate: 0
            flags:
              - detecttrigger

Okay, I can hear you all now: "OMG!! WHAT IS ALL THAT????"

Let's break it down:

Here is just the emitter part:

RndBirdEmt:
   type: soundemit
   sound:
      flags:
        - localonly
      file: bahvforestbird01
      volume: 0.5
      type: SoundFX

Okay, now the next part is the logic. We are making the emitter into a random responder that is controlled by a python file. we are also setting up the values for the randomness:

   logic:
      modifiers:
        - tag: RandResp
         actions:
           - type: pythonfile
            ref: $Pyth_Random
      actions:
        - type: pythonfile
         ref: Pyth_Random
         pythonfile:
            file: BahvahninBirds
            parameters:
              - type: responder
                ref: $Resp_Random
              - type: string
               value: RndBirdEmt
              - type: int
               value: 1
              - type: float
               value: 20
              - type: int
               value: 20
              - type: sceneobject
               ref: scnobj:RndBirdEmt

Now let me explain some things here: First, yes, you'll need a python file, but you'll only need one for all the emitters. Thank D'Lanor as it's something he came up with, and works great! I'll list the Python file here towards the end, and what you need to do with it.

Next, you need to look at something:

			pythonfile:
				file: BahvahninBirds
				parameters:
				  - type: responder
				    ref: $Resp_Random
				  - type: string
					value: RndBirdEmt
				  - type: int
					value: 1
				  - type: float
					value: 20
				  - type: int
					value: 20
				  - type: sceneobject
					ref: scnobj:RndBirdEmt

The name of the python file is "BahvahninBirds" but of course, you'll be naming the python file what ever YOU want to call it. The string value, RndBirdEmt is the name of my emitter. Please note if you are doing more than one emitter as you have more than one sound, you'll need to change this to the name of that emitter you have. Okay, now we have 3 other values here: "int", "float", and another "int" the FIRST "int" value is set to 1. Now if you have another emitter, in the ALCScript for the 2nd emitter, you'd change this to 2. The 3rd emitter, it would be 3. Do you see what I'm saying? If you are adding this ALCScripting to other emitters, you need to append that number for each one increasing it by 1 each time.

The "Float" value is the number of seconds between playing the sound. This is in seconds. I have mine set to 20 on my first emitter. For best results, if you have more than one emitter, you need to vary this number, depending on how long an interval you want. In other words, this emitter will "roll the dice" so to speak, and see if it can play a sound. If it can, it will, but then it has to wait 20 seconds before it can roll the dice again.

The last "int" value: this number is your chance at sound. It's a percentage, and 20 is about as high as you want to go. Any higher and the chances of the sound being played are too good, and your random sounds will seem to play a lot more often.

Okay, the last part is the scripting to play the sound:

        - type: responder
         tag: Resp_Random
         responder:
            states:
              - cmds:
                 - type: soundmsg
                  params:
                     receivers:
                       - 0011:RndBirdEmt
                     cmds:
                       - play
                       - setvolume
                     volume: 0.5
                  waiton: -1
               nextstate: 0
               waittocmd: 0
            curstate: 0
            flags:
              - detecttrigger


Here you would need to append where it says "RndBirdEmit" for each emitter you are playing your sound.

Okay, so here's the script again, only I've changed it to indicate where you need to put in stuff:


Okay, now you need to do this to ALL your Random Sound Emitters.


Now For Python!!

Okay, now for the Python file....

Oh quit yer whining!!!! Not everything should be all ALCScripting. If done right, Both ALCScript and Python work very well together, and can be very powerful tools to make your Age work right!

First, if you have not done so already, you need to create a python file for your Age that has your Age name in it. If you have any kind of responders for you Age, you'll need this.

If you don't know what I'm talking about, you'll need to go back to Age Building 101.

Here is an example of my "dummy" Age Python File.

from Plasma import *
from PlasmaTypes import *
from PlasmaNetConstants import *
from xPsnlVaultSDL import *
class Bahvahnin(ptResponder,):
    __module__ = __name__

    def __init__(self):
        ptResponder.__init__(self)
        self.id = 10235001
        self.version = 1



    def OnFirstUpdate(self):
        pass


    def OnServerInitComplete(self):
        pass


    def OnNotify(self, state, id, events):
        pass


    def OnSDLNotify(self, VARname, SDLname, playerID, tag):
        pass

#Put In Glue Here

Okay, you need to change the class to your Age name, and change the self.id number.

Next, here is the python file for the random sounds:

from Plasma import *
from PlasmaTypes import *
import xRandom
respSound = ptAttribResponder(1, 'Sound responder')
strObj = ptAttribString(2, 'Object String')
intID = ptAttribInt(3, 'Timer ID')
floatTime = ptAttribFloat(4, 'Timer interval')
intChance = ptAttribInt(5, 'Chance value')
testObj = ptAttribSceneobject(6, 'Owner test object')
class BahvahninBirds(ptModifier,):
    __module__ = __name__

    def __init__(self):
        ptModifier.__init__(self)
        self.version = '1'
        print ('__init__%s v.%s' % (self.__class__.__name__,
         self.version,))



    def OnFirstUpdate(self):
        print ('%s: OnFirstUpdate: Getting local avatar' % self.__class__.__name__)
        self.LocalAvatar = PtGetLocalAvatar()



    def OnServerInitComplete(self):
        print ('%s: OnServerInitComplete: Starting timer %d with interval %d for %s' % (self.__class__.__name__,
         intID.value,
         floatTime.value,
         strObj.value,))
        PtAtTimeCallback(self.key, floatTime.value, intID.value)



    def BeginAgeUnLoad(self, avatar):
        if (avatar == self.LocalAvatar):
            print ('%s: BeginAgeUnLoad: Leave your timer at the door' % self.__class__.__name__)
            PtClearTimerCallbacks(self.key)



    def OnTimer(self, id):
        print ('%s: OnTimer: id = %d' % (self.__class__.__name__,
         id,))
        if (id == intID.value):
            cur_chance = xRandom.randint(0, 100)
            print (' - Chance value = %d, Local chance roll = %d' % (intChance.value,
             cur_chance,))
            if (cur_chance <= intChance.value):
                if (type(testObj) != type(None)):
                    if testObj.sceneobject.isLocallyOwned():
                        print (' - I am game owner. Running sound from %s' % strObj.value)
                        respSound.run(self.key)
                else:
                    print (' - Unknown game owner, running sound locally from %s' % strObj.value)
                    respSound.run(self.key, netPropagate=0)
            PtAtTimeCallback(self.key, floatTime.value, intID.value)

# put in glue here

Okay, the neat thing here is, all you need to change is at the top where the class is. I have it named BahvahninBirds, and that's the name of the python file. Change this to what ever you want to call this file (just make sure it matches what you put in your ALCScripting you did!!!).

That's it! All of you need to give D'Lanor a BIG pat on the back for this! This one file will make ALL of your random emitters work, and you only need one python file, AND all you need to change in the python file is ONE NAME!!!

How cool is that???

Okay, now save the python file, put it with your other python file into a pak file. Export your Age, link in and enjoy your random sounds.


Return To: Andy's Blender Tutorials