How does the Max Playbacks event work in a multiplayer game? I set it to 1, but still hear the event when it’s triggered by another player. Is there a way to flag certain events to only be heard by the player who triggers them?
- JHedges asked 10 years ago
Yes, but you have to do it in the code that calls Event::start(). There’s no FMOD feature that will do that for you. In our game we have the notion of the "local player" (i.e. the player controlled by a given client machine) and some sounds are only played if they were generated by the local player.
You can also add, as a general feature of your sound system, code that checks to see if a short one-shot sound has a chance of being audible before playing it. Long or looping sounds can follow a similar pattern, but are more involved.
One more question: Are 2D sounds supposed to only be heard by the "local" player? I’ve got a bunch of powerup and UI sounds set to 2D, and I’m hearing some (but not all) of them when another player uses them. I can’t see any difference in how I set them up.
- JHedges answered 10 years ago
Yep. "Local player" is a title specific idea, not anything to do directly with FMOD and is totally orthogonal to 2D vs 3D.
In our game, some 2D sounds are local player only (like interior monologue) while others are for all players (like the announcer informing everyone that only 5 minutes remain in the current round).
What if you set a custom rolloff for the events with a very very short distance? That way you can make the sound only heard by the single player who it is for. This would make the sound silent for other players, but would not take the sound out of memory for those players who are not supposed to hear it. Maybe setting the rolloff to be silent after .1 meters. Usually players can not get closer than that to another player. I have never tried this in practice but it seems like it should work.
That would be a way of implemeting player specific sounds, though it’s something of a hack and, as such, has a couple of drawbacks.
First off, all players are paying some cost for playing that sound even though they really don’t need to. In a simple game, that’s problably not a problem, but it would scale poorly if you had lots of local player sounds.
Another issue is that 3D sounds assume spatialization. If you play a sound right on top of the microphone, you’ll get artifacts due to FP precision issues. So, you probably want to play it in front of the microphone, but then you still don’t necessarily have great control over which speakers the sound is coming out of.
Also, you mention something about the sound not going out of memory. I’m not exactly sure what you mean by that. Do you mean the sample data associated with that sound or is there a reason you need that sound instance (Channel/Event) active on all clients?
Yeah, I understand that it may have a slight cost to players who don’t need to hear the sounds. My thought though was that most of these UI/HUD sounds are going to be used by every player anyways, because all players generally have the same UI/HUD. So if you were to set the max playbacks to 1 it would only load one instance of the sound definition into memory for all players. Correct? This wouldn’t really be a draw back because all of the players need the UI/HUD sounds loaded into memory while playing anyways. If I am missing something let me know, because this is how I am planning on setting up the UI/HUD sounds for the game I am currently working on.
Yeah I know what you mean by playing "right on top of the microphone". What I would do to solve this is put a 3D pan level effect on the UI/HUD events so that when they are let’s say within .2 meters they are panned to 2D, which is what I would want anyways. This would keep the sounds in a predictable place and remove the possibility for weird spacialization. Also with the event having a custom roll off where no sound is heard outside of .1 or .2 meters the other players will not ever hear it. I would also set the Max Playbacks Behavior for the event to "steal quietest" that way the UI sound for the player will always hear their UI sound.
What I meant by not taking the sample data out of memory for the other players is that players who would not need to hear the sounds would still have to have the data in memory, even though they would never be able to hear the sound. But I then realized all players will have the same UI sounds so it doesn’t matter if they have the sample data in memory, because they will need the UI sounds for their own UI/HUD.
If you have any comments on faults / downfalls of this method or suggestions on how to make this better let me know. I would greatly appreciate it. Thanks!
In short, yes, the solution you talk about can be made to work, but it seems like a lot of unnecessary drama stemming from the desire to have each HUD instantiated on all clients, something I would generally consider to be a bad design. In more detail…
I’ve always seen HUDs done as client side only objects. No other player can possibly see or hear them. Furthermore, good encapsulation and network security mean that you usually want the UI to talk to the game through some sort of abstraction layer like dispatching script commands instead of poking game systems directly. So don’t even instantiate one player’s HUD on another player’s machine. From there, it’s trivial to have your UI/HUD sounds in 2D, only audible by a single player.
I also think you are unnecessarily conflating loading sound data with playing sounds. True, FMOD will load data if it needs it to play a sound, but really that’s just a distraction. Especially for stuff like UI sounds, you basically want to have each player load the UI EventGroup at the start of the game, play sounds to their heart’s content, and then unload the UI group at the end of the game.
Please login first to submit.