{"name":"Conversations","title":"Conversations","type":"topic","url":"https://community.bistudio.com/wiki/Conversations","revid":370901,"updated":"2025-02-21T10:44:31Z","aliases":[],"markdown":"Arma 2 v1.00 Arma 2: Operation Arrowhead v1.50 Take On Helicopters v1.00 Arma 3 v1.00\n\nConversations is a system created to manage discussions that was introduced in **Arma 2**.\nThis system allows dynamic conversations and a more fluid sentence/answer flow.\n\nIts main advantages are:\n\n- The system itself waits for the sound sample to finish. No more sample time measuring and countless sleeps!\n- Conversation always flows through the appropriate channel (direct for face to face, team radio for distant team members etc.)\n- Possibility to create fully dynamic conversations\n- Transparent syntax (FSM branches allow fast and efficient edits)\n\n### Usage\n\n- A **topic** is defined by a String for id and sentences defined in a **Conversation .bikb** file\n- A **Conversation .bikb** lists all available sentences in a **topic**\n- A **topic** must be added to the concerned units, with eventually a **Conversation FSM** and/or a **Conversation Event Handler**\n- A **Conversation FSM** defines an **AI unit** reaction to a sentence\n- A **Conversation Event Handler** defines a **player's unit** reaction to a sentence, potentially defining available answers\n- If the unit is playable (can be either player or AI), both should be present to ensure a proper reaction in every encountered scenario.\n\n### Commands\n\nA conversation topic:\n\n1. must be added to units (via kbAddTopic)\n1. for the units to be able use it (via kbTell for example)\n1. once the unit said wanted sentences (checked via kbWasSaid),\n1. the topic can be removed (via kbRemoveTopic).\n\n- Related commands are listed in Conversations Command Group\n- Related functions are listed in Conversations Function Group\n\n#### Manual Conversation Example\n\n```sqf\nmiles    kbAddTopic [\"briefing\", \"kb\\briefing.bikb\"];\nshaftoe    kbAddTopic [\"briefing\", \"kb\\briefing.bikb\"];\n\nshaftoe kbTell [miles, \"briefing\", \"shaftoe_briefing_H_1\"];\nwaitUntil { shaftoe kbWasSaid [miles, \"briefing\", \"shaftoe_briefing_H_1\", 3]; };\n\nmiles kbTell [shaftoe, \"briefing\", \"shaftoe_briefing_M_1\"];\nwaitUntil { miles kbWasSaid [shaftoe, \"briefing\", \"shaftoe_briefing_M_1\", 3]; };\n\nhint \"Conversation ended.\";\n// kbRemoveTopic can be used here to \"clear\" the units if the topic is not required anymore. This is not mandatory.\n```\n\n### Conversation .bikb\n\n**.bikb** extension stands for \"**B**ohemia **I**nteractive **K**nowledge **B**ase\" as it was originally used only for storing an AI unit's memory of what it has seen.\nThis file declares the available sentences in the topic, their sound samples and the corresponding subtitles (see example 1 and example 2).\nAs the syntax is the same as config files (Description.ext, Config.cpp) PreProcessor Commands can be used.\n\nConversation sounds do **not** need to be defined in CfgSounds or CfgRadio, unless of course they are to be used with e.g playSound, say or groupRadio too.\nAs opposed to these commands, this new conversation system will automatically use setRandomLip during the speech if no .lip file is present. A .lip file can however still be used for a more precise animation.\n\n> [!IMPORTANT]\n> A duplicate sentence in .bikb file **WILL** crash the game!\n\n#### \"Interrupted\" Event\n\nThe left-side conversation menu (with the list of possible sentences) can be closed via backspace at all times. In order to handle this event as well, add a sentence class called **Interrupted** into the .bikb file. It can then be used as a standard `_sentenceId` in the script.\n\n#### .bikb Simple Example\n\n```cpp\nclass Sentences\n{\n    class hello1\n    {\n        text = \"Hello!\";                    // sentence subtitle - can be \"text\" or $STR_ stringtable reference\n        speech[] = { \"\\Sound\\hello1.ogg\" };    // sound file path relative to mission or campaign directory\n        class Arguments {};                    // unused here\n    };\n    class hi_how_are_you\n    {\n        text = \"Hi, how are you?\";\n        speech[] = { \"\\Sound\\hi_how_are_you.ogg\" };\n        class Arguments {};\n    };\n    class good_you\n    {\n        text = \"$STR_GoodYou\"; // has to start with \"STR_\"!\n        speech[] = { \"\\Sound\\good_you.ogg\" };\n        class Arguments {};\n    };\n    class fine_thanks\n    {\n        text = \"$STR_FineThanks\";\n        speech[] = { \"\\Sound\\fine_thanks\" }; // no extension means .wss to the engine\n        class Arguments {};\n    };\n\n    // these sentences are here to be a full example for later Conversation Event Handler example\n    class what_do_we_do        { text = \"What do we do today?\"; speech[] = { \"\\Sound\\wdwd.ogg\" };    class Arguments {}; };\n    class choose_football    { text = \"Let's football!\";         speech[] = { \"\\Sound\\cf.ogg\" };    class Arguments {}; };\n    class choose_bike        { text = \"Let's bike?\";             speech[] = { \"\\Sound\\cb.ogg\" };    class Arguments {}; };\n    class choose_arma2        { text = \"I know! Arma 2\";         speech[] = { \"\\Sound\\ca.ogg\" };    class Arguments {}; };\n\n    // the Interrupted sentence triggered when the conversation menu is closed without answering (e.g using backspace)\n    class Interrupted\n    {\n        text = \"Hey, come back!\";\n        speech[] = { \"\\Sound\\interrupted.ogg\" };\n        class Arguments {};\n    };\n};\n\n// Needed parameters.\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\n#### .bikb Advanced Example\n\nSee Words configuration and below for more details.\n\n```cpp\nclass Sentences\n{\n    class AirstrikeRequest\n    {\n        // %team and %location will be replaced by the game engine with according values\n        text = \"%team requesting close air support at grid %location \";\n\n        // available words are defined in config > RadioProtocol > Words\n        speech[] = { %Team, RequestingCloseAirSupportAtGrid, %Location };\n\n        class Arguments\n        {\n            class Team { type = \"simple\"; };        // refers to %Team, first element of speech[]\n            // \"RequestingCloseAirSupportAtGrid\" is part of Radio Protocol\n            class Location { type = \"simple\"; };    // refers to %Location, last element of speech[]\n        };\n    };\n};\n\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nAbove sentence would be used this way:\n\n```sqf\nplayer kbTell [\n    BIS_HQ,                                        // to\n    \"Airstrike\",                                // topic\n    \"AirstrikeRequest\",                            // sentence\n    [\"Team\", {}, \"Anvil\", [\"Anvil\"]],            // argument 1\n    [\"Location\", {}, \"Strelka\", [\"Strelka\"]]    // argument 2\n];\n```\n\n#### .bikb BIS_fnc_kbTell Example\n\n> [!NOTE]\n> **Arma 3:**\n>\n> ```cpp\n> class Sentences\n> {\n>     class Sentence1\n>     {\n>         text = \"\"; // must be empty\n>         textPlain = \"$STR_MySubTitle\";\n>         /* other parameters */\n>     };\n> };\n> ```\n>\n> **In an addon/mod scope**, an additional subtitle entry is available to have subtitle rendered with BIS_fnc_showSubtitle: `textPlain`, declared as shown.\n> **This is not available for standard missions** as BIS_fnc_kbTellLocal only checks configFile and none of missionConfigFile or campaignConfigFile.\n\nBIS_fnc_kbTell needs a Description.ext **CfgSentences** entry presented as follows:\n\n```cpp\nclass CfgSentences\n{\n    class MissionName\n    {\n        class Event1\n        {\n            file = \"kb\\event1.bikb\";    // mandatory\n            class Sentences\n            {\n                class Sentence1\n                {\n                    // the following arguments are used by BIS_fnc_kbTell (if they are defined, they are not mandatory)\n                    actor = \"obi1\";        // (missionNamespace getVariable actor) speaker variable name (can NOT be \"player\")\n                    variant = \"\";        // used by BIS_fnc_kbTell to define an alternative sentence\n                    variantText = \"\";    // used by BIS_fnc_kbTell to define an alternative sentence\n                };\n                class Sentence2\n                {\n                    actor = \"griev\";\n                };\n                class Sentence3\n                {\n                    actor = \"griev\";\n                };\n            };\n        };\n    };\n};\n```\n\nwith a .bikb file looking like this:\n\n```cpp\nclass Sentences\n{\n    class Sentence1\n    {\n        text = \"$STR_HelloThere\";\n        speech[] = { \"\\Sound\\hello.ogg\" };\n        class Arguments {};\n    };\n    class Sentence2\n    {\n        text = \"$STR_GeneralKenobi\";\n        speech[] = { \"Sound\\gk.ogg\" };\n        class Arguments {};\n    };\n    class Sentence3\n    {\n        text = \"$STR_YouAreABoldOne\";\n        speech[] = { \"Sound\\bold.ogg\" };\n        class Arguments {};\n    };\n};\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nA tidier way of doing so is to put all the needed information in the **.bikb** file:\n\n```cpp\nclass Sentences\n{\n    class Sentence1\n    {\n        text = \"$STR_HelloThere\";\n        speech[] = { \"\\Sound\\hello.ogg\" };\n        class Arguments {};\n        actor = \"obi1\";\n    };\n    class Sentence2\n    {\n        text = \"$STR_GeneralKenobi\";\n        speech[] = { \"Sound\\gk.ogg\" };\n        class Arguments {};\n        actor = \"griev\";\n    };\n    class Sentence3\n    {\n        text = \"$STR_YouAreABoldOne\";\n        speech[] = { \"Sound\\bold.ogg\" };\n        class Arguments {};\n        actor = \"griev\";\n    };\n};\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nAnd to include it via `#include` in Description.ext:\n\n```cpp\nclass CfgSentences\n{\n    class MissionName\n    {\n        class Event1\n        {\n            file = \"kb\\event1.bikb\";\n            #include \"kb\\event1.bikb\" // avoids a double declaration\n        };\n    };\n};\n```\n\n*Et voilà !* All that remains to be done now is to call the discussion like this: `[\"Event1\", \"MissionName\"] call BIS_fnc_kbTell; // note that the topic comes first`;\nthe game will make the defined actors say the lines in the order they were declared. BIS_fnc_kbTell will manage to use kbAddTopic, kbTell and other commands.\n\n> [!IMPORTANT]\n> Please note:\n>\n> - use **class CfgSentences** in Description.ext\n> - use **class Sentences** in .bikb files\n\n### Conversation FSM\n\nAs stated earlier, the **Conversation FSM** fires on sentences **received by an AI** and defines an AI unit's reaction.\nThe Conversation FSM receives the following arguments:\n\n- **_this:** Object - receiver or listener of the sentence. One of the units that had this particular script assigned via kbAddTopic\n- **_from:** Object - the unit that told the sentence\n- **_sentenceId:** String - the sentence this unit is reacting to. Defined in .bikb in class Sentences\n- **_topic:** String - topic name used in kbAddTopic\n\nSee also: FSM, FSM Editor\n\n#### Conversation FSM Example\n\n### Conversation Event Handler\n\nThe **Conversation Event Handler** is code, provided through kbAddTopic, that is executed with each sentence **received by a player**, and will constantly fire (onEachFrame) when the player is pointing at a \"talkable\" person at \"talkable\" range. Following parameters are passed:\n\n- **_this:** Object - the player receiving the sentence. Must have had this particular script assigned via kbAddTopic\n- **_from:** Object - the unit that told the sentence\n- **_sentenceId:** String - the sentence the player is reacting to. Defined in .bikb in class Sentences\n- **_topic:** String - topic name used in kbAddTopic\n\n> [!NOTE]\n> This Conversation Event Handler is **not** an Event Handler as we know them.\n\nIts return value is used to provide the player's available replies; its format is an Array of arrays (or an empty array) that can look like this:\n\n```sqf\n[\n    [\n        localize \"STR_AnswerTitle1\",    // conversation menu's display text\n        \"myTopic\",                        // topic to answer to\n        \"answer1SentenceId\",            // sentence ID\n        []                                // sentence arguments\n    ],\n    [\n        localize \"STR_AnswerTitle2\",\n        \"myTopic\",\n        \"answer2SentenceId\",\n        []\n    ]\n];\n```\n\nThere is a certain resemblance with the kbTell syntax; note that the *forceRadio* parameter is not present.\n\n> [!IMPORTANT]\n> The Conversation Event Handler's code is executed in **unscheduled** environment - be sure to not use sleep or any other Scheduler-incompatible commands.\n\n#### Conversation Event Handler Example\n\n```sqf\n// here we will be storing all the sentences from which the player will choose (left side menu)\n// if there is only one option in the array, the sentence will replace the \"Talk to\" action name\n\nprivate _convMenu = [];\n\n// we want the player to be able to approach his buddy and talk to him via the action menu.\n// we need to check:\n// if the player is pointing at his buddy\n// if the player is not answering any of his buddy's sentences\n// if the player has not told him hello already\n// then we add that array to _convMenu - the parameters are mostly self-explanatory:\n\nif (_from == buddy1 && _sentenceId == \"\" && !(_this kbWasSaid [_from, _topic, \"hello1\", 999999])) then\n{\n    _convMenu pushBack [\"Say hello.\", _topic, \"hello1\", []];\n};\n\n// here we make the unit say the proper sentence based on the one he just received\n// switch-case-do is used here but it is only one solution to manage sentences (if-then etc could do)\n\nswitch (_sentenceId) do\n{\n    case \"hello1\":\n    {\n        _this kbTell [_from, _topic, \"hi_how_are_you\"];\n    };\n    case \"good_you\":\n    {\n        _this kbTell [_from, _topic, \"fine_thanks\"];\n    };\n    case \"what_do_we_do\":\n    {\n        // the player will have 3 answers to choose from:\n        _convMenu pushBack [\"Football.\",    _topic, \"choose_football\",    []];\n        _convMenu pushBack [\"Bike.\",        _topic, \"choose_bike\",        []];\n        _convMenu pushBack [\"Arma 2.\",        _topic, \"choose_arma2\",        []];\n    };\n};\n\n// return the sentence list pool\n_convMenu;\n```\n\n### See Also\n\n- Conversations Command Group\n- Conversations Function Group\n- [Jezuro's introduction forum post](https://forums.bohemia.net/forums/topic/89071-new-conversation-system-how-to/)\n- [HateDread's forum post and Evil_Echo's answers](https://forums.bohemia.net/forums/topic/107662-using-dialogue-system-between-player-and-ai/)\n- FSM\n- FSM Editor","sections":[{"heading":null,"level":1,"markdown":"Arma 2 v1.00 Arma 2: Operation Arrowhead v1.50 Take On Helicopters v1.00 Arma 3 v1.00\n\nConversations is a system created to manage discussions that was introduced in **Arma 2**.\nThis system allows dynamic conversations and a more fluid sentence/answer flow.\n\nIts main advantages are:\n\n- The system itself waits for the sound sample to finish. No more sample time measuring and countless sleeps!\n- Conversation always flows through the appropriate channel (direct for face to face, team radio for distant team members etc.)\n- Possibility to create fully dynamic conversations\n- Transparent syntax (FSM branches allow fast and efficient edits)"},{"heading":"Usage","level":3,"markdown":"- A **topic** is defined by a String for id and sentences defined in a **Conversation .bikb** file\n- A **Conversation .bikb** lists all available sentences in a **topic**\n- A **topic** must be added to the concerned units, with eventually a **Conversation FSM** and/or a **Conversation Event Handler**\n- A **Conversation FSM** defines an **AI unit** reaction to a sentence\n- A **Conversation Event Handler** defines a **player's unit** reaction to a sentence, potentially defining available answers\n- If the unit is playable (can be either player or AI), both should be present to ensure a proper reaction in every encountered scenario."},{"heading":"Commands","level":3,"markdown":"A conversation topic:\n\n1. must be added to units (via kbAddTopic)\n1. for the units to be able use it (via kbTell for example)\n1. once the unit said wanted sentences (checked via kbWasSaid),\n1. the topic can be removed (via kbRemoveTopic).\n\n- Related commands are listed in Conversations Command Group\n- Related functions are listed in Conversations Function Group"},{"heading":"Manual Conversation Example","level":4,"markdown":"```sqf\nmiles    kbAddTopic [\"briefing\", \"kb\\briefing.bikb\"];\nshaftoe    kbAddTopic [\"briefing\", \"kb\\briefing.bikb\"];\n\nshaftoe kbTell [miles, \"briefing\", \"shaftoe_briefing_H_1\"];\nwaitUntil { shaftoe kbWasSaid [miles, \"briefing\", \"shaftoe_briefing_H_1\", 3]; };\n\nmiles kbTell [shaftoe, \"briefing\", \"shaftoe_briefing_M_1\"];\nwaitUntil { miles kbWasSaid [shaftoe, \"briefing\", \"shaftoe_briefing_M_1\", 3]; };\n\nhint \"Conversation ended.\";\n// kbRemoveTopic can be used here to \"clear\" the units if the topic is not required anymore. This is not mandatory.\n```"},{"heading":"Conversation .bikb","level":3,"markdown":"**.bikb** extension stands for \"**B**ohemia **I**nteractive **K**nowledge **B**ase\" as it was originally used only for storing an AI unit's memory of what it has seen.\nThis file declares the available sentences in the topic, their sound samples and the corresponding subtitles (see example 1 and example 2).\nAs the syntax is the same as config files (Description.ext, Config.cpp) PreProcessor Commands can be used.\n\nConversation sounds do **not** need to be defined in CfgSounds or CfgRadio, unless of course they are to be used with e.g playSound, say or groupRadio too.\nAs opposed to these commands, this new conversation system will automatically use setRandomLip during the speech if no .lip file is present. A .lip file can however still be used for a more precise animation.\n\n> [!IMPORTANT]\n> A duplicate sentence in .bikb file **WILL** crash the game!"},{"heading":"\"Interrupted\" Event","level":4,"markdown":"The left-side conversation menu (with the list of possible sentences) can be closed via backspace at all times. In order to handle this event as well, add a sentence class called **Interrupted** into the .bikb file. It can then be used as a standard `_sentenceId` in the script."},{"heading":".bikb Simple Example","level":4,"markdown":"```cpp\nclass Sentences\n{\n    class hello1\n    {\n        text = \"Hello!\";                    // sentence subtitle - can be \"text\" or $STR_ stringtable reference\n        speech[] = { \"\\Sound\\hello1.ogg\" };    // sound file path relative to mission or campaign directory\n        class Arguments {};                    // unused here\n    };\n    class hi_how_are_you\n    {\n        text = \"Hi, how are you?\";\n        speech[] = { \"\\Sound\\hi_how_are_you.ogg\" };\n        class Arguments {};\n    };\n    class good_you\n    {\n        text = \"$STR_GoodYou\"; // has to start with \"STR_\"!\n        speech[] = { \"\\Sound\\good_you.ogg\" };\n        class Arguments {};\n    };\n    class fine_thanks\n    {\n        text = \"$STR_FineThanks\";\n        speech[] = { \"\\Sound\\fine_thanks\" }; // no extension means .wss to the engine\n        class Arguments {};\n    };\n\n    // these sentences are here to be a full example for later Conversation Event Handler example\n    class what_do_we_do        { text = \"What do we do today?\"; speech[] = { \"\\Sound\\wdwd.ogg\" };    class Arguments {}; };\n    class choose_football    { text = \"Let's football!\";         speech[] = { \"\\Sound\\cf.ogg\" };    class Arguments {}; };\n    class choose_bike        { text = \"Let's bike?\";             speech[] = { \"\\Sound\\cb.ogg\" };    class Arguments {}; };\n    class choose_arma2        { text = \"I know! Arma 2\";         speech[] = { \"\\Sound\\ca.ogg\" };    class Arguments {}; };\n\n    // the Interrupted sentence triggered when the conversation menu is closed without answering (e.g using backspace)\n    class Interrupted\n    {\n        text = \"Hey, come back!\";\n        speech[] = { \"\\Sound\\interrupted.ogg\" };\n        class Arguments {};\n    };\n};\n\n// Needed parameters.\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```"},{"heading":".bikb Advanced Example","level":4,"markdown":"See Words configuration and below for more details.\n\n```cpp\nclass Sentences\n{\n    class AirstrikeRequest\n    {\n        // %team and %location will be replaced by the game engine with according values\n        text = \"%team requesting close air support at grid %location \";\n\n        // available words are defined in config > RadioProtocol > Words\n        speech[] = { %Team, RequestingCloseAirSupportAtGrid, %Location };\n\n        class Arguments\n        {\n            class Team { type = \"simple\"; };        // refers to %Team, first element of speech[]\n            // \"RequestingCloseAirSupportAtGrid\" is part of Radio Protocol\n            class Location { type = \"simple\"; };    // refers to %Location, last element of speech[]\n        };\n    };\n};\n\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nAbove sentence would be used this way:\n\n```sqf\nplayer kbTell [\n    BIS_HQ,                                        // to\n    \"Airstrike\",                                // topic\n    \"AirstrikeRequest\",                            // sentence\n    [\"Team\", {}, \"Anvil\", [\"Anvil\"]],            // argument 1\n    [\"Location\", {}, \"Strelka\", [\"Strelka\"]]    // argument 2\n];\n```"},{"heading":".bikb BIS_fnc_kbTell Example","level":4,"markdown":"> [!NOTE]\n> **Arma 3:**\n>\n> ```cpp\n> class Sentences\n> {\n>     class Sentence1\n>     {\n>         text = \"\"; // must be empty\n>         textPlain = \"$STR_MySubTitle\";\n>         /* other parameters */\n>     };\n> };\n> ```\n>\n> **In an addon/mod scope**, an additional subtitle entry is available to have subtitle rendered with BIS_fnc_showSubtitle: `textPlain`, declared as shown.\n> **This is not available for standard missions** as BIS_fnc_kbTellLocal only checks configFile and none of missionConfigFile or campaignConfigFile.\n\nBIS_fnc_kbTell needs a Description.ext **CfgSentences** entry presented as follows:\n\n```cpp\nclass CfgSentences\n{\n    class MissionName\n    {\n        class Event1\n        {\n            file = \"kb\\event1.bikb\";    // mandatory\n            class Sentences\n            {\n                class Sentence1\n                {\n                    // the following arguments are used by BIS_fnc_kbTell (if they are defined, they are not mandatory)\n                    actor = \"obi1\";        // (missionNamespace getVariable actor) speaker variable name (can NOT be \"player\")\n                    variant = \"\";        // used by BIS_fnc_kbTell to define an alternative sentence\n                    variantText = \"\";    // used by BIS_fnc_kbTell to define an alternative sentence\n                };\n                class Sentence2\n                {\n                    actor = \"griev\";\n                };\n                class Sentence3\n                {\n                    actor = \"griev\";\n                };\n            };\n        };\n    };\n};\n```\n\nwith a .bikb file looking like this:\n\n```cpp\nclass Sentences\n{\n    class Sentence1\n    {\n        text = \"$STR_HelloThere\";\n        speech[] = { \"\\Sound\\hello.ogg\" };\n        class Arguments {};\n    };\n    class Sentence2\n    {\n        text = \"$STR_GeneralKenobi\";\n        speech[] = { \"Sound\\gk.ogg\" };\n        class Arguments {};\n    };\n    class Sentence3\n    {\n        text = \"$STR_YouAreABoldOne\";\n        speech[] = { \"Sound\\bold.ogg\" };\n        class Arguments {};\n    };\n};\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nA tidier way of doing so is to put all the needed information in the **.bikb** file:\n\n```cpp\nclass Sentences\n{\n    class Sentence1\n    {\n        text = \"$STR_HelloThere\";\n        speech[] = { \"\\Sound\\hello.ogg\" };\n        class Arguments {};\n        actor = \"obi1\";\n    };\n    class Sentence2\n    {\n        text = \"$STR_GeneralKenobi\";\n        speech[] = { \"Sound\\gk.ogg\" };\n        class Arguments {};\n        actor = \"griev\";\n    };\n    class Sentence3\n    {\n        text = \"$STR_YouAreABoldOne\";\n        speech[] = { \"Sound\\bold.ogg\" };\n        class Arguments {};\n        actor = \"griev\";\n    };\n};\nclass Arguments {};\nclass Special {};\nstartWithVocal[] = { hour };\nstartWithConsonant[] = { europe, university };\n```\n\nAnd to include it via `#include` in Description.ext:\n\n```cpp\nclass CfgSentences\n{\n    class MissionName\n    {\n        class Event1\n        {\n            file = \"kb\\event1.bikb\";\n            #include \"kb\\event1.bikb\" // avoids a double declaration\n        };\n    };\n};\n```\n\n*Et voilà !* All that remains to be done now is to call the discussion like this: `[\"Event1\", \"MissionName\"] call BIS_fnc_kbTell; // note that the topic comes first`;\nthe game will make the defined actors say the lines in the order they were declared. BIS_fnc_kbTell will manage to use kbAddTopic, kbTell and other commands.\n\n> [!IMPORTANT]\n> Please note:\n>\n> - use **class CfgSentences** in Description.ext\n> - use **class Sentences** in .bikb files"},{"heading":"Conversation FSM","level":3,"markdown":"As stated earlier, the **Conversation FSM** fires on sentences **received by an AI** and defines an AI unit's reaction.\nThe Conversation FSM receives the following arguments:\n\n- **_this:** Object - receiver or listener of the sentence. One of the units that had this particular script assigned via kbAddTopic\n- **_from:** Object - the unit that told the sentence\n- **_sentenceId:** String - the sentence this unit is reacting to. Defined in .bikb in class Sentences\n- **_topic:** String - topic name used in kbAddTopic\n\nSee also: FSM, FSM Editor"},{"heading":"Conversation FSM Example","level":4,"markdown":""},{"heading":"Conversation Event Handler","level":3,"markdown":"The **Conversation Event Handler** is code, provided through kbAddTopic, that is executed with each sentence **received by a player**, and will constantly fire (onEachFrame) when the player is pointing at a \"talkable\" person at \"talkable\" range. Following parameters are passed:\n\n- **_this:** Object - the player receiving the sentence. Must have had this particular script assigned via kbAddTopic\n- **_from:** Object - the unit that told the sentence\n- **_sentenceId:** String - the sentence the player is reacting to. Defined in .bikb in class Sentences\n- **_topic:** String - topic name used in kbAddTopic\n\n> [!NOTE]\n> This Conversation Event Handler is **not** an Event Handler as we know them.\n\nIts return value is used to provide the player's available replies; its format is an Array of arrays (or an empty array) that can look like this:\n\n```sqf\n[\n    [\n        localize \"STR_AnswerTitle1\",    // conversation menu's display text\n        \"myTopic\",                        // topic to answer to\n        \"answer1SentenceId\",            // sentence ID\n        []                                // sentence arguments\n    ],\n    [\n        localize \"STR_AnswerTitle2\",\n        \"myTopic\",\n        \"answer2SentenceId\",\n        []\n    ]\n];\n```\n\nThere is a certain resemblance with the kbTell syntax; note that the *forceRadio* parameter is not present.\n\n> [!IMPORTANT]\n> The Conversation Event Handler's code is executed in **unscheduled** environment - be sure to not use sleep or any other Scheduler-incompatible commands."},{"heading":"Conversation Event Handler Example","level":4,"markdown":"```sqf\n// here we will be storing all the sentences from which the player will choose (left side menu)\n// if there is only one option in the array, the sentence will replace the \"Talk to\" action name\n\nprivate _convMenu = [];\n\n// we want the player to be able to approach his buddy and talk to him via the action menu.\n// we need to check:\n// if the player is pointing at his buddy\n// if the player is not answering any of his buddy's sentences\n// if the player has not told him hello already\n// then we add that array to _convMenu - the parameters are mostly self-explanatory:\n\nif (_from == buddy1 && _sentenceId == \"\" && !(_this kbWasSaid [_from, _topic, \"hello1\", 999999])) then\n{\n    _convMenu pushBack [\"Say hello.\", _topic, \"hello1\", []];\n};\n\n// here we make the unit say the proper sentence based on the one he just received\n// switch-case-do is used here but it is only one solution to manage sentences (if-then etc could do)\n\nswitch (_sentenceId) do\n{\n    case \"hello1\":\n    {\n        _this kbTell [_from, _topic, \"hi_how_are_you\"];\n    };\n    case \"good_you\":\n    {\n        _this kbTell [_from, _topic, \"fine_thanks\"];\n    };\n    case \"what_do_we_do\":\n    {\n        // the player will have 3 answers to choose from:\n        _convMenu pushBack [\"Football.\",    _topic, \"choose_football\",    []];\n        _convMenu pushBack [\"Bike.\",        _topic, \"choose_bike\",        []];\n        _convMenu pushBack [\"Arma 2.\",        _topic, \"choose_arma2\",        []];\n    };\n};\n\n// return the sentence list pool\n_convMenu;\n```"},{"heading":"See Also","level":3,"markdown":"- Conversations Command Group\n- Conversations Function Group\n- [Jezuro's introduction forum post](https://forums.bohemia.net/forums/topic/89071-new-conversation-system-how-to/)\n- [HateDread's forum post and Evil_Echo's answers](https://forums.bohemia.net/forums/topic/107662-using-dialogue-system-between-player-and-ai/)\n- FSM\n- FSM Editor"}],"categories":["Introduced with Arma 2 version 1.00","Scripting Topics"],"groups":["Scripting"]}