diff --git a/message_bus_tools.py b/message_bus_tools.py
new file mode 100644
index 00000000..b930e456
--- /dev/null
+++ b/message_bus_tools.py
@@ -0,0 +1,48 @@
+from ansi_tags import ansiprint
+from enum import StrEnum
+from uuid import UUID, uuid4
+
+class Event(StrEnum):
+ START_OF_TURN = "start_of_turn"
+ END_OF_TURN = "end_of_turn"
+ START_OF_COMBAT = "start_of_combat"
+ END_OF_COMBAT = "end_of_combat"
+
+class MessageBus():
+ def __init__(self, debug=True) -> None:
+ self.subscribers = dict(dict())
+ self.debug = debug
+
+ def subscribe(self, event: Event, uid: UUID, callbk_func):
+ if event not in self.subscribers:
+ self.subscribers[event] = dict()
+ self.subscribers[event][uid] = callbk_func
+ if self.debug is True:
+ ansiprint(f"MESSAGEBUS: {event} | Subscribed {callbk_func.__qualname__}")
+
+ def unsubscribe(self, event: Event, uid: UUID):
+ if self.debug is True:
+ ansiprint(f"MESSAGEBUS: {event} | Unsubscribed {self.subscribers[event][uid].__qualname__}")
+ del self.subscribers[event][uid]
+
+ def event_call(self, event, data):
+ if event in self.subscribers:
+ for _uid, callback in self.subscribers[event].items():
+ if self.debug:
+ ansiprint(f"MESSAGEBUS: {event} | Calling {callback.__qualname__}")
+ callback(event, data)
+ return data
+
+class Registerable():
+ events = []
+ def register(self, bus):
+ for event in self.events:
+ bus.subscribe(event, self.uid, self.callback)
+
+ def unregister(self, bus, event=None):
+ if event:
+ bus.unsubscribe(event, self.uid)
+ else:
+ for event in self.events:
+ bus.unsubscribe(event, self.uid)
+