Multiplayer Interactive-Fiction Game-Design Blog



Download 8.87 Mb.
Page111/151
Date02.02.2017
Size8.87 Mb.
#15199
1   ...   107   108   109   110   111   112   113   114   ...   151

08 Talking with the client


Discusses how communication between the server and client works.


Talking with the client

The Circumreality server application communicates with the client software

(on the player's computer) over the internet. All communications

are done using a MML string (basically XML).

The Basic IF library supplies several functions useful for

sending messages over the Internet to the client.


Most of the functions have two flavors, one that sends the

message immediately, although it will be queued up on the

client. The other returns a MML string; several of these

strings can be appended and then sent all at once to the

client. Functions that return the MML string are generally

prepended with "MML", such as MMLAudioPlay(), which returns

a MML string, while MMLAudioPlay() sends the string immediately.





Basic functions

The most commonly used communication functions are:







  • ActorLanguageSet() - Calling this function

    sets the current language (through LanguageSet()), to whatever

    language the actor has chosen as their preferred language.

    Before sending any message to an actor, you should call

    ActorLanguageSet() to ensure they will receive the message

    in the proper language.







  • AudioPlay() - Plays a wave or MIDI (music) file

    on the user's computer.







  • AutoCommand() - Has the user's computer send

    a command back to the server, such as "go north". At first

    glance this function may seem pointless, but it is useful

    since the message will be sent only when the

    client's playback queue gets to this point.


  • AutoCommand() is particularly useful for story segments

    since a small portion of audio and animation can be queued

    up on the user's system. When all that is played, the

    AutoCommand() will cause a message to be send back to the

    server, which in turn sends a bit more of the story.



  • ObjectDisplayUpdate() - Whenever an object

    is changed (such as turned on or opened) its visuals may

    change. Calling ObjectDisplayUpdate() will update the

    object's visuals to one of the players.







  • ObjectDisplayUpdateAll() - This is just

    like ObjectDisplayUpdate() except that all of the players

    in the room will get the visual update.





  • RoomDisplayUpdate() - When the contents of

    a room has changed, calling this will update the visuals

    (room display, contents, inventory) for one of the

    players.






  • RoomDisplayUpdateAll() - Just like

    RoomDisplayUpdate() except all players in the room are

    notified.





  • Silence() - Calling this will add silence to

    the queue, creating a pause between actions.







  • SpeakNarrator() - Causes the text-to-speech

    to be played on the player's computer. The voice used

    will be the narrator's.





  • SpeakObject() - Causes the text-to-speech

    to be played on the player's computer. The voice used

    will be the object's.





  • StringCleanup() - This utility function

    removes potentially unsafe characters from names (or other strings)

    that come from from the user's command.




Some less commonly used functions are:







  • AmbientLoopVar() - Some ambient sounds that

    include loops have the ability to loop in different ways

    depending upon the value of "ambient loop variables". This

    function lets the server set the value of the variable.







  • AmbientUpdate() - This updates the ambient

    sounds played on a player's computer. The ambient sounds

    are a set of sounds based on the player's room, and sometimes

    even items carried by the player.







  • ChatDisplayUpdate() - Update's the actor's

    chat window.







  • ChatVerbUpdate() - Update's the actor's

    chat window.







  • CommandLineShow() - Shows or hides the command

    line. If the command line is hidden the player must click

    on hotspots or menus, and cannot type in commands directly.





  • Position360() - Changes the player's facing

    for the 360 degree images.







  • VerbWindowShow() - Shows or hides the player's

    verb window.








MML-string functions

The MML string functions don't actually send a message to

the player's computer. Instead, they return a string with the

message. The message can then be sent at a later date, combined

with other messages, or passed into other MMLxxx() functions.





  • MMLAmbientLoopVar() - Like AmbientLoopVar()

    except it returns the string.







  • MMLAmbientSounds() - This function combines

    several "<Ambient>" resources into a single "<AmbientSounds>..</AmbientSounds>"

    message that can be sent to the client.





  • MMLAudioPlay() - Like AudioPlay() except

    it returns the string.







  • MMLAutoCommand() - Like AutoCommand() except

    it returns the string.







  • MMLCommandLineShow() - Like CommandLineShow() except

    it returns the string.







  • MMLDelay() - See the "Queues and delays" section

    for a complete description.







  • MMLDisplayWindow() - Calling this will create

    a new window on the client's computer and display the provided

    object within the window. If the window already exists then

    it will be updated.







  • MMLDisplayWindowMain() - This function combined

    MMLObjectDisplay() with MMLDislpayWindowMain() to make

    it very easy to update the image shown in the main window.





  • MMLGroup() - MMLGroup() is used to wrap up groups

    of related object images (See MMLObjectDisplay() or the

    method VisualAndMenuGet()). The groups of images are then combined

    using MMLIconWindow().







  • MMLIconWindow() - Creates a new window on the

    player's computer that displays a series of objects. If the

    icon window already exists then it will be updated with

    the new information. The objects

    are arranged into groups. For example: The inventory window

    has a group of items immediately held by the player character,

    followed by groups for items contained within other items.





  • MMLObjectDisplay() - The MMLObjectDisplay()

    function creates an "<ObjectDisplay>" MML command, which

    is used to name an object, provide a visual for it, and

    perhaps a menu. You may also wish to look at the

    VisualAndMenuGet() method documentation.


  • The <ObjectDisplay> MML

    command can be used in a few different ways: The MML

    string can be passed to MMLGroup() or MMLDisplayWindow() to

    specify what objects are displayed in an icon or display window.

    Alternatively, the <ObjectDisplay> MML can be sent directly

    to the client using ConnectionSend(); doing this will cause

    any visuals for the object to be updated to whatever is

    in the new MML.




  • MMLObjectDisplayGroup() - This function

    is used to get the <ObjectDisplay> MML for the contents

    of an object.





  • MMLPosition360() - Like Position360() except

    this returns the MML.







  • MMLQueue() - See "Queues and delays" for more

    information.







  • MMLQueueSimultaneous() - See "Queues and delays"

    for more information.







  • MMLSilence() - Like Silence() except this returns

    the MML.






  • MMLSpeakNarrator() - Like SpeakNarrator() except

    this returns the MML string.







  • MMLSpeakObject() - Like SpeakObject() except

    this returns the MML string.








Queues and Delays

Whenever a message is sent to the client (using ConnectionSend()),

there is an option for placing the message in the main queue

or acting on it right away. If the message is placed in the main

queue it will ignored until that point of the queue is reached.

The queue allows you to have the client play a sound (waiting

until the sound is finished), speak (waiting until the speech

is finished), display an image, speak again (waiting until

the speech is finished), etc.

If the message are marked for immediate use, then all of the

events will happen at the sime time... except the

speech. The text-to-speech system can only generate one voice

at a time, so even if you tell it to speak several sentences

at once, it will end up speaking them one at a time.


All of this can easily be done using ConnectionSend() and the

MMLxxx() functions above.

However, what if you want a sound to play concurrently with

the second audio (both being played after the image is

displayed)? Or what if you wanted the sound to play half

way through the speech?

To do this you would use MMLDelay().


The <Delay> MML command causes another queue to be created

which runs at the same time as the original one. Therefore,

if you call add MMLDelay (0, rWaveToPlay) into the queue then

at the point in the queue where the message is processed, it

will create a new queue that playes "rWaveToPlay". When

rWaveToPlay is finished playing the second queue will

automatically shut down.


If you pass a time into delay, such as MMLDelay (5, rWaveToPlay)

then the wave won't play until 5 seconds of the next sound (or

speech) has been played. (For example: MMLDelay(5,rWaveToPlay) +

MMLNarratorSpeak(...) will play the sound 5 seconds after the

narrator begins to speak.)


Since the amount of time to speak will vary depending upon the

user's speed settings (or language selected), you can have the

delayed wave play a percentage of the way through the next

sound (or speech). Just use a negative number to indicate

the percentage. (For example: MMLDelay(-50,rWAveToPlay) +

MMLNarratorSpeak(...) will start the wave playing half way

through.)


But what if you want your secondary queue to play more than

one wave, or perform some other action?

That's where MMLQueue() comes in. It combines

a series of MML actions into a queue MML. This queue can then

be passed into MMLDelay(). After the delay occurs, the queue

will be processed one at a time.

(For example: MMLDelay(-50, MMLQueue(rWaveToPlay, rWaveOther)) +

MMLNarratorSpeak(...) will play rWavePlay half way through the

speech. When rWavePlay is finished, rWaveOther will be played,

sequentially after rWavePlay, but concurrently with MMLNarratorSpeak()).

You can also use MMLQueue() when calling ConnectionSend().

If you have the message queued up in the main queue then nothing

unusual happens. However, if ConnectionSend() is set to immediate

playback, then the queued events (in MMLQueue()) will start playing

in their own queue, but sequentially.


The Basic IF Library also includes a

function, MMLQueueSimultaneous that combines

MMLDelay(0, xxx) with MMLQueue(). It just makes programming

a bit easier.

Using the MMLQueue() and MMLDelay() functions you can create

complex timings on the user's computer. These are particularly

useful for the story segments, which often rely on simple

animations.


Download 8.87 Mb.

Share with your friends:
1   ...   107   108   109   110   111   112   113   114   ...   151




The database is protected by copyright ©ininet.org 2024
send message

    Main page