diff --git a/Polonium.csproj b/Polonium.csproj
index cd3342f..4fb5015 100644
--- a/Polonium.csproj
+++ b/Polonium.csproj
@@ -14,6 +14,7 @@
+
diff --git a/src/Agents/ActionSet.cs b/src/Agents/ActionSet.cs
new file mode 100644
index 0000000..2efbbda
--- /dev/null
+++ b/src/Agents/ActionSet.cs
@@ -0,0 +1,13 @@
+using Godot;
+using Polonium.Resources;
+
+namespace Polonium.Agents;
+
+public abstract partial class ActionSet : Node
+{
+ [Signal]
+ public delegate void ActionSubmittedEventHandler(ActionBody action);
+
+
+}
+
diff --git a/src/Agents/Agent.cs b/src/Agents/Agent.cs
index dca77e7..471f87a 100644
--- a/src/Agents/Agent.cs
+++ b/src/Agents/Agent.cs
@@ -1,51 +1,39 @@
+using Godot;
+using Polonium.Resources;
+
namespace Polonium.Agents;
-public abstract class Agent
+public abstract partial class Agent : Node
{
- protected static int ComputerCount = 0;
+ [Signal]
+ public delegate void ActionExecutedEventHandler(SignalHeader header, ActionBody actionBody);
+ protected Knowledge Knowledge { get; set; }
+ public ActionSet ActionSet { get; set; }
- public string Name { get; init; }
-
- public Agent(string name)
+ public virtual void __Ready()
{
- Name = name;
- PoloniumRegistry.Instance.Agents[name] = this;
+ Knowledge = GetNode("Knowledge");
+ ActionSet = GetNode("ActionSet");
+ ActionSet.ActionSubmitted += ExecuteAction;
}
- public int Level { get; private set; }
- public abstract int MaxLevel { get; }
-
- public virtual void LevelUp()
+ public sealed override void _Ready()
{
- if(Level < MaxLevel)
- Level++;
+ Knowledge = GetNode("Knowledge");
+ ActionSet = GetNode("ActionSet");
+ __Ready();
+ base._Ready();
}
-}
-
-public abstract class Agent : Agent
- where TAgent : Agent, new()
- where TAgentDecisionMaker : AgentDecisionMaker, new()
- where TAgentKnowledge : AgentKnowledge, new()
- where TAgentAction : AgentAction, new()
-{
-
- public Dictionary Actions { get; } = new();
-
- public TAgentDecisionMaker DecisionMaker { get; init; }
- public TAgentKnowledge Knowledge { get; init; }
-
-
- public Agent() : base($"Computer {ComputerCount++}")
- {
- DecisionMaker = new TAgentDecisionMaker();
- Knowledge = new TAgentKnowledge();
- }
-
- public Agent(string name, TAgentDecisionMaker decisionMaker, TAgentKnowledge knowledge) : base(name)
- {
- DecisionMaker = decisionMaker;
- Knowledge = knowledge;
- }
+ public void UpdateKnowledge(KnowledgePatch update) => update.Patch(Knowledge);
+
+ public virtual void ExecuteAction(ActionBody actionBody)
+ {
+ SignalHeader header = PoloniumRegistry.Instance.PoloniumFactory.CreateSignalHeader();
+ header.SetSender(this);
+ EmitSignalActionExecuted(header, actionBody);
+ }
+
+
}
diff --git a/src/Agents/AgentAction.cs b/src/Agents/AgentAction.cs
deleted file mode 100644
index 328832e..0000000
--- a/src/Agents/AgentAction.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using Polonium.Interfaces;
-
-namespace Polonium.Agents;
-
-public abstract class AgentAction
-{
-}
-
-public abstract class AgentAction : AgentAction, ITimeConsumer
- where TAgent : Agent, new()
- where TAgentDecisionMaker : AgentDecisionMaker, new()
- where TAgentKnowledge : AgentKnowledge, new()
- where TAgentAction : AgentAction, new()
-{
-
- public int Level { get; private set; }
-
- public abstract int MaxLevel { get; }
-
- public virtual void LevelUp()
- {
- if(Level < MaxLevel)
- Level++;
- }
-
- public AgentAction(double coolDown)
- {
- CoolDown = coolDown;
- PoloniumRegistry.Instance.TimeConsumers.Add(this);
- }
-
- public abstract class ActionParameter
- {
- }
-
- public virtual bool Execute(ActionParameter parameter)
- {
- if (Disabled || CoolDown > 0)
- return false;
- CoolDownTime = CoolDown;
- return true;
- }
-
-
- private double CoolDownTime { get; set; }
- public bool Disabled { get; set; }
-
- private double CoolDown { get; }
-
- public void Process(double delta)
- {
-
- if (Disabled || CoolDownTime <= 0)
- return;
- CoolDownTime -= delta;
- if (CoolDownTime <= 0)
- CoolDownTime = 0;
-
- }
-}
diff --git a/src/Agents/AgentDecisionMaker.cs b/src/Agents/AgentDecisionMaker.cs
deleted file mode 100644
index 4c20980..0000000
--- a/src/Agents/AgentDecisionMaker.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Polonium.Agents;
-
-public abstract class AgentDecisionMaker(DecisionMakerType type)
- where TAgent : Agent, new()
- where TAgentDecisionMaker : AgentDecisionMaker, new()
- where TAgentKnowledge : AgentKnowledge, new()
- where TAgentAction : AgentAction, new()
-{
-
-
-
- public DecisionMakerType Type { get; init; } = type;
-
- public AgentDecisionMaker() : this(DecisionMakerType.Computer)
- {
- }
-}
\ No newline at end of file
diff --git a/src/Agents/AgentKnowledge.cs b/src/Agents/AgentKnowledge.cs
deleted file mode 100644
index 4b07676..0000000
--- a/src/Agents/AgentKnowledge.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Polonium.Agents;
-
-public abstract class AgentKnowledge
-{
-}
-
-public abstract class AgentKnowledge : AgentKnowledge
- where TAgent : Agent, new()
- where TAgentDecisionMaker : AgentDecisionMaker, new()
- where TAgentKnowledge : AgentKnowledge, new()
- where TAgentAction : AgentAction, new()
-{
- public AgentKnowledge()
- {
- }
-
- public abstract void Update(TAgentKnowledge newKnowledge);
-}
diff --git a/src/Agents/DecisionMakerType.cs b/src/Agents/DecisionMakerType.cs
deleted file mode 100644
index f721983..0000000
--- a/src/Agents/DecisionMakerType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Polonium.Agents;
-
-public enum DecisionMakerType
-{
- None = 0,
- Player = 1,
- Computer = 2,
- Global = 3,
-}
\ No newline at end of file
diff --git a/src/Agents/Knowledge.cs b/src/Agents/Knowledge.cs
new file mode 100644
index 0000000..6a51d94
--- /dev/null
+++ b/src/Agents/Knowledge.cs
@@ -0,0 +1,8 @@
+using Godot;
+
+namespace Polonium.Agents;
+
+public abstract partial class Knowledge : Node
+{
+
+}
\ No newline at end of file
diff --git a/src/Agents/World.cs b/src/Agents/World.cs
new file mode 100644
index 0000000..e3fa191
--- /dev/null
+++ b/src/Agents/World.cs
@@ -0,0 +1,45 @@
+using Godot;
+using Polonium.Resources;
+
+namespace Polonium.Agents;
+
+public abstract partial class World : Node
+{
+ private WorldModel Model { get; set; }
+ public HashSet Agents { get; } = new();
+ public Knowledge CommonKnowledge { get; set; }
+
+ public override void _Ready()
+ {
+ Model = GetNode("WorldModel");
+ CommonKnowledge = GetNode("CommonKnowledge");
+ Model.CommonKnowledgeUpdated += CommonKnowledgeUpdated;
+ Model.PrivateKnowledgeUpdated += ForwardPrivateKnowledgeUpdated;
+ base._Ready();
+ }
+
+ public void RegisterAgent(Agent agent)
+ {
+ Agents.Add(agent);
+ agent.ActionExecuted += Model.ActionExecuted;
+ }
+
+ public virtual void Enter()
+ {
+ PoloniumRegistry.Instance.CurrentWorld = this;
+ }
+
+ public virtual void Exit()
+ {
+ PoloniumRegistry.Instance.CurrentWorld = null;
+ }
+
+ public void CommonKnowledgeUpdated(KnowledgePatch update) => update.Patch(CommonKnowledge);
+
+ public void ForwardPrivateKnowledgeUpdated(SignalHeader header, KnowledgePatch update)
+ {
+ foreach (Agent receiver in header.ResolveReceivers())
+ receiver.UpdateKnowledge(update);
+ }
+
+}
\ No newline at end of file
diff --git a/src/Agents/WorldModel.cs b/src/Agents/WorldModel.cs
new file mode 100644
index 0000000..b5a7794
--- /dev/null
+++ b/src/Agents/WorldModel.cs
@@ -0,0 +1,22 @@
+using Godot;
+using Polonium.Resources;
+
+namespace Polonium.Agents;
+
+public abstract partial class WorldModel : Node
+{
+
+ [Signal]
+ public delegate void CommonKnowledgeUpdatedEventHandler(KnowledgePatch update);
+ [Signal]
+ public delegate void PrivateKnowledgeUpdatedEventHandler(SignalHeader header, KnowledgePatch update);
+
+ private Knowledge WorldKnowledge { get; set; }
+
+ public override void _Ready()
+ {
+ WorldKnowledge = GetNode("WorldKnowledge");
+ base._Ready();
+ }
+ public abstract void ActionExecuted(SignalHeader header, ActionBody actionBody);
+}
diff --git a/src/Interfaces/IPoloniumFactory.cs b/src/Interfaces/IPoloniumFactory.cs
new file mode 100644
index 0000000..f3c5e24
--- /dev/null
+++ b/src/Interfaces/IPoloniumFactory.cs
@@ -0,0 +1,8 @@
+using Polonium.Resources;
+
+namespace Polonium.Interfaces;
+
+public interface IPoloniumFactory
+{
+ public SignalHeader CreateSignalHeader();
+}
\ No newline at end of file
diff --git a/src/PoloniumRegistry.cs b/src/PoloniumRegistry.cs
index d3dd4d3..04bbd43 100644
--- a/src/PoloniumRegistry.cs
+++ b/src/PoloniumRegistry.cs
@@ -14,6 +14,12 @@ public class PoloniumRegistry
public Config Config { get; set; }
[RegistryPassThrough]
public Save Save { get; set; }
+ [RegistryPassThrough]
+ public World CurrentWorld { get; set; }
+
+ [RegistryPassThrough]
+ public IPoloniumFactory PoloniumFactory { get; set; }
+
public static void Prepare()
{
@@ -28,4 +34,4 @@ public class PoloniumRegistry
public HashSet TimeConsumers { get; } = new();
-}
\ No newline at end of file
+}
diff --git a/src/Resources/ActionBody.cs b/src/Resources/ActionBody.cs
new file mode 100644
index 0000000..1bc28d9
--- /dev/null
+++ b/src/Resources/ActionBody.cs
@@ -0,0 +1,9 @@
+using Godot;
+
+namespace Polonium.Resources;
+
+public abstract partial class ActionBody : Resource
+{
+ public StringName ActionName { get; set; }
+
+}
diff --git a/src/Resources/KnowledgePatch.cs b/src/Resources/KnowledgePatch.cs
new file mode 100644
index 0000000..b8b20a3
--- /dev/null
+++ b/src/Resources/KnowledgePatch.cs
@@ -0,0 +1,11 @@
+using Godot;
+using Polonium.Agents;
+
+namespace Polonium.Resources;
+
+public abstract partial class KnowledgePatch : Resource
+{
+ public SignalHeader Header { get; set; }
+ public abstract void Patch(Knowledge knowledge);
+
+}
\ No newline at end of file
diff --git a/src/Resources/SignalHeader.cs b/src/Resources/SignalHeader.cs
new file mode 100644
index 0000000..468d298
--- /dev/null
+++ b/src/Resources/SignalHeader.cs
@@ -0,0 +1,15 @@
+using Godot;
+using Polonium.Agents;
+
+namespace Polonium.Resources;
+
+public abstract partial class SignalHeader : Resource
+{
+
+ public abstract Agent[] ResolveReceivers();
+ public abstract Agent ResolveSender();
+
+ public abstract void SetSender(Agent agent);
+ public abstract void AddReceiver(Agent agent);
+
+}