{"id":1689,"date":"2021-03-19T23:47:23","date_gmt":"2021-03-19T22:47:23","guid":{"rendered":"https:\/\/lootburnkillrepeat.wordpress.com\/?p=1689"},"modified":"2023-12-25T13:44:41","modified_gmt":"2023-12-25T13:44:41","slug":"demox-3-ai","status":"publish","type":"post","link":"https:\/\/crumblingsoftware.net\/index.php\/2021\/03\/19\/demox-3-ai\/","title":{"rendered":"Demox AI #1"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote has-white-color has-text-color has-background has-link-color has-small-font-size wp-elements-b31feafcfd1f47475ef5e6d486aa1792 is-layout-flow wp-block-quote-is-layout-flow\" style=\"background-color:#645449;font-style:italic;font-weight:600\">\n<p>Note!<\/p>\n\n\n\n<p><\/p>\n<cite>This article is part of the, now deprecated, Demox development log. Demox was cancelled and is no longer in active development so this article can be somewhat out of context- however, I felt some information here could still be of use to someone, therefore it&#8217;ll remain for anyone to read.<\/cite><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">.Factions<\/h2>\n\n\n\n<p>So to start things off, let&#8217;s go through my primary goals for the AI in <strong><em>Demox<\/em><\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-02a3e8c6d1a1135b0ddb22ab3d7f77d0\">&#8211; A game world that feel more alive than <em><strong><a href=\"https:\/\/lootburnkillrepeat.wordpress.com\/om-2\/\">LBKR <\/a><\/strong><\/em>did, this includes AI that show more presence and that interact with the player, game world and eachother alot more than what the AI in <strong><em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">LBKR <\/span><\/em><\/strong>did. ( <span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-cyan-blue-color\"><em>AI in LBKR were idiots really, let&#8217;s be honest \ud83d\ude09<\/em> <\/span>)<br>&#8211; Possability for the player to hire friendly AI to accompany him into battle.<br>&#8211; Maintain <strong><em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-cyan-blue-color\">LBKR&#8217;s<\/span> <\/em><\/strong>style of &#8220;<strong><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">DPM<\/span><\/strong>&#8221; intelligence to allow making some AI more alert and some more sluggish-acting, more on this subject later!<br>&#8211; Simple setup, with a way of dynamically adding\/removing <em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">decision behaviour<\/span> types<\/em> to different enemies.<br>&#8211; <em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">Situational Awareness<\/span><\/em> in combat aswell as AI <em>cooperation<\/em><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-gallery has-nested-images columns-3 wp-block-gallery-1 wp-container-content-29dca9c1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d9fc83d0e18&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"69d9fc83d0e18\" class=\"wp-block-image size-thumbnail wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" data-id=\"2515\" src=\"https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/a_aicoop1-150x150.webp\" alt=\"\" class=\"wp-image-2515\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d9fc83d1270&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"69d9fc83d1270\" class=\"wp-block-image size-thumbnail wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" data-id=\"2516\" src=\"https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/a_aicoop3-150x150.webp\" alt=\"\" class=\"wp-image-2516\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/figure>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">.DPM<\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"has-text-align-left has-cyan-bluish-gray-color has-black-background-color has-text-color has-background has-link-color wp-elements-cbfe1fd07ef2598429f2fd27851d6781\"><strong>AI Status Check<\/strong><br><em>&#8211; Are there any active damage effects?<br>&#8211; Have the AI depleted all resources such as weapons or energy?<br>&#8211; How much health has been lost and how intact is the AI&#8217;s armor?<br>&#8211; What is the distance between the AI and it&#8217;s current target? <\/em><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p><strong><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">DPM<\/span><\/strong>, or &#8220;<em>Decisions per Minute<\/em>&#8221; is a simple AI behaviour system I put together for<em> <\/em><a href=\"https:\/\/crumblingsoftware.net\/index.php\/projects\/lootburnkillrepeat\/\" data-type=\"page\" data-id=\"843\"><strong>Loot Burn Kill Repeat<\/strong><\/a>, which I have continued to build upon for <strong><em>Demox <\/em><\/strong>aswell! The name comes from a property field I&#8217;ve assigned to the AI character code that determine how many times per minute the AI avatar will calculate a new decision, I guess a less confusing name for it would be &#8220;Intelligence&#8221;&#8230; but&#8230; err, yeah!<\/p>\n\n\n\n<p>Worth to note is that despite the AI calculating a decision at regular intervals, the process won&#8217;t always end with the AI actually deciding or changing any current actions, since the decision is controlled by multiple aspects concerning the current situation of the AI. I&#8217;ve improved the AI&#8217;s situational awareness and the <strong><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">DPM <\/span><\/strong>system extensively for <strong><em>Demox<\/em><\/strong>, compared to what I had in <strong><a href=\"https:\/\/lootburnkillrepeat.wordpress.com\/om-2\/\">LBKR<\/a><\/strong>. Among other things, the AI will check it&#8217;s own status, <\/p>\n<\/div>\n<\/div>\n\n\n\n<p>A check will also be done for the AI&#8217;s party members, to determine how many are wounded, escaped combat, have been killed and how scattered the party members are on the battlefield. These are the primary things that are impacting the decision, furthermore, each <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">decision behaviour<\/span><\/em> have tailor-made awareness checks.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ai alarming\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/wmruU9CiSho?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\"><em><span class=\"has-inline-color has-luminous-vivid-amber-color\">AI triggering an alarm, decided with the AI decision behaviour system.<\/span><\/em><\/figcaption><\/figure>\n\n\n\n<p>To describe what these &#8220;<em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">decision behaviours<\/span><\/em>&#8221; are, they are basicly <em>instructions <\/em>for the AI how to determine if the behaviour should be used, aswell as how it is to be executed by the AI. The instructions include simple things like escaping combat, changing target, changing position during combat aswell as more complicated tasks such as triggering traps and alarms, or aiding party members.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">.DPBS<\/h3>\n\n\n\n<p>When improving the AI awareness there were, as with everything else, some issues to solve, first and foremost- how would I make the AI select the most appropriate action? This morphed my old <span class=\"has-inline-color has-luminous-vivid-orange-color\"><strong>DPM <\/strong><\/span>system into what I now call <strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">DPBS<\/span><\/strong>, or <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">Decision Point Behaviour System<\/span><\/em>. And yes, again, why not just call it &#8220;<em>Intelligence<\/em>&#8220;? &#8230; I&#8217;m a hopeless case&#8230;<br>When the AI is calculating a decision, all <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">decision behaviours<\/span><\/em> are iterated and compared with each others. They are individually scored depending on the current situation and the best scored behaviour will be selected at the end of the process.<\/p>\n\n\n\n<p>Below is an example from one of the implemented <em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">decision behaviours<\/span><\/em>, multiple aspects of the current situation are checked and affects the score of the decision before said score is sent back to the member calculating the AI&#8217;s decision.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><em><span class=\"has-inline-color has-vivid-green-cyan-color\">\/\/\/&lt;summary&gt;\n\/\/\/<\/span><\/em><strong><span class=\"has-inline-color has-vivid-green-cyan-color\"> Gets the current score of this decision\n<\/span><\/strong><em><span class=\"has-inline-color has-vivid-green-cyan-color\">\/\/\/&lt;\/summary&gt;\n\/\/\/&lt;returns&gt;<\/span><\/em><strong><span class=\"has-inline-color has-vivid-green-cyan-color\">The score.<\/span><\/strong><em><span class=\"has-inline-color has-vivid-green-cyan-color\">&lt;\/returns&gt;\n\/\/\/&lt;param name=\"agent\"&gt;<\/span><\/em><strong><span class=\"has-inline-color has-vivid-green-cyan-color\">Agent Reference.<\/span><\/strong><em><span class=\"has-inline-color has-vivid-green-cyan-color\">&lt;\/param&gt;<\/span>\n<\/em><strong>public override <\/strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>int<\/strong> <\/span>GetScore<strong>(<\/strong> <span class=\"has-inline-color has-vivid-red-color\">CombatAgent <\/span><span class=\"has-inline-color has-luminous-vivid-orange-color\">agent <\/span><strong>){\n    <\/strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>int<\/strong> <\/span>score = <strong>0<\/strong>;\n\n    if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.CurHealth <strong>&gt; (<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.stats.health * .<strong>5f ) || <\/strong>Time.time - <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.alarmAgent.LastEscape <strong>&lt;<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.alarmAgent.minEscapeDelay <strong>){\n        <\/strong><span class=\"has-inline-color has-vivid-red-color\"><em><strong>return<\/strong><\/em> <\/span>ImpossibleScore;   <span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>\/\/If the AI is comfortable with it's current health value, or we recently escaped, return a score that prohibits the AI from chosing this decision<\/strong><\/span>\n    <strong>}\n\n<\/strong>    if<strong>( !<\/strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.canAttack <strong>){\n<\/strong>        <span class=\"has-inline-color has-luminous-vivid-orange-color\">score <\/span>+= <strong>5<\/strong>;    <span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>\/\/If AI is unable to engage in combat, increase score<\/strong><\/span>\n    <strong>}\n\n<\/strong>    if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.CurHealth <strong>&lt; (<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.stats.health * .<strong>5f )){\n<\/strong>        <span class=\"has-inline-color has-luminous-vivid-orange-color\">score<\/span>++;    <span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>\/\/If AI health is less than half of max health value, increase score<\/strong><\/span>\n\n        if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.party<strong> !<\/strong>= <em><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>null<\/strong><\/span><\/em><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"> <\/span>){\n            for( <\/strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>int<\/strong> <\/span>i = <strong>0<\/strong>; i <strong>&lt;<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.party.Length; i++ <strong>){\n<\/strong>                if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.party<strong>[<\/strong>i<strong>]<\/strong>.IsDead <strong>){<\/strong>\n                    <span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>\/\/For each member of the AI's party who has died, either increase score, or decrease it. (Enemies should be able to be enraged by their friends dying)<\/strong><\/span><strong>\n<\/strong>                    <span class=\"has-inline-color has-luminous-vivid-orange-color\">score <\/span>+= Random.Range<strong>(<\/strong> -<strong>1<\/strong>, <strong>1 )<\/strong>;\n                <strong>}\n            }\n        }\n    }\n\n<\/strong>    if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.targetDistance <strong>&lt;<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.safeDistance.Sqr<strong>() ){\n<\/strong>        if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.CurHealth <strong>&lt; (<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.stats.health * .<strong>35f )){\n<\/strong>            <span class=\"has-inline-color has-luminous-vivid-orange-color\">score <\/span>+= Random.Range<strong>( 0<\/strong>, <strong>1 )<\/strong>;   <span class=\"has-inline-color has-vivid-green-cyan-color\"> <strong>\/\/If at unsafe distance from target, increase score<\/strong><\/span><strong>\n        }\n\n<\/strong>        if<strong>(<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.CurHealth <strong>&lt; (<\/strong> <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.stats.health * .<strong>2f )){\n<\/strong>            <span class=\"has-inline-color has-luminous-vivid-orange-color\">score <\/span>+= Random.Range<strong>( 0<\/strong>, <strong>2 )<\/strong>;    <strong><span class=\"has-inline-color has-vivid-green-cyan-color\">\/\/If health value is critically low, increase score<\/span>\n        }\n    }\n\n<\/strong>    if<strong>(<\/strong> Time.time - <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.LastDmgReceived <strong>&lt;<\/strong>= <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.DpmThreshold &amp;&amp; <span class=\"has-inline-color has-luminous-vivid-orange-color\">agent<\/span>.main.CurHealth <strong>&lt;<\/strong> .<strong>4f){\n<\/strong>        <span class=\"has-inline-color has-luminous-vivid-orange-color\">score <\/span>+= Random.Range<strong>( 0<\/strong>, <strong>1 )<\/strong>;   <strong><span class=\"has-inline-color has-vivid-green-cyan-color\">\/\/If at relatively low health and recently received damage, increase score<\/span><\/strong>\n    <strong>}\n\n    <\/strong><span class=\"has-inline-color has-vivid-red-color\"><em><strong>return<\/strong><\/em> <\/span><span class=\"has-inline-color has-luminous-vivid-orange-color\">score<\/span>;    <strong><span class=\"has-inline-color has-vivid-green-cyan-color\">\/\/Return calculated score.<\/span><\/strong>\n<strong>}<\/strong><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/lootburnkillrepeat.files.wordpress.com\/2021\/02\/a_setup.png?w=1024\" alt=\"\" class=\"wp-image-1703\"\/><figcaption class=\"wp-element-caption\"><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\"><em>Decision behaviours<\/em> available can be customized for each AI character from the editor, since not all characters will have the same options nor priorities.<\/span><\/figcaption><\/figure>\n\n\n\n<p>This improved handling of AI awareness also helped me improve the AI attack system, which has been created in a very similar fashion. To give an example, in <strong><a href=\"https:\/\/crumblingsoftware.net\/index.php\/projects\/lootburnkillrepeat\/\" data-type=\"page\" data-id=\"843\">LBKR <\/a><\/strong>enemies would always attack the player with the most powerful attack that was not in cooldown, they would take no regard to the distance to the player and only checked their maximum attack range to determine if they could not possibly hit the player.<\/p>\n\n\n\n<p>This created a weird behaviour though where AI&#8217;s with ranged attacks would fire at the player from point-blank range alot. With <em><span class=\"has-inline-color has-luminous-vivid-orange-color\">DPBS <\/span><\/em>I&#8217;ve implemented a &#8216;<strong><em>Reposition<\/em><\/strong>&#8216;-behaviour that will determine if the AI is at the most appropriate distance from the player, taking in considering a whole lot of properties ranging from current situation as described above, aswell as presets of what ranges the AI is most and least comfortable with aswell as check if they have a clear line of sight to their target. Hence, the AI will adapt their position continuously.<\/p>\n\n\n\n<p>This alone didn&#8217;t solve the point-blank ranged attack issue described though, since the AI only make use of the <em><span class=\"has-inline-color has-vivid-cyan-blue-color\">Decision Behaviours<\/span><\/em> at certain intervals. But as I structured the attack system similar I, among other things, added attack range limits and preferences for each AI attack to prevent them from beeing used in certain situations. Also all AI with ranged attacks have a minimum of one melee-attack to allow the AI to attack in close quarters if repositioning is not possible.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">.Party interaction <\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>All AI in the game belong to a party, the sizes of each party differ from each other, some contain only two characters while another party can contain 10 &#8211; 20 party members. The AI party is used primarily for the AI to be able to interact with eachother, as described in the topic above, <strong><em><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">DBPS<\/span><\/em><\/strong>, AI party status is checked when making decisions, how dependant a decision behaviour is of the AI&#8217;s party is different for each behaviour, also how an action from a decision behaviour is performed can be modified by the status of the AI&#8217;s party. <\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69d9fc83d1de7&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"69d9fc83d1de7\" class=\"wp-block-image size-medium wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"169\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/gp_aicoop4-300x169.webp\" alt=\"\" class=\"wp-image-2517\" srcset=\"https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/gp_aicoop4-300x169.webp 300w, https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/gp_aicoop4-768x432.webp 768w, https:\/\/crumblingsoftware.net\/wp-content\/uploads\/2023\/12\/gp_aicoop4.webp 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Take the &#8220;<em>Escape<\/em>&#8221; behaviour for example, if the AI for some reason become scared and decides to break contact his action can be either to run away and try to hide, or if the AI know about nearby party members who are not in combat, the character will escape to those party members and rally them, then returns to the battle with his fetched friends.<\/p>\n\n\n\n<p>The combat role assigned to the AI also determine how much it will interact with it&#8217;s party, the roles I&#8217;ve currently implemented are classed as &#8220;<em>Assault<\/em>&#8220;, &#8220;<em>Ranger<\/em>&#8220;, &#8220;<em>Support<\/em>&#8221; and &#8220;<em>Berserk<\/em>&#8220;. <em>Assault <\/em>characters will most commonly only use the party to find AI to help them when they&#8217;re in trouble, ranger&#8217;s will be more bold when Assaulters are nearby. <em>Support <\/em>are generally the most party-fixated characters, they will keep a close eye on it&#8217;s party members to know if they require their attention, eg. resurrection or healing of a party member, or summoning new minions. <em>Berserkers <\/em>pay least attention to it&#8217;s party, they are focused entirely on destroying their enemy.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ai combatRoles\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/LUpbLz0JvGw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\"><em><span class=\"has-inline-color has-luminous-vivid-amber-color\">Combat roles in action- Support classed Bone Wizard (Staff-carrying guy) focus on resurrecting and healing his party, while the Rangers and Assaulters engage the player<\/span><\/em><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"eGameplay\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/6-X9WHT8Q_s?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\"><em><span class=\"has-inline-color has-luminous-vivid-amber-color\">Example of a hybrid-class, the <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>Corpse Warden<\/strong><\/span><span class=\"has-inline-color has-luminous-vivid-amber-color\"> is a mix of Berserker and support, agressively attacking it&#8217;s opponents but if needed it will prioritize resurrecting and aiding it&#8217;s party members<\/span><\/em><\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Going through design ideas, concepts and execution of the AI for the cancelled game &#8220;Demox&#8221;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_share_on_mastodon":"0"},"categories":[105],"tags":[108,31],"class_list":["post-1689","post","type-post","status-publish","format-standard","hentry","category-design-scribbles","tag-dev-blog","tag-development"],"share_on_mastodon":{"url":"","error":""},"_links":{"self":[{"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/posts\/1689","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/comments?post=1689"}],"version-history":[{"count":2,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/posts\/1689\/revisions"}],"predecessor-version":[{"id":2519,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/posts\/1689\/revisions\/2519"}],"wp:attachment":[{"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/media?parent=1689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/categories?post=1689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/crumblingsoftware.net\/index.php\/wp-json\/wp\/v2\/tags?post=1689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}