Jump to content

Photo
- - - - -

New conversation system how-to


  • Please log in to reply
75 replies to this topic
Thread Starter
jezuro
jezuro

    BI Developer

  • 257 posts
  • LocationBrno, Czech republic

Posted 15 December 2009 - 12:24 #1

As many of you have noticed, Arma II introduced a new conversation system (I'll be referring to it as "conversations" further on) which replaced the old say/...Radio description.ext-based approach. There have been many questions regarding this subject, so I decided to write a short overview of the possibilities and usage of this system.

Main advantages
  • The system itself waits for the sound sample to finish. No more sample time measuring and countless sleeps!
  • Conversation always flows through the appropriate channel (direct for face to face, team radio for distant team members etc.)
  • Possibility to create fully dynamic conversations.
  • Transparent syntax (FSM branches allow fast and efficient edits).
Theory
In order to run a conversation, all of the participants need to have the proper topic added to them. The conversation then starts with the first sentence which one of the participants says to another. After that, the conversation flow is usually controlled by scripts - FSM's and event handlers assigned to the participants. After a participant receives a sentence, his script reacts to its ID and reacts with the proper answer. It may sound a bit complicated, but it's really not.

Let's start with adding the topic. The scripting command to do this is kbAddTopic:

person kbAddTopic [topicName, fileName.bikb, (fileName.fsm, (eventHandler))]
  • topicName: (string) Can be anything.
  • fileName.bikb: (string) Name of the .bikb file - will be described later.
  • fileName.fsm: (string) Name of the .fsm file - will be described later. Optional.
  • eventHandler: (string or code) Will be described later. Optional.
Here is an example of what the code usually looks like:

unit2 kbAddTopic ["baseDefended", "baseDefended.bikb", "baseDefended_unit2.fsm", {call compile preprocessFileLineNumbers "baseDefended_unit2.sqf"}]
.bikb files
Stand for "Bohemia Interactive Knowledge Base" as it was originally used only for storing an AI unit's memory of what it has seen. Not important to you. You will use these files to store all the speech samples (referred to as "Sentences" further on) used for the topic. This is in fact quite similar to the good old cfgSounds and cfgRadio classes in description.ext. Here is a short .bikb file:

class Sentences
{

    class example_01
    {
        text = "Hello Bret.";
        speech[] = {"\Sound\jemaine01.ogg"};
        class Arguments {};
        
    };

    class example_02
    {
        text = "Oh, hello Jemaine.";
        speech[] = {"\Sound\bret01.ogg"};
        class Arguments {};
        
    }
};
class Arguments{};
class Special{};
startWithVocal[] = {hour};
startWithConsonant[] = {europe, university}
  • text: Subtitles used to caption the sample. If you're using stringtable, use $stringName (has to start with "STR_"!)
  • speech: Sound sample.
  • arguments, special, startWithVocal, startWithConsonant: Don't worry about these.
The scripts
In both FSM's and event handlers, there are some default variables which you'll be using quite often:
  • _this: Receiver of the sentence. The unit that had this particular script assigned via kbAddTopic.
  • _from: Self-explanatory. Basically the unit that told me the sentence.
  • _sentenceId: The sentence this unit is reacting to. Defined in .bikb in class Sentences.
  • _topic: Self-explanatory. Topic name used in kbAddTopic.
FSM's
FSM stands for Finite-state machine. We have released the FSM Editor some time ago. I will not describe its functionality here, I'm sure there are plenty tutorials out there. You can open one of the conversation FSMs used in the example mission (you need to have the FSM Editor installed to open it).

As you can see, the FSM parameter is optional in kbAddTopic. That is because a) you don't want to use scripts at all and rather manage the conversation manually (about that later) or B) the unit is always controlled by a player. The engine recognizes who's controlling the unit by the time it receives a sentence. If it's controlled by AI, the assigned FSM is executed. If it's player-controlled, it fires the event handler. If you're making an MP mission and the unit is playable, you will want to use both the FSM and the event handler.

Event Handlers
Nothing to do with our standard event handlers. This is a code used only if the unit is controlled by a player and is executed not only if it receives a sentence, but also if the player points at someone and is close enough to start a conversation ("Talk to" action appears). This is very important to understand. FSM's are executed only once after each received sentence, event handlers are fired constantly (usually every frame) as long as you're pointing at somebody.

Here is an example showing all you might want to use (you should get familiar with kbTell and kbWasSaid first):

// here we'll be storing all the sentences from which the player will choose (the menu on the left side of the screen)
// if there's only one option in the array, you will have the sentence as the "Talk to" action

BIS_convMenu = [];

// we want the player to be able to approach his buddy and talk to him via the action menu
// we need to check:
// if I'm pointing at my buddy
// if I'm not answering any of his sentences
// if I haven't told him hello already
// then we add that array to BIS_convMenu - the parameters are mostly self-explanatory

if (_from == buddy1 && _sentenceId == "" && !(_this kbWasSaid [_from, _topic, "hello1", 999999])) then {
    BIS_convMenu = BIS_convMenu + [["Say hello.", _topic, "hello1", []]]
};

// here we make the unit say the proper sentence based on the one he just received
// I use switch-case-do, it's completely up to you how to evaluate it (if-then etc.)

switch (_sentenceId) do
{
    case "hello1": {
        _this kbTell [_from, _topic, "hi_how_are_you"]
    };
    case "good_you": {
        _this kbTell [_from, _topic, "fine_thanks"]
    };
    case "what_do_we_do_today": {
        // here the player will have 3 answers to choose from
        BIS_convMenu = BIS_convMenu + [["Football.", _topic, "choose_footbal", []]];
        BIS_convMenu = BIS_convMenu + [["Bike.", _topic, "choose_bike", []]];
        BIS_convMenu = BIS_convMenu + [["Arma II.", _topic, "choose_arma2", []]]
    };
};

// return the sentence list pool
BIS_convMenu
There. Everything should be explained in the comments inside the code. As you can see, it's nothing more than a compiled sqf function.

"Interrupted" event
The left-side menu on the HUD with the list of possible sentences can be closed via backspace at all times. If you want to handle this event as well, you just have to add new sentence class called Interrupted into you .bikb file. It can be then used as a standard _sentenceId in the script.

Example mission
And finally, here it is. The example mission contains everything that has been explained here and shows you mainly how to manage the files. It contains voice samples from the Harvest Red campaign, please don't be surprised that the conversation is a bit out of context :)
Get it here.

"Manual" conversation flow
For some reasons, you may not want to use FSMs and event handlers to control a conversation. For this, you will want to use kbWasSaid. An example will suffice I think.

miles kbAddTopic ["briefing", "kb\briefing.bikb", ""];
shaftoe kbAddTopic ["briefing", "kb\briefing.bikb", ""];

shaftoe kbTell [miles, "briefing", "shaftoe_briefing_H_1"];
waitUntil {shaftoe kbWasSaid [miles, "briefing", "shaftoe_briefing_H_1", 3]};

miles kbTell [shaftoe, "briefing", "shaftoe_briefing_M_1"];
waitUntil {miles kbWasSaid [shaftoe, "briefing", "shaftoe_briefing_M_1", 3]};

hint "Conversation ended."
Mission accomplished
:yay:

Well, I think that's everything for now. It's quite possible I forgot to mention something or made a typo in the scripts, please let me know if you're confused about something and I'll edit it out.

Edited by W0lle, 15 April 2011 - 17:11.
Missing "\" in speech paths


IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 15 December 2009 - 15:29 #2

Finally! Thanks man! :yay:
But it's a bit late, i already use the old approach. Anyway, i think i'll try it out in future missions.

Edith: I somehow noticed in earlier tries that there's a problem with custiom sounds. They weren't working. Is there anything i must know to use custom sounds?

mchide
mchide

    Sergeant

  • Members
  • 171 posts

Posted 16 December 2009 - 19:30 #3

This topic should be pinned.
Posted Image

icebreakr
icebreakr

    Captain

  • Members
  • 6211 posts

Posted 16 December 2009 - 19:42 #4

Jezuro tnx!

IceBreakr, C/O [SBP] - Slovenian Black Panthers (www.vojak.si)

OUT NOW for A3: Isla Duala 3.35 | Island Panthera v3.1
WIP: Isla Abramia, Lingor, Tonal Legend, Isla Balkania, Keystone, Jade Groove 3, Ibis World, Rowalla.

sigbif.jpg


sbsmac
sbsmac

    Master Gunnery Sergeant

  • Members
  • 1297 posts

Posted 17 December 2009 - 09:52 #5

Excellent article and great to see this kind of information coming from BIS - thank you !
Author of PVPmissionWizard ArmA2FPSAnalyser AddonChecker and ... squint

Tools homepage

Crosseyed and Painless - a blog about my ArmA2 developments



MadDogX
MadDogX

    Mindless F@nb0!

  • Moderator
  • 9050 posts

Posted 17 December 2009 - 11:03 #6

Excellent article! I especially loved the reference to Flight of the Conchords. :D

Edited by MadDogX, 17 December 2009 - 11:06.


Gigabyte Z97-HD3 Motherboard | Intel Core i5 4690k @ 4.5GHz | NVidia GTX 970
16GB G-Skill Ripjaws 2133MHz RAM | Kingston HyperX SSD | be Quiet! 750W PSU

Himmelsfeuer
Himmelsfeuer

    Banned

  • 724 posts

Posted 18 December 2009 - 15:11 #7

I would be nice if someone could provide a very easy Example Conversation Mission cause i dont know where i add the Topics and which files are exactly needed.
I tried some things out now, but no success. Would be much appreciated!

Edited by Himmelsfeuer, 18 December 2009 - 15:32.


Thread Starter
jezuro
jezuro

    BI Developer

  • 257 posts
  • LocationBrno, Czech republic

Posted 19 December 2009 - 16:21 #8

Currently it's not possible to use sound files stored in the mission directory itself for the new system of conversations (the path in the bikb files starts in the addons folder). I consulted this with our programmers and they kindly made a quick hotfix. Still waiting for the commit though, I'll prepare an example mission as soon as this fix is released.

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 19 December 2009 - 20:52 #9

Great! That is what i call sercvice! Thank you and your programmers!

Thread Starter
jezuro
jezuro

    BI Developer

  • 257 posts
  • LocationBrno, Czech republic

Posted 21 December 2009 - 12:48 #10

The fix will be present in the upcoming patch 1.05. I edited the first post with the Interrupted event and the example mission (note that you won't be able to hear the voice samples before updating to v1.05).

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 21 December 2009 - 20:24 #11

Thanks man! I just finished my first conversation with multiple choice! :yay:

Himmelsfeuer
Himmelsfeuer

    Banned

  • 724 posts

Posted 22 December 2009 - 21:22 #12

Thanks for the example mission !
Hope i get it now...:)

I wanted to try it without Speechsamples first. But i dont get where you create the Subtitles[Texts only] for Speech Files.
Talking about this


text = "$STR_shaftoe_briefing_m_0"; [ where is that File???]
speech[] = {"\ca\dubbing\C0_FirstToFight\shaftoe_briefing\shaftoe_briefing_M_0.ogg"};

Edited by Himmelsfeuer, 22 December 2009 - 22:26.


Thread Starter
jezuro
jezuro

    BI Developer

  • 257 posts
  • LocationBrno, Czech republic

Posted 23 December 2009 - 09:19 #13

The strings I used are defined in the core stringtable. The engine looks there if it can't find the string ID in the mission's stringtable.

Himmelsfeuer
Himmelsfeuer

    Banned

  • 724 posts

Posted 28 December 2009 - 00:49 #14

Thanks very much for the tutorial, its not really easy with the FSM, but if you get behind it, you can do it with some work and without much scriptingknowledge....still i need yours now;-)

Is it possible to use the FSM Conditionfield with waypoints and triggers?
I want to start a AI Action if you has chosen a specific Topic Answer, how would you do it? Thanks!

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 29 December 2009 - 11:55 #15

Hm, i think that's possible. I'd use variables. So a var is set to true if you chose a specific answer. Then you need a trigger wich checks for the variable.

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 30 December 2009 - 02:32 #16

Argh, i've got a situation here wich is driving me mad!

I just want to create a little briefing where two people telling the player what's going on and the player can ask a few questions. But it doesns't work at all! I made a small test mission a few days ago to learn how to create such conversations with success. And now i did the same things as in my test mission, only in a bigger dimension but - no success! There's no error in the .rpt, so i got no clue what it might be. But i have the suspicion that the FSMs aren't triggered at all. Anyway, here're the basic files i use:

"init.sqf"
Spoiler


"start.sqf"
Spoiler


"startDoe.sqf"
Spoiler


"start.bikb"
Spoiler


And here are two pictures of the FSMs:
Spoiler


And here's a link to the WIP mission if you wanna take a look: http://www.filefront...n.Chernarus.rar

I'd really appriciate some help!

Edit: The mission requires ACE2!

Edited by IndeedPete, 30 December 2009 - 02:41.


binkowski
binkowski

    cranky old vet

  • Members
  • 3441 posts

Posted 30 December 2009 - 02:40 #17

Finally! Thank you BI :)
Spoiler
Posted ImagePosted Image
Posted Image
A3: SP Revenge!, SP Infantry

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 01 January 2010 - 18:28 #18

Bump. If anyone with a bit of knowlegde about FSMs would take a look at my problem please. I still have no clue where the mistake is and i'd really, really appreciate some help!

IndeedPete
IndeedPete

    Warrant Officer

  • Members
  • 2625 posts
  • LocationNorthwestern Germany

Posted 03 January 2010 - 14:14 #19

Ha, i got it! Somehow, one of the guys didn't receive some sentences, so he couldn't answer... :rolleyes:

Thread Starter
jezuro
jezuro

    BI Developer

  • 257 posts
  • LocationBrno, Czech republic

Posted 04 January 2010 - 11:16 #20

Don't forget that you can't use either sleep or waitUntil in the FSMs as they're pre-compiled. If you need to add a delay into the code, you have to start a new script scope via spawn.

---------- Post added at 12:16 PM ---------- Previous post was at 11:51 AM ----------

First post updated with main advantages and manual conversation control.