open Outcast is a total conversion mod for Crysis Wars that should become an unofficial successor of the Action-Adventure Outcast (by Appeal).

Report article RSS Feed Extending Crysis with a custom Dialogue System

This feature describes how we added a RPG/Adventure-style nonlinear Dialogue System to the First-Person-Shooter Crysis Wars. The technically interested reader may also find some codesamples at the end.

Posted by s87 on Mar 31st, 2010
Article

The CryEngine 2 is undoubtedly one of the most advanced game engines today offering great graphics, good scaling on weaker and stronger systems, amazing physics and not to forget a feature rich system for character animation.
What is missing a bit are classical RPG/Adventure game elements like a nonlinear Dialogue System. We believed that it's possible to extend Crysis Wars with such a system.
Sounds too good to be true? Got curious how we did it? Read along and see for yourself ...

Choice Screen

1.) Under the hood

In this section you will learn what was needed to create the dialogue shown in the Dialogue Video presented in the corresponding news posting.

XML Files

The first question when designing a Dialogue System is how to define a dialogue and where to put that data. We decided to use XML files since they're common for such things (the native Dialogue System of Crysis also uses XML by the way) and there exist many libraries and tools to manipulate them.
I won't be listing our specifications here, but just to get an impression here is an excerpt from the XML defining the dialogue shown in the video:

xml code:
<dialogue name="Molaar / Oasis">
  <label name="start" />
 
  <logic type="gametoken" name="Level.Molaar.C01.MolaarShownCutterToShrine" is="true">
    <jump to="helped" />
   
  [...]
  <say speaker="player" timeout="4">You talan really are something. How can I help, Molaar?</say>
  <say speaker="npc1" voice="mods/OpenOutcast/Game/Sounds/Dialog:Oasis_test:c01_molaar_molaarisnotknowing" facial="c01_molaar_molaarisnotknowing">Uhh, Molaar does not know. Shamaz Zelum knows! He is at the shrine.</say>
 
  <set gametoken="Level.Molaar.C01.InitialConversationDone" to="true" />
 
  <label name="choice" />
  <choose listener="player" speaker="npc1" />
  <option>Locate Shrine</option>
  <option>Take me to Shrine</option>
  <option>Good bye</option>
  <done />
  <logic type="choice">
  <jump to="locate" />
  <jump to="takemeto" />
 
  [...]
  <say speaker="player">Could you take me to the shrine?</say>
  <say speaker="npc1" voice="mods/OpenOutcast/Game/Sounds/Dialog:Oasis_test:c01_molaar_yesulukai" facial="c01_molaar_yesulukai">Yes, Ulukai! Molaar knows the way.</say>
  <action id="2" />
 
  <set gametoken="Level.Molaar.C01.MolaarShownCutterToShrine" to="true" />  
  <done />
 

To point out some interesting tags:

  • the dialogues are organized using label tags
  • normal conversation is initiated by the say tag
  • selections can be performed using the choose tag
  • you can jump around between labels using the jump tag
  • external actions can be triggered using the action tag

Scene Nodes

Anyone of you who tried out Oasis, our first technology demo released in February, probably noticed that we already had some kind of Dialogue System back then. So did it actually pay off to invest so much time in creating a new one? Why not move along with the old version? Let the pictures talk:

Dialogue System Pics


The image above shows the Flow Graph (for those uncommon with the CryEngine 2 terminology: that's a visual script you can modify by adding and connecting different nodes) of the initial Molaar-dialogue. And now the same with the new system:

Dialogue System Pics


The latter version looks much simpler and less chaotic - this has two implications:

  • Our Level Designers and Game Designers can focus on their work instead of connecting thousands of nodes again and again (since we are going to have LOTS of NPCs!)
  • Our coders can focus on their work instead on debugging this nightmare

Camera modes

To find a way for adding more itensity to dialogues it's always a good idea to take a look at movies. And what do they do to accomplish this among other things? Right - using different camera settings according to the current situation.
An important aspect of the camera part of the Dialogue System was the easy configuration. You can setup any mode (shown in the Camera Video) via an XML-file that looks like:

xml code:
<cameramodes default="overshoulder">
   
  <mode name="extremecloseup" offset="-0.04f,0.45f,0.07f" toffset="0.0f,0.0f,0.17f" zoomspeed="2.5f" fov="26.0f" />
  <mode name="closeup" offset="-0.2f,0.5f,0.10f" toffset="0.0f,0.0f,0.12f" fov="40.0f" />
  <mode name="mediumcloseup" offset="-0.3f,0.6f,0.15f" toffset="0.0f,0.0f,0.05f" fov="50.0f" />
  <mode name="mediumshot" offset="-0.4f,0.9f,0.1f" toffset="0.0f,0.0f,0.0f" fov="60.0f" />
  <mode name="fullshot" offset="-0.5f,1.35f,0.45f" toffset="0.0f,0.0f,-0.4f" fov="68.0f" />
 
  <mode name="mastershot" offset="-14.0f,7.0f,6.0f" toffset="0.0f,0.0f,6.8f" fov="70.0f" />
  <mode name="objectfocus" offset="0.3f,-3.0f,0.5f" toffset="0.0f,0.0f,1.5f" zoomspeed="6.0f" fov="70.0f" />
  <mode name="zoomin" offset="-0.3f,0.93f,0.1f" toffset="0.0f,0.0f,0.0f" zoomspeed="4.0f" fov="55.0f" />
 
  <mode name="overshoulder" offset="0.3f,-0.7f,0.1f" toffset="0.0f,0.0f,0.1f" fov="45.0f" />
  <mode name="medium2shot" offset="-1.2f,0.0f,0.1f" toffset="0.0f,0.0f,1.5f" fov="70.0f" />
  <mode name="overhead" offset="-0.3f,0.7f,0.1f" toffset="0.0f,0.0f,0.1f" rotspeed="4.0f" fov="90.0f" />
  <mode name="roundabout" offset="-2.2f,-1.0f,0.1f" toffset="0.0f,0.0f,1.8f" rotspeed="6.0f" fov="90.0f" />
 

The camera is placed and oriented dynamically according to the position of the current speaker and listener as shown on this sketch:

Dialogue System Pics

Lipsync

Every bigger game comes fully lip-synced nowadays. But what is with Mods? Does it pay off? Animating line by line seems to be extremely time-consuming. So no lipsync after all?
Fortunately there are some tricks to lower the workload by generating lipsync automatically. The animations seen in the Dialogue Video have been autogenerated from the sound files first, and tweaked later a little manually. But let's hear some details on this process from doCHtor, our head of animations:

doCHtor wrote:For lipsync, first of all morph targets were made by the 3d artists. Then phonemes and many expressions (which you can't see in the demo video yet) were build by the animators in the facial editor (that is included in Sandbox 2). Then timings for phonemes were pulled out of the sound files by a free tool called "Quick'n'Dirty Phoneme Extractor". For the future we also want to add some head motions, gesticulation and facial expressions.

2.) Probably FAQ

A list of questions that may probably be asked frequently.

  • Do I have to wait for the final release of open Outcast to see the Dialogue System in action?

Answer: No. We want your feedback on the Dialogue System to improve it's usabilty. Therefore we will release an improved version of Oasis after the implementation of the Questsystem and some additional HUD-elements (Journal and Lexicon) in Q2 2010 (most likely around June).

  • Is the Dialogue System compatible with the FGPS?

Answer: No.

  • Will the Sourcecode of the Dialogue System be released?

Answer: That's not going to happen in the near future.

  • Why not?

Answer: We don't have enough time for maintaining a separate public release of the Dialogue System. Some parts of it definetly will be changed after the implementation of the Quest- and advanced AI-system.

  • That is the only reason? But I just want to have some code to play with and I don't care for it's quality!

Answer: Releasing parts of the mod along with the corresponding sources before the main release has been discussed in the team and the majority was against it.
The main reason is that we don't want to see our work reused by other mods before we used it ourselvels in the release version of open Outcast. You can take a look at the Code snippets below and you may still find what you've been looking for.

3.) Code snippets

Some handy pieces of code that proved themselves valuable during the development of the Dialogue System. I didn't find much about the camera and lipsync handling on the net so those points may be particularly of interest.


Creating entities

With the following code you can create a simple entity from C++ code. You can use it to keep track of a position or a rotation (or attach some view to it and use it as camera!).

cpp code:
// Create a dummy entity
// Will be placed at vPosInit(Vec3) and rotated with qRotInit(Quat)

SEntitySpawnParams spawn;
spawn.sName = "DummyEntity";
spawn.pClass = gEnv->pEntitySystem->GetClassRegistry()->GetDefaultClass();
spawn.vPosition = vPosInit;
spawn.qRotation = qRotInit;
pDummyEntity = gEnv->pEntitySystem->SpawnEntity(spawn);

Cameras and Views

This code will create a new view, attach it to an entity (could be created like described above), rotate it in a way that it looks to a target vector and finally change the field of view:

cpp code:
// Make the dummy entity look to vTarget(Vec3)
Quat q;
q.SetRotationVDir(vTarget - pDummyEntity->GetPos());
pDummyEntity->SetRotation(q);

// Attach a view to the dummy entity and make it the default view
IView* NewView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetViewByEntityId(pDummyEntity->GetId(), true);
if (NewView)
  g_pGame->GetIGameFramework()->GetIViewSystem()->SetActiveView(NewView);
 
// Change field of view to 60°
SViewParams sViewPar = *(g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView()->GetCurrentParams());
sViewPar.fov = 60.0f*gf_PI/180.0f;
g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView()->SetCurrentParams(sViewPar);

Parsing XML files

Let's say you want to parse a config file for camera modes with the syntax showed higher above (surprising example, isn't it?). Reading the name of the available modes could be done as:

cpp code:
// Print the list of supported modes

XmlNodeRef ROOT = gEnv->pSystem->LoadXmlFile("mods/OpenOutcast/Game/config/cameramodes.xml");
XmlNodeRef CHILD;

int iChildren = ROOT->getChildCount();
for (int i=0; i < iChildren; i++)
{
  CHILD = ROOT->getChild(i);
  if (CHILD->haveAttr("name"))
    CryLogAlways("Camera mode %s found!", CHILD->getAttr("name"));
}

Activating Lipsync

If you always asked yourself how to trigger lipsync from code, then here is your answer:

cpp code:
// Set the facial animation of an Entity whose Entity Id is stored in iEntId

CActor* pActor = reinterpret_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(iEntId));
pActor->RequestFacialExpression("grin");

You shouldn't forget to register that "grin" animation for your model properly. We are using CAT for our animations and the config file used for the Dialogue Video looks like:

text code:
#filepath = Animations\talan\facial\test

//-------FACIAL ANIMATIONS-------
c01_molaar_hail = c01_molaar_hail.fsq
c01_molaar_ifoundyou = c01_molaar_ifoundyou.fsq
c01_molaar_molaarhelpedyoufindshamaz = c01_molaar_molaarhelpedyoufindshamaz.fsq
c01_molaar_molaarisnotknowing = c01_molaar_molaarisnotknowing.fsq
c01_molaar_rightoverthere = c01_molaar_rightoverthere.fsq
c01_molaar_wehaveabigproblem = c01_molaar_wehaveabigproblem.fsq
c01_molaar_what = c01_molaar_what.fsq
c01_molaar_yesulukai = c01_molaar_yesulukai.fsq
c01_molaar_theyodsaresmiling = c01_molaar_theyodsaresmiling.fsq


Post comment Comments
Ash712
Ash712 Apr 10 2010, 3:03am says:

This is REALLY F*cking cool of you guys to do for fellow modders!

I've got a similar system in the works thanks to Vigilante on the CryMod forums.
I based ours after Mass Effects Dialog System as well ;)

+2 votes     reply to comment
Alex626
Alex626 May 10 2010, 5:01pm says:

this is not a tutorial, just a show-off for noobs, and you are noob. **** off and shut up.

-4 votes     reply to comment
s87 Author
s87 May 12 2010, 4:41am replied:

Hm, let's see ... if this was intended to be a tutorial it may have been posted under the "tutorials" section instead of "features", don't you think?

The idea of this article was to give other modders an idea how we solved the problem of creating a nonlinear dialogue system - I really don't see the point to get offended by that. -_-

+4 votes   reply to comment
Alex626
Alex626 May 13 2010, 8:36am replied:

So you think that this "tutorial" will help to do anything ?

-1 votes     reply to comment
s87 Author
s87 May 13 2010, 9:33am replied:

Well as said before, it ISN'T a tutorial. This feature just lists some code snippets of things that weren't documented elsewhere - as stated in the FAQ you won't find the sourcecode of the Dialogue system shown in the video anywhere in it.

+2 votes   reply to comment
Post a Comment
click to sign in

You are not logged in, your comment will be anonymous unless you join the community today (totally free - or sign in with your social account on the right) which we encourage all contributors to do.

2000 characters limit; HTML formatting and smileys are not supported - text only

Icon
Crysis Wars Icon
Platform
Windows
Developer
Eternal Outcasts
Contact
Send Message
Official Page
Openoutcast.org
Release Date
TBD
Mod Watch
Track this mod
Feature
Browse
Features
Report Abuse
Report article
Related Mods
open Outcast (Crysis Wars)
open Outcast Crysis Wars - Single Player Adventure
Related Games
Crysis Wars
Crysis Wars Multiplayer First Person Shooter
Related Groups
CryENGINE 2 Developers
CryENGINE 2 Developers Fans & Clans group with 217 members
Eternal Outcasts
Eternal Outcasts Developer & Publisher with 20 members
Single Player Modders
Single Player Modders Fans & Clans group with 94 members