Multiplayer issue: playing sound at player's position

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Multiplayer issue: playing sound at player's position

Post by Player701 »

The problem: I have a weapon that can be turned on and off, and when it's turned on, it loops a sound. The weapon is supposed to retain its state when it is dropped, so if the weapon was turned on, the sound should continue playing. The current logic makes inventory items stop all sounds when they are moved in or out of inventory, so I'm using an auxiliary "sound source" actor to loop the sound. When the weapon is in the owner's inventory, the sound source is attached to the owner, and when the weapon is dropped, the sound source is re-attached to the weapon. Here is a stripped-down testable example of what the code for this actor looks like:

Code: Select all

class SoundSource : Actor
{
	Default
	{
		+NOINTERACTION;
	}
	
	override void BeginPlay()
	{
		Super.BeginPlay();
		target = players[0].mo;
		A_PlaySound("weapons/sawidle", CHAN_WEAPON, looping: true);
	}
	
	override void Tick()
	{
		if (target)
		{
			SetOrigin(target.pos, false);
		}
		else
		{
			Destroy();
		}
	}
}
When summoned, this actor attaches itself to the first player and constantly loops the sound "weapons/sawidle". In single player it works perfectly, and it is impossible to tell that the sound isn't coming from the player itself. However, in multiplayer this setup breaks. Depending on whether the player is standing still, moving or turning around, the perceived position of the sound's source is constantly changing: the sound is heard either only in the left or only in the right speaker, and its volume also appears to be non-constant. It's as if the sound source actor cannot catch up with the player's position for some reason (even though the effect of SetOrigin with the second argument set to false should be instantaneous, shouldn't it?).

I thought it could be an issue related to network lag, but I've tested it in a multiplayer setup where two GZDoom instances running on the local machine are connected to each other, and the problem still persists. Maybe I'm missing something in my actor definition or I should also do something else besides calling SetOrigin when repositioning the actor? Though it does look more like a bug to me because the behavior is not consistent between singleplayer and multiplayer modes.
Attachments
zscript.txt
(364 Bytes) Downloaded 16 times
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49226
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Multiplayer issue: playing sound at player's position

Post by Graf Zahl »

This is most likely caused by movement prediction. I can't tell for sure because it's not the kind of code I am too familiar with. The entire setup you made here is rather volatile and as you experienced, may not work like you might expect.

To be honest, I think the best you can do is to stop the sound on the player when the item is dropped and start a new one on the dropped item. It may cause a short interruption but it's probably the only real option.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Multiplayer issue: playing sound at player's position

Post by Player701 »

Graf Zahl wrote:To be honest, I think the best you can do is to stop the sound on the player when the item is dropped and start a new one on the dropped item. It may cause a short interruption but it's probably the only real option.
Yes, this is an option, but the interruption is exactly what I'm trying to avoid here. If only it were possible to change the source of an already playing sound...

Update: Here is the solution I've implemented to address this issue. It is based on Graf's proposal, but only as a fallback in multiplayer mode. In single player, the SoundSource actor is used to play the weapon's sounds, and in multiplayer, SoundSource is used to route the playback to either the player or the weapon itself depending on whether the weapon is on the ground. The actor also monitors its target (i.e. what it is currently attached to), and when it changes, the playback is restarted automatically. Thus, there is no period of silence, and the only drawback is that a looping sound has to be restarted from the beginning. This is also not perfect, but at least it's much better than the effects caused by movement prediction.

The code (with many descriptive comments) will be available once the mod is released.
Post Reply

Return to “Scripting”