Page 1 of 1

Multiplayer issue: playing sound at player's position

Posted: Sun Dec 02, 2018 10:36 am
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.

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

Posted: Sun Dec 02, 2018 11:03 am
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.

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

Posted: Sun Dec 02, 2018 11:06 am
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.