{"author_link":"\/users\/python-b5","author_name":"python-b5","author_uid":"python-b5","comments":[],"epoch":1633643230,"event":"LD49","format":"md","ldjam_node_id":273664,"likes":10,"metadata":{"p_key":"161534","p_author":"python-b5","p_authorkey":"1259103","p_urlkey":"384524","p_title":"A Gift in Good Faith - Minotaur AI Breakdown","p_cat":"LDJam ","p_event":"LD49","p_time":"1633643230","p_likes":"10","p_comments":"0","p_status":"WAYBACK","us_key":"1259103","us_name":"LDJam user 259103","us_username":"259103","event_start":"1633046400","event_key":"119","event_name":"Ludum Dare 49"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD49","removed_author":false},"_superparent":258323,"_trust":1,"author":259103,"body":"![hEbC3z.png](\/\/\/raw\/f14\/f3\/z\/47c05.png)\n\nA Gift in Good Faith was our first game to really implement AI, so it was my first experience making it. In this post, I\u2019ll walk you through how the AI for the Minotaur in the game works.\n\n![1.gif](\/\/\/raw\/f14\/f3\/z\/47c1a.gif)\n\nGameMaker Studio 2 has built-in pathfinding, so that aspect was sorted already. However, the way it works is a little strange: GameMaker has assets called \u201cpaths\u201d, which are lines from point A to point B with various turns on the way. The built-in pathfinding outputted a single path to use. Unfortunately, this wouldn\u2019t work if I wanted to have the Minotaur constantly follow the player, as since each path started and stopped individually, it would quickly fall out-of-date once the player moved.\n\nThe solution to this problem seemed simple; I could just recalculate the Minotaur\u2019s path every frame so it always tracked the player\u2019s current position. However, this created a strange effect in the movement - see if you can spot it:\n\n![2.gif](\/\/\/raw\/f14\/f3\/z\/47c1b.gif)\n\nIt\u2019s very distracting and looks off. The solution wasn\u2019t too difficult, though. To explain it, I\u2019ll first have to explain how the map is parsed by the Minotaur.\n\nGameMaker doesn\u2019t automatically let you pathfind around tiles; it makes you input \u201ccells\u201d first, which are points on a grid. I decided that my cells would be 2x2 tiles wide, as it feels much less cramped when playing.\n\nThese cells could be automatically created, but only for objects. This posed a problem, as I was using tiles for this game. My solution was to automatically generate instances based on the tiles:\n\n![3.gif](\/\/\/raw\/f14\/f3\/z\/47c0e.gif)\n\nThe opaque tiles are cells the Minotaur has decided are walls (so ones with any amount of tiles), and the transparent ones are marked as \u201csafe\u201d. The latter was necessary to implement for the solution to the strange movement.\n\nBy the way, cells not filled with wall tiles being seen as walls by the Minotaur can lead to fun moments like this:\n\n![4.gif](\/\/\/raw\/f14\/f3\/z\/47c0f.gif)\n\nAnyway, the solution to the strange movement was to only recalculate the Minotaur\u2019s path when the player steps on a new \u201csafe\u201d cell. The Minotaur would then pathfind to the center of that cell, ensuring it doesn\u2019t try to move off its grid. This eliminated the movement bugs.\n\nNext up was to add the flares, which work fairly simply. If a flare is on the ground, the Minotaur will pathfind to it instead of the player, and wait there for 10 seconds. The game also has support for multiple flares, as originally, you were going to have multiple. This came in handy for the player\u2019s other main ability.\n\n![5.gif](\/\/\/raw\/f14\/f3\/z\/47c10.gif)\n\nPushing the minotaur away (or the \"shockwave\", as it was called internally) actually uses the flare code. When used, it places an invisible flare a few tiles behind the Minotaur, causing it to pathfind to it. This \u201cflare\u201d only lasts 3 seconds, and is not collectable upon being dropped. Reusing this code rapidly sped up development, and was responsible for this mechanic being in the game at all.\n\n![6.gif](\/\/\/raw\/f14\/f3\/z\/47c14.gif)\n\nThat\u2019s my breakdown of A Gift in Good Faith\u2019s AI! The Minotaur, being the first complex enemy AI I\u2019ve had to code, was a new experience for me, and it's been very interesting to learn how this side of game development works.\n\nI hope you enjoyed the post, and if you haven\u2019t already, you can play the game here: https:\/\/ldjam.com\/events\/ludum-dare\/49\/a-gift-in-good-faith\n\n![47221.png](\/\/\/raw\/f14\/f3\/z\/47c1d.png)\n\nThanks for reading! :)","comments":2,"comments-timestamp":"2021-10-07T22:01:21Z","created":"2021-10-07T21:14:50Z","files":[],"files-timestamp":0,"id":273664,"love":10,"love-timestamp":"2021-10-10T01:03:42Z","meta":[],"modified":"2021-10-10T01:03:42Z","name":"A Gift in Good Faith - Minotaur AI Breakdown","node-timestamp":"2021-10-08T19:43:48Z","parent":267498,"parents":[1,5,9,258323,267498],"path":"\/events\/ludum-dare\/49\/a-gift-in-good-faith\/a-gift-in-good-faith-minotaur-ai-breakdown","published":"2021-10-07T21:47:10Z","scope":"public","slug":"a-gift-in-good-faith-minotaur-ai-breakdown","subsubtype":"","subtype":"","type":"post","version":846315},"node_metadata":{"n_key":"273664","n_urlkey":"384524","n_parent":"267498","n_path":"\/events\/ludum-dare\/49\/a-gift-in-good-faith\/a-gift-in-good-faith-minotaur-ai-breakdown","n_slug":"a-gift-in-good-faith-minotaur-ai","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"259103","n_created":"1633641290","n_modified":"1633827822","n_version":"846315","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/49\/a-gift-in-good-faith\/a-gift-in-good-faith-minotaur-ai-breakdown","text":"![hEbC3z.png](\/\/\/raw\/f14\/f3\/z\/47c05.png)\n\nA Gift in Good Faith was our first game to really implement AI, so it was my first experience making it. In this post, I\u2019ll walk you through how the AI for the Minotaur in the game works.\n\n![1.gif](\/\/\/raw\/f14\/f3\/z\/47c1a.gif)\n\nGameMaker Studio 2 has built-in pathfinding, so that aspect was sorted already. However, the way it works is a little strange: GameMaker has assets called \u201cpaths\u201d, which are lines from point A to point B with various turns on the way. The built-in pathfinding outputted a single path to use. Unfortunately, this wouldn\u2019t work if I wanted to have the Minotaur constantly follow the player, as since each path started and stopped individually, it would quickly fall out-of-date once the player moved.\n\nThe solution to this problem seemed simple; I could just recalculate the Minotaur\u2019s path every frame so it always tracked the player\u2019s current position. However, this created a strange effect in the movement - see if you can spot it:\n\n![2.gif](\/\/\/raw\/f14\/f3\/z\/47c1b.gif)\n\nIt\u2019s very distracting and looks off. The solution wasn\u2019t too difficult, though. To explain it, I\u2019ll first have to explain how the map is parsed by the Minotaur.\n\nGameMaker doesn\u2019t automatically let you pathfind around tiles; it makes you input \u201ccells\u201d first, which are points on a grid. I decided that my cells would be 2x2 tiles wide, as it feels much less cramped when playing.\n\nThese cells could be automatically created, but only for objects. This posed a problem, as I was using tiles for this game. My solution was to automatically generate instances based on the tiles:\n\n![3.gif](\/\/\/raw\/f14\/f3\/z\/47c0e.gif)\n\nThe opaque tiles are cells the Minotaur has decided are walls (so ones with any amount of tiles), and the transparent ones are marked as \u201csafe\u201d. The latter was necessary to implement for the solution to the strange movement.\n\nBy the way, cells not filled with wall tiles being seen as walls by the Minotaur can lead to fun moments like this:\n\n![4.gif](\/\/\/raw\/f14\/f3\/z\/47c0f.gif)\n\nAnyway, the solution to the strange movement was to only recalculate the Minotaur\u2019s path when the player steps on a new \u201csafe\u201d cell. The Minotaur would then pathfind to the center of that cell, ensuring it doesn\u2019t try to move off its grid. This eliminated the movement bugs.\n\nNext up was to add the flares, which work fairly simply. If a flare is on the ground, the Minotaur will pathfind to it instead of the player, and wait there for 10 seconds. The game also has support for multiple flares, as originally, you were going to have multiple. This came in handy for the player\u2019s other main ability.\n\n![5.gif](\/\/\/raw\/f14\/f3\/z\/47c10.gif)\n\nPushing the minotaur away (or the \"shockwave\", as it was called internally) actually uses the flare code. When used, it places an invisible flare a few tiles behind the Minotaur, causing it to pathfind to it. This \u201cflare\u201d only lasts 3 seconds, and is not collectable upon being dropped. Reusing this code rapidly sped up development, and was responsible for this mechanic being in the game at all.\n\n![6.gif](\/\/\/raw\/f14\/f3\/z\/47c14.gif)\n\nThat\u2019s my breakdown of A Gift in Good Faith\u2019s AI! The Minotaur, being the first complex enemy AI I\u2019ve had to code, was a new experience for me, and it's been very interesting to learn how this side of game development works.\n\nI hope you enjoyed the post, and if you haven\u2019t already, you can play the game here: https:\/\/ldjam.com\/events\/ludum-dare\/49\/a-gift-in-good-faith\n\n![47221.png](\/\/\/raw\/f14\/f3\/z\/47c1d.png)\n\nThanks for reading! :)","title":"A Gift in Good Faith - Minotaur AI Breakdown","wayback_source":[]}