What story segments are and how to use them.
cStorySegment - Story segment objects
Sometimes you will need to show players a "cut scene", which is
basically a short animation (series of images) along with audio.
For example: If the player meets an important NPC, you may wish
to spend a minute having the NPC talk, showing the NPC interacting
with the player, etc. Cut scenes are fairly common in game,
although usually they're full motion video. (Circumreality doesn't allow
for FMV.)
You might even need to go one step futher, and have a cut
scene with a series of options at the end, such as how the
player can respond to the NPC's question. These responses
might result in further cut scenes.
Using this technique creates an experience similar to the
traditional "Choose Your Own Adventure" books.
Alternatively, you can string one cut scene after another,
creating a linear story.
All of these devices can be created using the cStorySegment
class.
The cStorySegment class allows you to display short (or long)
animations (as a series of stills) and audio on the player's
computer. When the animations have finished displaying, the
story segment either moves onto the next story segment (creating
a linear narrative) or displays a menu that lets the user
chose what's next.
Creating a new story segment
Creating a story segment is easy:
-
Just as described in the "cObject" tutorial, create
a new object, but instead of deriving
your room off cObject, derive it from cStorySegment.
(cStorySegment is a subclass of cObject, so by deriving from cStorySegment
you are also deriving from cObject.)
-
Make sure the Automatically create as an object button
is checked.
-
Story segments should not be contained in
other objects.
-
In the object's properties tab, you'll find a
number of properties that were automatically added when
you selected the "cStorySegment" class. You'll need to fill these in.
-
pNLPParseName and pNLPNounName can
be filled in with the segment's name. See How command parsing
works and Noun cases and noun-verb agreement.
-
pAmbient can be filled in with a resource for
the ambient sounds played during the story segment, or
left blank.
-
The menu properties need to be filled in; I
will discuss them later..
-
If the story segment's pStorySegmentHideUI is FALSE (which is
the default), then you'll need
to set pVisual to the final image of the story segment.
-
Fill pStorySegmentCutScene in with the cut scene to
be played for the story segment, along with pVisual with
the final visual to be displayed to the user, giving them menu
choices.
If you want something more complicated, then you'll
need to modify StorySegmentGet(). In
the object's methods tab, you'll find an
entry for the StorySegmentGet method. You
will need to write this. See below.
Each story segment should provide
a pStorySegmentCutScene and pVisual property.
However, if these are too limiting, then you
may wish to write your own StorySegmentGet() method.
This method is used to control what images are displayed on the
user's computer, along with any sounds that are played.
StorySegmentGet() returns a MML string that is passed directly
to ConnectionSend(). What you place in the MML string is up
to you, but (by convention) it should set the visuals for the
main image using MMLDisplayWindowMain(). You may even
wish to update the main display window several times.
A typical StorySegmentGet() function will look something like this:
return
&tab;MMLDisplayWindowMain (...) +
&tab;MMLSpeakNarrator (...) +
&tab;MMLDisplayWindowMain (...) +
&tab;MMLAudioPlay (...) +
&tab;MMLDisplayWindowMain (...);
|
Each MMLxxx() function is a step in the animation or audio.
The "..." will depend upon the function, of course.
For more information about generating MML strings,
see the "Talking with the client" tutorial.
If a StorySegmentGet() isn't written, the story segment will
call MMLCutScene() and VisualGet(), and display the
pStorySegmentCutScene and pVisual properties instead.
When the story segment is finished playing, it brings up a
menu, allowing the user to choose an option. There are several
ways of accomplishing this:
The easiest is to fill in pStorySegmentOptions with
a list of menu strings, such as ["Say hello to Fred", "Ask Fred
about the sword", "Leave"]. You then need to
fill in pStorySegmentActions with a list of story
segment or room objects
corresponding to the action taken. Example: [oStoryHelloToFred,
oStoryAskFredSword, oRoomInTheCity]. If the object is a story
segment then the new story segment will be run. If it's a room
the the player's character will be moved into the room.
If you do use the the pStorySegmentOptions property,
you can also fill pStorySegmentMenuTimeOut to the
number of seconds before the menu will time out. (If you leave
the property blank, the menu won't time out.) When the menu
times out, it will automatically chose the first item in the
menu and do that.
Alternatively, if you want more control over the menu, you
can create a GeneralMenu resource and
fill pStorySegmentMenu with the resource name.
If you use a menu resource, pStorySegmentOptions will
be ignored.
You may still wish to fill in pStorySegmentActions though.
The story segment object automatically handles user commands
in the form of "Option X", where X is a number from 1+.
If the menu item's command is "Option 1", then
the player will be moved to pStorySegmentActions[0]. "Option 2"
will move the player to pStorySegmentActions[1], etc.
If your menu returns commands that are not "Option X", such
as "Say hello to fred", then you will need to provide a
NLPCommandParse() and NLPCommandParseQuery() message for
the story segment, which is a lot more work.
If you don't wish to display a menu at all, but wish to have
the story segment automatically pass the player to another
story segment or another room then fill
in pStorySegmentAutoCommand with the command
text to run when the segment is finished with its in animation.
The easiest way to handle this is to set pStorySegmentAutoCommand
to "Option 1" and have pStorySegmentMenuActions contain
a list with one item, the next room or story segment.
And if that weren't enough options, you can even have hot
spots in the images displayed by the story segment's
StorySegmentGet() call. If the user clicks on a hot spot,
the specified command will be send. As with menu resources,
using "Option X" will make programming much easier.
Some story segments might include "mini choices" that (usually) reveal
information that helps players make a choice for the story segment,
but don't actually branch off into a new story segment.
For example: A story segment might have the player encounter a door,
and then decide to open the door or leave it alone. The player might
wish some more information, and might be provided with
the mini-choices of "Examine the door" or "Look through the keyhole".
Selecting a mini-choice will speak some text (or play a cutscene),
like "You look through a keyhole and see an orc waiting to
ambush you."
However, mini-choices have a cost. If they didn't, then players
would aways select them. The costs might incur the risk of something
else happening (branching to another story segment for a "wandering
monster" instead of the keyhole description being played), or
negatively affecting a NPC that the player is in conversation with,
or perhaps the player is only allowed to choice "one of the above".
To add mini choices:
-
Add the choice description
to pStorySegmentMenuOptions as usual.
-
Under pStorySegmentMenuActions, use a sub-list
for the action instead of a room.
For example: In the "Look through the keyhole" option,
the sub-list might be ["speak", "You look through a keyhole and see an orc waiting to
ambush you."].
-
Describe the consequence by
filling in pStorySegmentMenuConsequences. If
you don't fill the consequence in then the
default is to use 1 action point, which effectively becomes
a "Choose 1 of the following."
NOTE: Once a mini-choice has been made, it cannot be made again if
the player re-enters the story segment.
The default consequences deal in "action points".
The first time the player enters the story segment they
are given a limited number of action points; Always less
than the number of choices that require action points!
A limited supply of action points forces the player to
"Choose 1 of the following 2 choices", and turns
the story segment into a small sub-game of its own.
You can specify the number of action
points in pStorySegmentActions. If you don't,
then players will be given enough action points so
they can only choose half of the available action-point-based mini-choices.
Moving a player into a story segments
Once the player is in a story segment, it's easy to for
the player to move to other story segments or rooms, but
how does the player get into a story segment in the first place?
There are two ways:
-
You can provide a story segment as an exit from a room,
filling pExitXXX with the story segment
object instead of a room object.
-
Your code can call ActorMoveParty() to move the
character into a story segment.
Other properties and methods
Unlike other classes, there really isn't much more to a
story segment. cStorySegment is a fairly simple class. However,
some more properties exist:
-
pStorySegmentEnterAsParty - This flag defaults to
TRUE, and forces all members of a party to enter (and leave) a story segment
together. This ensures that party members don't just wander around,
but that they don't wander into different paths of the story.
-
pStorySegmentHideUI - Setting this flag in a story segment
causes all the UI except for the main window to be hidden. This will prevent
players from typing in commands, viewing inventory, or even
talking to other players in the segment. Since most story segments
are entered as a party and may want to talk with
one another, pStorySegmentHideUI defaults to FALSE.
However, if pStorySegmentHideUI is FALSE, then strangers in the story
segment will also be able to see and talk to one another. This
may break the immersion of the game. To solve this problem, put the
story segments into their own "instance" (described later).
-
pStorySegmentMenuExtraText - Provides an extra description
to the command. If not specified, some "extra text"
values are automatically generated for mini-choices.
-
pStorySegmentIdentifySelf - Causes one or more NPCs
to introduce themselves to the PCs.
-
pStorySegmentKnowledgeAdd - Automatically calls KnowledgeAdd()
for one or more pieces of knowledge.
-
pStorySegmentQuestsAdd - Adds a quest to the PC's list.
-
pStorySegmentMystery - Adds a mystery to the player's list
by calling MysteriesAdd().
Share with your friends: |