Using play-sound in Spring

Using play-sound in Spring

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

Post Reply
Gnomre
Imperial Winter Developer
Posts: 1754
Joined: 06 Feb 2005, 13:42

Using play-sound in Spring

Post by Gnomre »

As we all know, Spring has supported the "play-sound" command in scripts since 0.63b1:

-Added support for loading TA:K COB files and implemented the TA:K-specific opcode play-sound.

This allows a unitmaker to play any sound he wants (a wav file in the /sounds/ directory) at any volume at any point in the script. This is useful, since now we can do things such as running engine sounds while units move, foot step noises, or anything else of that nature.

Getting it to work isn't as simple as that makes it appear, though. After bothering Fnordia for a while, we finally got it working nicely.

Since I use scriptor, that's all this little guide is written for. I don't think any other compilers would be up to this task anyway. First of all, you must be compiling in TA:K mode. You can either click the little green TAK button in the scriptor GUI or you can put the following line at the beginning of your script:

#define TAK

Secondly, you cannot use the stock SmokeUnit.h file. If your unit uses SmokeUnit and you want it to play sounds, you can't right off the bat. This is because TAK handled smoking units differently than TA, mainly with a different function, but the point is if you try to compile with the original SmokeUnit you will crash scriptor.

So, to rectify this, I've made a hacked up Spring-sound-ready Smokeunit.h. It's available for download by clicking here. Simply put this .h file in your Includes directory, and then change the line:

#include "smokeunit.h"

in any scripts you want to play sounds in with:

#include "springsmoke.h"

And everything will compile and work just fine (barring other errors on your part, of course). You don't have to make this change for units that don't use play-sound.

Then, to use play-sound, you just type in the following line:

play-sound("filename", 1);

where filename is the filename of the .wav file in the /sounds/ directory to play, and 1 is the volume. There is no limit to volume afaik. For reference, I had to use a volume value of 10 for the Raven's explosion sound to make it about the same volume as it is normally in game. There's no limit to what functions it can be played in, as far as I know, but I'm sure putting a play-sound in a repeating loop without a sleep wouldn't be a good thing.
User avatar
GrOuNd_ZeRo
Posts: 1370
Joined: 30 Apr 2005, 01:10

Post by GrOuNd_ZeRo »

That'd be sweet for tanks and planes! that's real cool Gnome!
User avatar
Tim Blokdijk
Posts: 1242
Joined: 29 May 2005, 11:18

Post by Tim Blokdijk »

Put it in the wiki?
Gnomre
Imperial Winter Developer
Posts: 1754
Joined: 06 Feb 2005, 13:42

Post by Gnomre »

Just a random update to this:

After further experimenting, putting play-sound in StartMoving() does not loop, at least not without doing while( TRUE ), and last time I tried that in Spring it froze up (I imagine because it's an infinite loop). It will only play the sound in StartMoving() once, UNLESS (this is the important part!) the unit is in first person control! If the unit is being manually controlled, StartMoving() is apparently continuously called. I call this the Zwzsg Effect, in honor of zwzsg's battle with the constantly-being-called AimPrimary() function.

Anyway, what this means is that with some crafty scripting, you could probably make engine noises (such as a running engine) when a unit is in first person control. Ok, the scripting isn't all that crafty. It'd be along these lines:

Code: Select all

StartMoving() {
	if( TRUE ) {
		play-sound("filename", 5);
		sleep X;
	}
}
Where X is the length of the sound in milliseconds. This is necessary because otherwise the game just continuously starts the sound without waiting to start it again. Also note my volume in that example--sounds in first person are far louder than normal. You should take into consideration the fact that the sound will be played one time every time the unit is issued an order which results in moving in third person as well. Finally, remember that this little first-person engine sound hack is purely conjecture on my part, I haven't actually tested it yet but from what I have done with StartMoving() and play-sound it should work.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Actually, the battle was short, as soon as I figured out that my problems came from AimPrimary being constantly re-called, I "protected" all the aiming script of my Spring unit from then on.

Your script workaround doesn't seem right to me. I know Cavedog's script use if( TRUE ) alot, but still TRUE being always true not matter what, a if(TRUE) {...} is the same as not having any if, right?

What I'd advise to use would be more:

Code: Select all

static-var DoingTheMovingSound;

Create()
	{
	DoingTheMovingSound=FALSE;// Don't forget the initialisation!
	....
	....
	}


StartMoving()
	{
	if(DoingTheMovingSound)
		{return;}
	DoingTheMovingSound=TRUE;
	play-sound("filename", 5);
	sleep X;
	DoingTheMovingSound=FALSE;
	}
Gnomre
Imperial Winter Developer
Posts: 1754
Joined: 06 Feb 2005, 13:42

Post by Gnomre »

It only calls StartMoving() once during normal operation, and exactly a bazillion times per second in first person view. Your way would possibly work better, like I said, I haven't tried it yet myself.
Archangel of Death
Posts: 854
Joined: 28 Jan 2005, 18:15

Post by Archangel of Death »

Ok, I can understand why it has to keep calling Startmoving. Now I also understand why all these new units seem to use this MotionControl() function, and how to make stuff walk right when being controlled.

Wouldn't it be nice if we could detect when a unit was being piloted? *hint hint :wink: *
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

Post by yuritch »

Wouldn't something like this work better?

Code: Select all

static-var isMoving;

SoundControl()
{
	while(TRUE)
	{
		if(isMoving)
		{
			play-sound("engine", 2);
		}
		//Adjust according to sound length
		sleep 200;
	}
}

Create()
{
	isMoving = FALSE;
	start-script SoundControl();
	...
}

StartMoving()
{
	play-sound("engine_start", 2);
	//wait till it's played completely
	sleep 200;
	isMoving = TRUE;

	...
}

StopMoving()
{
	isMoving = FALSE;
	//wait till engine sound stops
	sleep 200;
	play-sound("engine_stop", 2);
	...
}
This should make engine sound while the unit is moving, with special start and stop sounds (which will play every time the unit is issued new order, even if it didn't stop, might need tweaking to work around that).
Post Reply

Return to “Game Development”