{"id":1277,"date":"2025-04-03T00:33:31","date_gmt":"2025-04-02T22:33:31","guid":{"rendered":"https:\/\/wesleydegraaf.com\/?page_id=1277"},"modified":"2025-04-29T00:25:13","modified_gmt":"2025-04-28T22:25:13","slug":"econeer","status":"publish","type":"page","link":"https:\/\/wesleydegraaf.com\/en\/econeer\/","title":{"rendered":"Econeer"},"content":{"rendered":"<div class=\"wp-block-cover\" style=\"min-height:280px;aspect-ratio:unset;\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-palette-color-1-background-color has-background-dim-100 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<p class=\"has-text-align-center has-x-large-font-size\"><strong>Econeer<\/strong><\/p>\n<\/div><\/div>\n\n\n\n<figure class=\"wp-block-embed alignright 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=\"Econeer Short Video\" width=\"1290\" height=\"726\" src=\"https:\/\/www.youtube.com\/embed\/3eyJ_QXVv7w?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><\/figure>\n\n\n\n<p>During Project Context II, we worked on a game commissioned by ROM Utrecht. The assignment was to develop a game based on an ecosystem. Econeer is a survival game with a dynamic ecosystem, in which the player takes on the role of a biologist exploring a mysterious island. The goal is to discover the island's unique animals and survive without drastically disrupting the ecosystem. The island reacts to your actions\u2026 Gather data, track animal populations, and try to survive in harmony with nature!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Project Info:<\/mark><\/h4>\n\n\n\n<p>Team members: Jim Dekker, Mitchel Gereadts, Julius Kamphuis, Joey van Gool, Griffin Linckens &amp; Emma Bout<br>Project duration: HKU Year 2, Period 3 (10-02-2025 until 28-03-2025)<br>Engine: Unity<br>Code Languages: C#<br>Design Patterns: Observer, Singleton &amp; FlyWeight<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"591\" data-id=\"1291\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-1024x591.png\" alt=\"\" class=\"wp-image-1291\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-1024x591.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-300x173.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-768x443.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-1536x886.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen3.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" data-id=\"1287\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-1024x576.png\" alt=\"\" class=\"wp-image-1287\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-1024x576.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-300x169.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-768x432.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-1536x865.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen5.png 1917w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"577\" data-id=\"1292\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-1024x577.png\" alt=\"\" class=\"wp-image-1292\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-1024x577.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-300x169.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-768x433.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-1536x865.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen6.png 1915w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" data-id=\"1295\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-1024x576.png\" alt=\"\" class=\"wp-image-1295\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-1024x576.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-300x169.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-768x432.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-1536x864.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen7.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" data-id=\"1293\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-1024x576.png\" alt=\"\" class=\"wp-image-1293\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-1024x576.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-300x169.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-768x432.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-1536x864.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen8.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" data-id=\"1297\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-1024x576.png\" alt=\"\" class=\"wp-image-1297\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-1024x576.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-300x169.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-768x432.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-1536x864.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9-18x10.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/Screen9.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-2-color has-text-color has-link-color wp-elements-34ba8d21f0961f1644c5bc913ce624e0\">Animal GOAP (Goal-Oriented Action Planning)<\/h2>\n\n\n\n<p>GOAP (Goal-Oriented Action Planning) is an AI system in which an agent is given a goal and independently determines which actions are needed to achieve that goal. Instead of following fixed behavior rules, GOAP dynamically generates a plan by analyzing available actions and how they connect. The AI starts with the end goal and works backward to form a sequence of actions that align with each other. Each action has a precondition that must be met (which can be fulfilled by a previous action). The planner searches for the most efficient route while considering the current situation. GOAP is highly flexible compared to traditional AI, as the agent can adapt to changing circumstances without requiring manually scripted scenarios. <\/p>\n\n\n\n<div class=\"dm-code-snippet light dm-normal-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\"line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-clike\"> public Queue&lt;GAction> Plan(List&lt;GAction> actions, Dictionary&lt;string, int> goal, WorldStates beliefstates)\n {\n     List&lt;GAction> useableActions = new List&lt;GAction>();\n     foreach (GAction a in actions)\n     {\n         if (a.IsAchievable()) useableActions.Add(a);\n     }\n\n     List&lt;Node> leaves = new List&lt;Node>();\n     Node start = new Node(null, 0, GWorld.Instance.GetWorld().GetStates(), beliefstates.GetStates(), null);\n\n     bool succes = BuildGraph(start, leaves, useableActions, goal);\n\n     if (!succes) return null;\n\n     Node cheapest = null;\n\n     foreach (Node leaf in leaves)\n     {\n         if (cheapest == null) cheapest = leaf;\n         else\n         {\n             if (leaf.cost &lt; cheapest.cost) cheapest = leaf;\n         }\n     }\n\n     List&lt;GAction> result = new List&lt;GAction>();\n     Node n = cheapest;\n\n     while (n != null)\n     {\n         if (n.action != null)\n         {\n             result.Insert(0, n.action);\n         }\n\n         n = n.parent;\n     }\n\n     Queue&lt;GAction> queue = new Queue&lt;GAction>();\n     result.ForEach(a => queue.Enqueue(a));\n\n     return queue;\n }<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"has-text-align-center\">Creates a plan with all the actions assigned to the animal, attempting to make it as cost-effective as possible.<\/p>\n\n\n\n<div style=\"height:75px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-2-color has-text-color has-link-color wp-elements-4134dd90583c3e28b0b9e88792068b0b\">Animal Script<\/h2>\n\n\n\n<p class=\"has-text-align-left\">The Animals script is the base class for all animals. This class manages functions such as: growing babies, food reduction, and handling pregnancies. The animals themselves have an additional GOAP layer on top. In their specific animal-type script, different animals' goals are defined. Goals include: Wander, Fed, FoundMate, HasBred, and IsSafe. Dynamic goals are also added when necessary. For example, Panic is added when an animal takes damage.<\/p>\n\n\n\n<div class=\"dm-code-snippet light dm-normal-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\"line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-clike\">    private void HandleReproduction()\n    {\n        timeSinceLastMating = Mathf.Max(timeSinceLastMating - TimeTickSystem.ANIMAL_TICK_RATE, 0);\n\n        if (Sex == Sex.Male) EvaluateReproduction();\n\n        if (IsPregnant) UpdatePregnancy();\n    }\n\n    private void EvaluateReproduction()\n    {\n        beliefs.RemoveState(\"canReproduce\");\n\n        if (IsBaby) return;\n        if (timeSinceLastMating > 0) return;\n        if (GetHungerPercentage() &lt; 70) return;\n        if (inventory.FindItemWithKey(\"partner\") != null) return;\n        if (currentAction != null &amp;&amp; currentAction.GetType() == typeof(AFlee)) return;\n\n        beliefs.SetState(\"canReproduce\", 1);\n    }<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"has-text-align-center\">Managing reproduction. This is the male part where it receives the belief \"canReproduce\". Now, through its GOAP, it can make a request to a female.<\/p>\n\n\n\n<div style=\"height:75px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-2-color has-text-color has-link-color wp-elements-d700ef4586e77df94019852e8cdd7dc9\">Inventory System<\/h2>\n\n\n\n<p>The player has a hotbar and the option for a backpack. Currently, the backpack is disabled, meaning the player can only store items in the hotbar. However, the original system was designed to automatically place items in the backpack when the hotbar is full. When the player interacts with an object in the world, the system can query which item the player is currently holding. This is determined by the contents of the hotbar. If the player performs an action that requires a specific item, the system will check if that item is present in the hotbar.<\/p>\n\n\n\n<div class=\"dm-code-snippet light dm-normal-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\"line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-clike\">    public bool AddToInventory(InventoryItemData itemToAdd, int amountToAdd)\n    {\n        \/\/Checks wheter Item exist in inventory.\n        if (ContainsItem(itemToAdd, out List&lt;InventorySlot> invSlot))\n        {\n            foreach (InventorySlot slot in invSlot)\n            {\n                if (slot.RoomLeftInStack(amountToAdd))\n                {\n                    slot.AddToStack(amountToAdd);\n                    OnInventorySlotChanged?.Invoke(slot);\n                    return true;\n                }\n            }\n        }\n\n        \/\/Gets the first available slot.\n        if (HasFreeSlot(out InventorySlot freeSlot))\n        {\n            freeSlot.UpdateInventorySlot(itemToAdd, amountToAdd);\n            OnInventorySlotChanged?.Invoke(freeSlot);\n            return true;\n        }\n\n        return false;\n    }\n\n    public bool ContainsItem(InventoryItemData itemToAdd, out List&lt;InventorySlot> invSlot)\n    {\n        invSlot = inventorySlots.Where(i => i.ItemData == itemToAdd).ToList();\n\n        return invSlot != null;\n    }\n\n    public bool HasFreeSlot(out InventorySlot freeSlot)\n    {\n        freeSlot = inventorySlots.FirstOrDefault(i => i.ItemData == null);\n        return freeSlot != null;\n    }<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"has-text-align-center\">Adding new items and checking available space.<\/p>\n\n\n\n<div style=\"height:75px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<p><iframe loading=\"lazy\" frameborder=\"0\" src=\"https:\/\/itch.io\/embed\/3422390?linkback=true&amp;link_color=02b000\" width=\"552\" height=\"167\"><a href=\"https:\/\/double-gezicht.itch.io\/econeer\">Econeer by Double_Gezicht, Drash1, Jim, seumru, Kampus, manda<\/a><\/iframe><\/p>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Tijdens Project Context II werkten we aan een game in opdracht van ROM Utrecht. De opdracht was om een game te ontwikkelen die gebaseerd is op een ecosysteem. Econeer is een survivalgame met een dynamisch ecosysteem, waarin de speler een bioloog speelt die een mysterieus eiland verkent. Het doel is om de unieke dieren van [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1277","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/comments?post=1277"}],"version-history":[{"count":59,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1277\/revisions"}],"predecessor-version":[{"id":1374,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1277\/revisions\/1374"}],"wp:attachment":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/media?parent=1277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}