Nicolas Weeger wrote: > > What about sending the spell's name to the client, so it could play the > 'right' sound? Like 'fireball', 'frostbolt', ... This isn't a good long term solution. Suppose I add a new spell 'large firebolt'. The client may know what to do with firebolt, but when it sees 'large firebolt' doesn't really know what sound to play (the designer of the spell may have envisioned using the same sound as firebolt). Now one can try to come up with clever matching logic, etc, but in the end, including the sound to play someplace with the object is the way to go. > > Seems nice, but I don't see the need for the volume - since it's a client > setting, not a server one. The idea of volume is that you may want to use the same sound file for multiple events, but vary the intensity. Such a case could be for the spells which have a small/medium/large variety - perhaps same sound effect, with the large one being louder than the small one. > And, if we redo the sound structure, could I suggest adding sound > direction/propagation information too? This way, in the future, clients could > add doppler effects to sounds, making'em coming towards, stuff like that. Can you provide a better example? Currently, when a sound is played, the location of the sound (relative to the player) is sent to the client, so the client might know that the offset is -5, 5 to the player, and adjust accordingly in terms of volume as well as stereo effect. The current sound interface only presumes a 2 channel system - I suppose if someone cared, they could in fact do a 4 channel setup (left/right/front/back). > Been thinking of this sound stuff, here are some ideas. > > We should define sounds in archetypes/treasures/artifacts: one or more lines > sound <sound code>:<sound name> which will fill in a list of sounds. > > Then when a sound needs to be sent for an event, we know which file to send. Well, if the sound structure as mentioned previously is used, that includes the sound name. So at collection time, a 'sounds' file could be written that associates each mentioned sound file with a number, much like the images. The sound stuff could then be dealt with much like the images are, however, I'd personally say that a pure cache approach is used (at startup, the client gets the number->name mapping of all the sounds - in generally, I'd expect that list to never be that big, so shouldn't hurt startup that much). Then, after that, the server references all sounds by number. If the client doesn't have a sound, it can request it either at startup (when it gets all the sound names), later on (when actually used) or never (if sound support is turned off for example). As I think about it, it could be nice to extend that sound mapping to be something like number:filename:printable name. Thus, the client could always get the sound notifications, and depending on settings, decide to actually make a sound, or print something like 'you hear a fireball off to the west' (where fireball is the printable name). I personally don't think a push idea of sending the sound files (unrequested) to the client is a good idea. The sound files are in most cases much larger than images are (most images are just a couple K, many of the sound files are in the 10-20K range). But in addition, I'd expect the sound files to be much more static. EG, new sounds may get added, but it is unlikely that someone will 'redo' the gong.raw file, so your almost certainly pushing redundant data. And in fact, the sounds should probably be included with the client. > > Of course, this will break current clients' sound support, which use a unique > identifier. But this would enable us to have multiple sounds, one per monster > for instance, maybe even up to specific sounds for one specific monster > (defining sounds in editor - which would then need to support that :)) This is why I mentioned the idea of the sound structure. In addition to knowing that sound X is associated with an object, you have to know how it is associated. Thus, you could have something like: sound_move walk(100) sound_attack clang(80) and so on. I suppose if you want different sounds for the same event, you could do them as a list, like perhaps: sound_move walk(100),pitterpatter(40),stomp(80) (the number in parens is to denote relative volume). However, you then have a few more issues: 1) in such a list, do you cycle the sounds (walk, pitterpatter, stomp), or whenever one should be played, do you choose random? And if the later, do you then want to add some weighting criteria (90% of the time, do the walk, and 5% do pitterpatter and 5% stomp for example). 2) Potentially some form of how often to play the sound is needed. For example, many sounds laster longer than 1 tick. So if you have something that is happening every tick, you don't want to play a sound every tick - you want to somehow denote 'wait 5 ticks before playing again'. But now if the different sounds have different lenghts, you then need to denote play length for each sound also. One thought I have is something like multiple lines - the format could be like: <sound event> <sound file name> <volume> <play time> <any other values> And so if you want multiple sounds, something like this may be perfectly valid for objects: sound_apply apply1 50 ... sound_apply apply2 80 ... sound_apply apply3 90 ... And then just have the sound structure be smart enough to know there are more than one sound associated with an apply event. > > Also, sounds would be considered as pictures, sendable to the client on > request. But sounds are probably bigger'an images (it seems to me), so we > don't want to lock the client while it's downloading a sound. There may not be a really easy way to avoid it. The easiest is to have a seperate stream to get the sound - however, if you're going to do that, might as well use http or ftp so that nothing special is needed (thus, you could point your client to any number of ftp servers that have the sound files). However, that only half fixes the problem - if you're on a slow link, the length of time it takes to download the sound on that seperate stream will still deprive the client/server connection bandwidth. If you're on a slow connection, this could still be a problem (connection appears lagged). If you're on a very fast connection, the time it takes to download is pretty insignifcant (if my math is correct, to download a 20 K sound over a 1.5 mbs dsl link or the like is about 1/8th of a second). However, the bigger issues are that sounds are not as critical as images are. So IMO, saying if you want sounds, download the sound file from the web site is perfectly valid - if you're sound file is slightly out of date, its almost certainly not going to cause the game to be unplayable like missing some number of images could be. I'd also note that since the format of the sound archive would be very simple (tarred/zipped up directory) that making new releases would be quite trivial - no code changes, or dependency of code changes like you can get with the arch files, so should be trivial to keep up to date archives around (but as said above, I also don't expect it to change a whole bunch). > > One thing, which could be used for pics too, would be for the client and > server to maintain a list of known images. When the client detects changes, > it grabs latest server's image list, and downloads all images/sounds/other > media in the 'background', without blocking play. This way, client would > transparently update its data, which'll be ready when needed. Of course, > still need the case when we ned to download a file before continuing (like a > new pic which is visible right now). Only drawback would be to find an easy > way to sync client with server, with minimum overhead. Well, there is code in place to sync up before play. I'm personally not all that interested in seeing code that syncs up during play - that adds a lot of extra complexity - certainly to the client, in handling multiple incoming sockets, making sure all the client is in sync, etc. And potentially the same issue on the server (associate another socket connection with that client, have to deal with state on it also in that the server can't ever perform blocking operations, so it has to track where it is in the process, wait for buffers to drain, etc). And all of that means that it isn't as efficient tranferring data as a program designed to do so (like ftp). But there is also those edge cases. The current method of syncing everything before play start (or during play through the current in band connection) isn't that big a deal if only a few images need to be updated. If your images are completely out of date, the method crossfire uses is much less efficient than grabbing an up to date set via ftp. If anything, the best method would be for each crossfire server to have an anonymous ftp server associated with it, and use ftp to get the data. The server installation could get modified to have something like a --with-ftp-directory=... option, which is set, the 'make install' copies the relevant files to the ftp directory. Scripts (or maybe builtin functionality if a GPL ftp library is included) would then get the files - this then removes all the image and sound and any other downloading functionality out of the server. The problem is that still doesn't help the case where 99% of your images are correct - you really do want to be able to download just those 50 images that need updating, and not the entire collection. _______________________________________________ crossfire-devel mailing list crossfire-devel at lists.real-time.com https://mailman.real-time.com/mailman/listinfo/crossfire-devel