diff --git a/.gitignore b/.gitignore
index c301ca8..bb88804 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,37 +1,37 @@
-# Godot 4.x
-.godot/
-.idea/
-sdk/
-bin/
-obj/
-
-#ai
-.omo/
-.opencode/
-
-gen/
-obj/
-bin/
-
-*.tres~
-*.tscn~
-
-# GDScript LSP
-.godot/
-
-# Export
-*.exe
-*.dmg
-*.apk
-*.aab
-*.pck
-*.zip
-*.log
-
-# OS
-.DS_Store
-Thumbs.db
-
-# Editor
-*.import
-*.godot.uid
+# Godot 4.x
+.godot/
+.idea/
+sdk/
+bin/
+obj/
+
+#ai
+.omo/
+.opencode/
+
+gen/
+obj/
+bin/
+
+*.tres~
+*.tscn~
+
+# GDScript LSP
+.godot/
+
+# Export
+*.exe
+*.dmg
+*.apk
+*.aab
+*.pck
+*.zip
+*.log
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Editor
+*.import
+*.godot.uid
diff --git a/src/IRecruitBehaviour.cs b/src/IRecruitBehaviour.cs
index 12e89b3..101cf97 100644
--- a/src/IRecruitBehaviour.cs
+++ b/src/IRecruitBehaviour.cs
@@ -1,48 +1,48 @@
-using Cthangover.Core.Settings;
-
-namespace Cthangover.Core.Relationship
-{
- ///
- /// Per-recruit behaviour plugin discovered via reflection from mod
- /// assemblies. Each implementation is registered into
- /// by
- /// and then
- /// invoked for every active recruit — not just those from the
- /// owning mod — during tick, configure, and removal lifecycle events.
- ///
- /// This cross-recruit dispatch pattern is intentional: a behaviour
- /// might want to introspect all recruits (e.g. a "rivalry" system
- /// that checks for conflicting personalities), so the registry passes
- /// the full recruit list to every behaviour rather than filtering by
- /// ownership.
- ///
- public interface IRecruitBehaviour
- {
- /// Unique identifier for lookup via RecruitBehaviourRegistry.Get.
- string Id { get; }
-
- ///
- /// Called once when a recruit is added to the party
- /// (via RecruitingData.Add). Use for initial stat
- /// setup, buff application, or spawning companion nodes.
- ///
- void ConfigureRecruit(Recruit recruit, RuntimeData runtime);
-
- ///
- /// Called every game tick for each active recruit. The
- /// value is the global
- /// RuntimeData.Time.Tick counter — use it for
- /// cooldown-based or periodic logic rather than maintaining
- /// a private timer.
- ///
- void OnTick(Recruit recruit, RuntimeData runtime, long currentTick);
-
- ///
- /// Called when a recruit is removed from the party
- /// (via RecruitingData.Remove). Clean up any
- /// persisted state, buffs, or companion nodes.
- ///
- void OnRemove(Recruit recruit, RuntimeData runtime);
- }
-
-}
+using Cthangover.Core.Settings;
+
+namespace Cthangover.Core.Relationship
+{
+ ///
+ /// Per-recruit behaviour plugin discovered via reflection from mod
+ /// assemblies. Each implementation is registered into
+ /// by
+ /// and then
+ /// invoked for every active recruit — not just those from the
+ /// owning mod — during tick, configure, and removal lifecycle events.
+ ///
+ /// This cross-recruit dispatch pattern is intentional: a behaviour
+ /// might want to introspect all recruits (e.g. a "rivalry" system
+ /// that checks for conflicting personalities), so the registry passes
+ /// the full recruit list to every behaviour rather than filtering by
+ /// ownership.
+ ///
+ public interface IRecruitBehaviour
+ {
+ /// Unique identifier for lookup via RecruitBehaviourRegistry.Get.
+ string Id { get; }
+
+ ///
+ /// Called once when a recruit is added to the party
+ /// (via RecruitingData.Add). Use for initial stat
+ /// setup, buff application, or spawning companion nodes.
+ ///
+ void ConfigureRecruit(Recruit recruit, RuntimeData runtime);
+
+ ///
+ /// Called every game tick for each active recruit. The
+ /// value is the global
+ /// RuntimeData.Time.Tick counter — use it for
+ /// cooldown-based or periodic logic rather than maintaining
+ /// a private timer.
+ ///
+ void OnTick(Recruit recruit, RuntimeData runtime, long currentTick);
+
+ ///
+ /// Called when a recruit is removed from the party
+ /// (via RecruitingData.Remove). Clean up any
+ /// persisted state, buffs, or companion nodes.
+ ///
+ void OnRemove(Recruit recruit, RuntimeData runtime);
+ }
+
+}
diff --git a/src/IRecruitCondition.cs b/src/IRecruitCondition.cs
index 6c8619b..ee6ff99 100644
--- a/src/IRecruitCondition.cs
+++ b/src/IRecruitCondition.cs
@@ -1,33 +1,33 @@
-using Cthangover.Core.Characters;
-using Cthangover.Core.Settings;
-
-namespace Cthangover.Core.Relationship
-{
- ///
- /// Gating predicate for the recruit system. Implementations are
- /// auto-discovered from mod assemblies by
- /// and
- /// evaluated conjunctively — all conditions must return
- /// true for recruitment to succeed.
- ///
- /// Conditions receive the full and
- /// so they can inspect character stats,
- /// inventory, relationship flags, quest state, or any other
- /// runtime-accessible data when deciding whether a given enemy is
- /// recruitable.
- ///
- public interface IRecruitCondition
- {
- /// Unique identifier for debugging and override lookups.
- string Id { get; }
-
- ///
- /// Returns true if the given
- /// can be recruited under current game state. Called from
- /// RecruitBehaviourRegistry.CanRecruit as part of a
- /// conjunctive gate — a single false blocks recruitment.
- ///
- bool CanRecruit(Character enemy, RuntimeData runtime);
- }
-
-}
+using Cthangover.Core.Characters;
+using Cthangover.Core.Settings;
+
+namespace Cthangover.Core.Relationship
+{
+ ///
+ /// Gating predicate for the recruit system. Implementations are
+ /// auto-discovered from mod assemblies by
+ /// and
+ /// evaluated conjunctively — all conditions must return
+ /// true for recruitment to succeed.
+ ///
+ /// Conditions receive the full and
+ /// so they can inspect character stats,
+ /// inventory, relationship flags, quest state, or any other
+ /// runtime-accessible data when deciding whether a given enemy is
+ /// recruitable.
+ ///
+ public interface IRecruitCondition
+ {
+ /// Unique identifier for debugging and override lookups.
+ string Id { get; }
+
+ ///
+ /// Returns true if the given
+ /// can be recruited under current game state. Called from
+ /// RecruitBehaviourRegistry.CanRecruit as part of a
+ /// conjunctive gate — a single false blocks recruitment.
+ ///
+ bool CanRecruit(Character enemy, RuntimeData runtime);
+ }
+
+}
diff --git a/src/Recruit.cs b/src/Recruit.cs
index ffea572..72a86b0 100644
--- a/src/Recruit.cs
+++ b/src/Recruit.cs
@@ -1,35 +1,35 @@
-using System;
-using Cthangover.Core.Utils;
-
-namespace Cthangover.Core.Relationship
-{
- ///
- /// Runtime model for a recruited party member. Stores the recruit's
- /// unique ID, the character template it was created from, and a
- /// modifiable bag that behaviours
- /// read and mutate during tick/configure events.
- ///
- /// Marked [Serializable] so the recruiting roster survives
- /// save/load — PropertyData serialises its nested values
- /// automatically. The PROP_HEALTH constant is the conventional
- /// key for health tracking; behaviours that need custom state
- /// (e.g. morale, loyalty timers) add their own keys to the
- /// Properties bag at configure time.
- ///
- [Serializable]
- public class Recruit
- {
- /// Conventional key for the recruit's health value in the Properties bag.
- public const string PROP_HEALTH = "Health";
-
- /// Unique instance ID (auto-generated via RecruitingData.GenID).
- public string ID { get; set; }
-
- /// Character template ID this recruit was spawned from.
- public string CharacterID { get; set; }
-
- /// Mutable property bag — behaviours read/write custom state here.
- public PropertyData Properties { get; set; } = new();
- }
-
-}
+using System;
+using Cthangover.Core.Utils;
+
+namespace Cthangover.Core.Relationship
+{
+ ///
+ /// Runtime model for a recruited party member. Stores the recruit's
+ /// unique ID, the character template it was created from, and a
+ /// modifiable bag that behaviours
+ /// read and mutate during tick/configure events.
+ ///
+ /// Marked [Serializable] so the recruiting roster survives
+ /// save/load — PropertyData serialises its nested values
+ /// automatically. The PROP_HEALTH constant is the conventional
+ /// key for health tracking; behaviours that need custom state
+ /// (e.g. morale, loyalty timers) add their own keys to the
+ /// Properties bag at configure time.
+ ///
+ [Serializable]
+ public class Recruit
+ {
+ /// Conventional key for the recruit's health value in the Properties bag.
+ public const string PROP_HEALTH = "Health";
+
+ /// Unique instance ID (auto-generated via RecruitingData.GenID).
+ public string ID { get; set; }
+
+ /// Character template ID this recruit was spawned from.
+ public string CharacterID { get; set; }
+
+ /// Mutable property bag — behaviours read/write custom state here.
+ public PropertyData Properties { get; set; } = new();
+ }
+
+}
diff --git a/src/RecruitTickController.cs b/src/RecruitTickController.cs
index 022e484..107c096 100644
--- a/src/RecruitTickController.cs
+++ b/src/RecruitTickController.cs
@@ -1,62 +1,62 @@
-using Cthangover.Core.Scenes;
-using Cthangover.Core.UI.Event;
-
-namespace Cthangover.Core.Relationship
-{
- ///
- /// Lazy bridge between the scene timer system and the recruit
- /// behaviour tick loop. Implements
- /// so it can be registered with
- /// via AddTimerTickEventListener.
- ///
- /// Registration is lazy ( is a no-op
- /// after the first call) because the recruit system should not
- /// force the timer subsystem to activate if no behaviours are
- /// actually loaded. The first behaviour lifecycle method in
- /// calls
- /// EnsureRegistered, which finds the scene's
- /// EventController node and subscribes.
- ///
- /// Priority = 0 so recruit ticks fire at a neutral point in
- /// the timer event chain — before or after other listeners as
- /// determined by their relative priorities.
- ///
- public class RecruitTickController : IOnTimeEvent
- {
- /// Neutral priority — doesn't preempt or follow any specific listener.
- public int Priority => 0;
-
- private bool _registered;
-
- ///
- /// Finds the scene's EventController node and subscribes
- /// this controller as a timer-tick listener. Idempotent —
- /// subsequent calls do nothing.
- ///
- public void EnsureRegistered()
- {
- if (_registered)
- return;
- var eventController = SceneContextNode.FindNode("EventController");
- if (eventController == null)
- return;
- eventController.AddTimerTickEventListener(this);
- _registered = true;
- }
-
- ///
- /// Called by on every
- /// timer tick. Delegates to
- /// .
- /// Ticks also fire during the launcher boot window, so the registry
- /// side must not touch GameData.Instance.Runtime or mod data
- /// until Boot.ModsReady (see the boot-window contract on
- /// IOnTimeEvent; core-side reference: TimeTickController).
- ///
- public void OnTimerTick()
- {
- RecruitBehaviourRegistry.Instance.OnTick();
- }
- }
-
-}
+using Cthangover.Core.Scenes;
+using Cthangover.Core.UI.Event;
+
+namespace Cthangover.Core.Relationship
+{
+ ///
+ /// Lazy bridge between the scene timer system and the recruit
+ /// behaviour tick loop. Implements
+ /// so it can be registered with
+ /// via AddTimerTickEventListener.
+ ///
+ /// Registration is lazy ( is a no-op
+ /// after the first call) because the recruit system should not
+ /// force the timer subsystem to activate if no behaviours are
+ /// actually loaded. The first behaviour lifecycle method in
+ /// calls
+ /// EnsureRegistered, which finds the scene's
+ /// EventController node and subscribes.
+ ///
+ /// Priority = 0 so recruit ticks fire at a neutral point in
+ /// the timer event chain — before or after other listeners as
+ /// determined by their relative priorities.
+ ///
+ public class RecruitTickController : IOnTimeEvent
+ {
+ /// Neutral priority — doesn't preempt or follow any specific listener.
+ public int Priority => 0;
+
+ private bool _registered;
+
+ ///
+ /// Finds the scene's EventController node and subscribes
+ /// this controller as a timer-tick listener. Idempotent —
+ /// subsequent calls do nothing.
+ ///
+ public void EnsureRegistered()
+ {
+ if (_registered)
+ return;
+ var eventController = SceneContextNode.FindNode("EventController");
+ if (eventController == null)
+ return;
+ eventController.AddTimerTickEventListener(this);
+ _registered = true;
+ }
+
+ ///
+ /// Called by on every
+ /// timer tick. Delegates to
+ /// .
+ /// Ticks also fire during the launcher boot window, so the registry
+ /// side must not touch GameData.Instance.Runtime or mod data
+ /// until Boot.ModsReady (see the boot-window contract on
+ /// IOnTimeEvent; core-side reference: TimeTickController).
+ ///
+ public void OnTimerTick()
+ {
+ RecruitBehaviourRegistry.Instance.OnTick();
+ }
+ }
+
+}