diff --git a/.idea/.idea.Unity_AIBehavioursPackage/.idea/.gitignore b/.idea/.idea.Unity_AIBehavioursPackage/.idea/.gitignore
new file mode 100644
index 0000000..d88b1e4
--- /dev/null
+++ b/.idea/.idea.Unity_AIBehavioursPackage/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/modules.xml
+/contentModel.xml
+/.idea.Unity_AIBehavioursPackage.iml
+/projectSettingsUpdater.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.Unity_AIBehavioursPackage/.idea/indexLayout.xml b/.idea/.idea.Unity_AIBehavioursPackage/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.Unity_AIBehavioursPackage/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Unity_AIBehavioursPackage/.idea/vcs.xml b/.idea/.idea.Unity_AIBehavioursPackage/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/.idea.Unity_AIBehavioursPackage/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/com.gamedeveducation.aibehaviours/Runtime/CommonCore/GameDebugger/Scripts/AIDebuggerCustomEditor.cs b/Assets/com.gamedeveducation.aibehaviours/Runtime/CommonCore/GameDebugger/Scripts/AIDebuggerCustomEditor.cs
new file mode 100644
index 0000000..8d70d2d
--- /dev/null
+++ b/Assets/com.gamedeveducation.aibehaviours/Runtime/CommonCore/GameDebugger/Scripts/AIDebuggerCustomEditor.cs
@@ -0,0 +1,226 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+using UnityEngine.Events;
+
+
+// notes: derived from https://docs.unity3d.com/Manual/UIE-HowTo-CreateEditorWindow.html
+
+namespace CommonCore
+{
+ public class AIDebuggerCustomEditor : EditorWindow, IGameDebugger
+ {
+ [SerializeField] string IndentString = " ";
+ [SerializeField] UnityEvent OnPopulateUI_SelectedObjectName = new();
+ [SerializeField] UnityEvent OnPopulateUI_DebugText = new();
+
+ [SerializeField] private int m_SelectedIndex = -1;
+ private VisualElement m_RightPane;
+
+
+ List Sources = new(); // AI Agents available in scene
+
+ // currently selected AI debugging data
+ int CurrentSourceIndex = -1;
+ IDebuggableObject CurrentSource => ((CurrentSourceIndex < 0) || (CurrentSourceIndex >= Sources.Count)) ? null : Sources[CurrentSourceIndex];
+
+ System.Text.StringBuilder DebugTextBuilder = new();
+ int IndentLevel = 0;
+
+
+ public static AIDebuggerCustomEditor Instance
+ {
+ get { return GetWindow< AIDebuggerCustomEditor >(); }
+ }
+
+
+ [MenuItem("Tools/AI Debugger")]
+ public static void ShowMyEditor()
+ {
+ // This method is called when the user selects the menu item in the Editor
+ EditorWindow wnd = GetWindow();
+ wnd.titleContent = new GUIContent("AI Debugger");
+ }
+
+
+ void Update()
+ {
+ RefreshUI();
+ }
+
+
+ public void CreateGUI()
+ {
+ // Create a two-pane view with the left pane being fixed width
+ var splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal);
+
+ // Add the panel to the visual tree by adding it as a child to the root element
+ rootVisualElement.Add(splitView);
+
+ // A TwoPaneSplitView always needs exactly two child elements
+ var leftPane = new ListView();
+ splitView.Add(leftPane);
+ m_RightPane = new ScrollView(ScrollViewMode.VerticalAndHorizontal);
+ splitView.Add(m_RightPane);
+
+ // Initialize the list view with all the AI-Agent names
+ leftPane.makeItem = () => new Label();
+ leftPane.bindItem = (item, index) => { (item as Label).text = Sources[index].DebugDisplayName; };
+ leftPane.itemsSource = Sources;
+
+ // React to the user's selection
+ //leftPane.selectionChanged += OnAISourceSelectionChange(leftPane.selectedIndex);
+ leftPane.selectedIndicesChanged += OnSelectedIndicesChange;
+
+ // Restore the selection index from before the hot reload
+ leftPane.selectedIndex = m_SelectedIndex;
+
+ // Store the selection index when the selection changes
+ leftPane.selectionChanged += (items) => { m_SelectedIndex = leftPane.selectedIndex; };
+
+ }
+
+ void RefreshUI()
+ {
+ // Clear all previous content from the pane
+ m_RightPane.Clear();
+
+ // remove any nulls
+ for (int Index = Sources.Count - 1; Index >= 0; Index--)
+ {
+ if (Sources[Index] == null)
+ {
+ Sources.RemoveAt(Index);
+
+ if (Index == CurrentSourceIndex)
+ CurrentSourceIndex = -1;
+ }
+ }
+
+ if ((CurrentSource == null) && (Sources.Count == 0))
+ CurrentSourceIndex = 0;
+
+ if (CurrentSource == null)
+ {
+ OnPopulateUI_SelectedObjectName.Invoke("No Sources");
+ OnPopulateUI_DebugText.Invoke("");
+ return;
+ }
+
+ OnPopulateUI_SelectedObjectName.Invoke(CurrentSource.DebugDisplayName);
+
+ // gather the debug data
+ var PrimarySource = CurrentSource;
+ DebugTextBuilder.Clear();
+
+ foreach (var Source in Sources)
+ {
+ Source.GatherDebugData(this, Source == PrimarySource);
+ }
+
+ var debugInformationLabel = new Label();
+ debugInformationLabel.text = DebugTextBuilder.ToString();
+ // Add the label control to the right-hand pane
+ m_RightPane.Add(debugInformationLabel);
+ }
+
+
+
+ private void OnSelectedIndicesChange(IEnumerable selectedItemIndex)
+ {
+ CurrentSourceIndex = selectedItemIndex.First();
+ // regenerate editor panel label with debug text contained within
+ RefreshUI();
+ }
+
+
+ // private void OnAISourceSelectionChange(IEnumerable