15 Mar, 2011, KaVir wrote in the 1st comment:
Votes: 0
Last night I ironed out the last known bug in my snippet, now I just need to flesh out the MSDP variables it ships with, and finish the documentation.

The snippet also includes my psuedo-ATCP alternative, primarily for the benefit of Mudlet. However Mudlet doesn't negotiate MSP either - the workaround I used in my own mud was to send an MSDP "SOUND" variable, which Mudlet would intercept as an ATCP event, and play with a simple Lua statement.

This brought to mind the various problems I've had with MSP, such as:

* Numerous checks throughout the code to make sure players can't send each other !!SOUND() triggers. This feels like a really hacky solution, it can cause problems if you miss one, and future changes to the mud will always need to keep the triggers in mind.

* Because it's in-band, sending a sound trigger on its own causes a blank line to be displayed. This looks a bit tacky, and I've already had one player report it as a bug.

* Some clients refuse to negotiate MSP, but they do actually let you play the sound triggers, so you need to give players a way to explicitly switch on sound.

* Clients which support MSP switch it on automatically after negotiation, but there's no way to know if the player actually wants sound, or if they've even downloaded the soundpack. So you need to give players a way to explicitly switch the sound off as well.

As a result, I've been considering making it more of an official feature - a better alternative to MSP. Kaz wrote an elegant proposal for MSP2 back in 2004, but no clients ever added support for it, and sadly I doubt they ever will. However I believe Kaz's underlying idea of sending the sound triggers out-of-band could be incorporated into MSDP (and by extension my pseudo-ATCP) with very little additional effort.

My suggestion is to add a new variable to the CONFIGURABLE_VARIABLES: "SOUND".

After negotiation, it would be up to the client to decide if it wanted sound - perhaps depending on whether the sound files exist, maybe tied to a GUI button, or whatever else is considered appropriate. The important thing is that it's controlled at the client end. The exchange would work as follows:

Server: IAC WILL MSDP
Client: IAC DO MSDP
Client: IAC SB MSDP MSDP_VAR "SOUND" MSDP_VAL "1" IAC SE

The mud would then start sending sound triggers like this:

Server: IAC SB MSDP MSDP_VAR "SOUND" MSDP_VAL "cake.wav" IAC SE

This should override MSP for obvious reasons, but it could use the same syntax as an MSP trigger
for backward compatibility with muds that support both.

I guess there could also be a "MUSIC" variable, although I've never found the use for it myself.

The other option would be to MSDPify the whole thing into something like:

Server: IAC SB MSDP MSDP_VAR "PLAY" MSDP_VAL MSDP_OPEN MSDP_VAR "SOUND" MSDP_VAL "cake.wav" MSDP_VAR "VOLUME" MSDP_VAL "100" MSDP_CLOSE IAC SE

However I think that's probably overkill.

Right now I just want something that's quick to add, but which can be easily extended in the future without backward compatibility issues. It does seem that just a configurable "SOUND" variable would be sufficient, perhaps with a simple SendSound() wrapper function that can be used whereever the mud owner sees fit.
15 Mar, 2011, Scandum wrote in the 2nd comment:
Votes: 0
I'd prefer:

Server: IAC SB MSDP MSDP_VAR "PLAY" MSDP_VAL MSDP_OPEN MSDP_VAR "FILE" MSDP_VAL "cake.wav" MSDP_VAR "VOLUME" MSDP_VAL "100" MSDP_CLOSE IAC SE

And for servers that want to keep it simple:

Server: IAC SB MSDP MSDP_VAR "PLAY_FILE" MSDP_VAL "cake.wav" IAC SE

That way there's a kind of pseudo-nesting consistency.
16 Mar, 2011, KaVir wrote in the 3rd comment:
Votes: 0
I notice you dropped the word "SOUND" entirely. Would "PLAY" and "PLAY_FILE" also allow you to play video clips? If so then that's fine - but if not, then I think "PLAY_SOUND" would be preferable, so that you can have "PLAY_VIDEO" as a separate MSDP variable.
16 Mar, 2011, Scandum wrote in the 4th comment:
Votes: 0
It seemed weird to me to place the file name under "SOUND".

It's also possible to use "SOUND" and "SOUND_FILE" as reportable variables. A server could support either or both, with "SOUND" having nested data. In addition, "MUSIC" could be added for background music, "IMAGE" for images, and "VIDEO" for videos.
16 Mar, 2011, KaVir wrote in the 5th comment:
Votes: 0
I only really picked SOUND because that's what MSP uses, and my snippet will automatically use in-band MSP triggers if the sound flag is switched on and the client doesn't support MSDP or ATCP. Thus the SoundSend() function will currently send one of:

1) IAC SB MSDP MSDP_VAR "SOUND" MSDP_VAL "cake.wav" IAC SE

2) IAC SB ATCP "SOUND cake.wav" IAC SE

3) "!!SOUND(cake.wav)"

I have no objections to changing it, I just don't want to call it "PLAY_FILE" if it only covers sound, as then people will start adding "PLAY_VIDEO" or something, and that's not very consistent - I'd rather just call it PLAY_SOUND to start with, then you could have PLAY_SOUND, PLAY_MUSIC, PLAY_VIDEO, etc. Or just "PLAY" if you're nesting it.

I'm not convinced that MUSIC is necessary though - surely it's just another SOUND file? I was under the impression that MSP only distinguished between the two because of the way zMUD handled sound. Of course you probably only want one background music file being played at a time, but that limitation could apply to other sounds as well (for example I only play one 'weather' sound at a time, and only one 'terrain' sound at a time, but you can still have one of each playing simultaneously). This could better be handled through some sort of grouping identifier for sound types, which could then be used for background music as well.

I did also consider using a REPORTABLE variable, the problem is that they're not always reported instantly - and even if you're sending MSDP variables once per second, the delay for combat sounds is going to feel a bit off. Also, REPORTABLE variables are only sent when they change, but it's possible you might receive the same sound multiple times in a row. So to be honest I think they should be handled separately.
16 Mar, 2011, Scandum wrote in the 6th comment:
Votes: 0
KaVir said:
I have no objections to changing it, I just don't want to call it "PLAY_FILE" if it only covers sound, as then people will start adding "PLAY_VIDEO" or something, and that's not very consistent - I'd rather just call it PLAY_SOUND to start with, then you could have PLAY_SOUND, PLAY_MUSIC, PLAY_VIDEO, etc. Or just "PLAY" if you're nesting it.

The way I see it you're transferring data and not giving an implicit instruction. From that perspective SOUND_FILE works if the variable contains a file name.

KaVir said:
I'm not convinced that MUSIC is necessary though - surely it's just another SOUND file?

Maybe someone with experience using background music is willing to comment? I assume it'd be easier to handle background music separately, but I have no practical experience.

KaVir said:
I did also consider using a REPORTABLE variable, the problem is that they're not always reported instantly - and even if you're sending MSDP variables once per second, the delay for combat sounds is going to feel a bit off. Also, REPORTABLE variables are only sent when they change, but it's possible you might receive the same sound multiple times in a row. So to be honest I think they should be handled separately.

Nothing forbids REPORTABLE variables from being reported instantly. There's also nothing that stops a server from sending the same data twice, as the responsibility is at the server end, the client shouldn't have any build in safeguards against data duplication. From that viewpoint SOUND data can be seen as data that expires, with the server handling data expiration, like making sure a 10 second sound isn't send twice in a 10 second interval.

There's an argument to be made however that it should be a configuration. If you have a command based configuration for MSP it'd make sense to override it with a silent MSDP based configuration.
17 Mar, 2011, KaVir wrote in the 7th comment:
Votes: 0
Scandum said:
The way I see it you're transferring data and not giving an implicit instruction. From that perspective SOUND_FILE works if the variable contains a file name.

You're transferring data in so much as you're sending a file name - but I would definitely consider it an instruction. The mud is telling the client to play the specified sound.

It wouldn't make sense, for example, for the client ask the mud to SEND the sound - it's not some variable that the mud would be expected to keep track of.

Scandum said:
Nothing forbids REPORTABLE variables from being reported instantly.

Agreed, but for practical reasons the server is unlikely to work that way.

Scandum said:
There's also nothing that stops a server from sending the same data twice, as the responsibility is at the server end, the client shouldn't have any build in safeguards against data duplication. From that viewpoint SOUND data can be seen as data that expires, with the server handling data expiration, like making sure a 10 second sound isn't send twice in a 10 second interval.

The server can't reliably do that - it has no way to know what sound files you're using. Most sounds are very short, and can be played over the top of each other. Others are longer and should wait until the previous sound has finished, but those probably can't be identified by filename (you'd need to categorise them by folder or type, eg "weather", "terrain", "music", etc). It's then up to the client to choose a sound channel for them, and check whether it's already being used.

Scandum said:
There's an argument to be made however that it should be a configuration. If you have a command based configuration for MSP it'd make sense to override it with a silent MSDP based configuration.

That's pretty much what my snippet currently does - it uses MSDP or ATCP if it can, otherwise it falls back on MSP.
02 Jun, 2011, Scandum wrote in the 8th comment:
Votes: 0
What I ended up doing for my snippet is having a STREAM bit that can be set on a reportable variable, and when enabled all variable changes are reported instantly instead of getting queued.

Various uses I can think of:

auto mapping: players can typically move several rooms per second, so the room data updates need to be sent instantly.
channels: several channel messages can occur in a short time span.
sounds: As discussed, need to be timely, and duplicates should be allowed.

Right now the server determines whether to stream a reportable variable or not, I don't think there'd be a whole lot of utility to let users enable/disable the streaming bit.

I think it'd be alright to use the report system as I don't think it matters to the client in what exact way a variable is reported.


You also mentioned having to categorize sounds to avoid collisions. It'd be somewhat tricky to handle that without nesting, while it's somewhat tricky to report a nested PLAY variable as it's a little too generic. It'd look somewhat silly to send "REPORT PLAY". I think it'd be best to use PLAY_SOUND, and nest FILE, VOLUME, CATEGORY, and other data inside it, and expect clients to handle nesting. It would be enabled by having PLAY_SOUND reported. On the nesting subject, did you ever get around to getting nesting support working in your Mushclient plugin?

Then for unnested support you could use PLAY_SOUND_FILE.. In theory it'd be possible to report PLAY_SOUND_CATEGORY, etc, as well, but then it's a bit of a guessing game whether the server sent the file or the category first, though if placed in the same sub-negotiation the client could schedule to play the sound at the sub-negotiation end event. I'm not a big fan of this approach though as this is one of the areas where nesting is ideal.
02 Jun, 2011, KaVir wrote in the 9th comment:
Votes: 0
Never needed nesting, so I didn't get around to adding support to my MUSHclient plugin.

I released my snippet two months ago, so it's going to be difficult persuading people to change now, particularly when the current approach works perfectly fine. Muds using my snippet will send PLAY_SOUND with a filename.
02 Jun, 2011, Scandum wrote in the 10th comment:
Votes: 0
Might be an idea to create a sub-specification of your variable set.

So I gather you've got SOUND as a configurable variable, with PLAY_SOUND variables being sent afterwards.

The approach I'm leaning toward is reporting PLAY_SOUND and sending back nested data, or reporting PLAY_SOUND_FILE for only receiving the file data. Servers would be expected to mark the variable to update instantly.

As you use a different reporting mechanism it should work out alright.
02 Jun, 2011, KaVir wrote in the 11th comment:
Votes: 0
Scandum said:
So I gather you've got SOUND as a configurable variable, with PLAY_SOUND variables being sent afterwards.

Yes. If the SOUND variable is set to 1, then the snippet will send PLAY_SOUND using MSDP or ATCP. If SOUND is 1 and the client doesn't support either MSDP or ATCP, the snippet will send MSP in-band !!SOUND() triggers instead.
0.0/11