diff --git a/include/fggl/grid/actions.hpp b/include/fggl/grid/actions.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ae3c98abc297130e6cc7d54b8ca3b6dc2933e12
--- /dev/null
+++ b/include/fggl/grid/actions.hpp
@@ -0,0 +1,77 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 19/12/22.
+//
+
+#ifndef FGGL_GRID_ACTIONS_H
+#define FGGL_GRID_ACTIONS_H
+
+#include <cstdint>
+#include <variant>
+
+#include "fggl/grid/hexagon.hpp"
+#include "fggl/grid/tokens.hpp"
+
+#include "fggl/util/safety.hpp"
+
+namespace fggl::grid {
+
+	template<typename State, typename Target>
+	class ActionType;
+
+	template<typename State, typename Target>
+	class Action {
+		public:
+			virtual void progress(State* state) = 0;
+			virtual bool isDone() = 0;
+	};
+
+	template<typename State, typename Target>
+	class InstantAction : public Action<State, Target> {
+		public:
+			void progress(State* state) final;
+			bool isDone() final;
+		private:
+			ActionType<State, Target>* m_action;
+			TokenIdentifer m_actor;
+			Target m_target;
+	};
+
+	template<typename State, typename Target>
+	class DurativeAction : public Action<State, Target> {
+		public:
+			void progress(State* state) final;
+			bool isDone() final;
+		private:
+			ActionType<State, Target>* m_action;
+			TokenIdentifer m_actor;
+			Target m_target;
+			uint64_t m_completionRound;
+	};
+
+	template<typename State, typename Target>
+	class ActionType {
+		public:
+			virtual bool canApply(const State* state, TokenIdentifer actor, Target target) = 0;
+			virtual void apply(State* state, TokenIdentifer actor, Target target) = 0;
+
+			virtual Action<State, Target> ground(TokenIdentifer actor, Target target) = 0;
+	};
+
+
+} // namespace fggl::grid
+
+#endif //FGGL_GRID_ACTIONS_H
diff --git a/include/fggl/grid/hexgrid.hpp b/include/fggl/grid/hexgrid.hpp
index cc8aa061672e101c09aa83df6209ae96b01a6ff5..1902b3bd0e3b8f2b4743c6e2210f1e5f0e037a82 100644
--- a/include/fggl/grid/hexgrid.hpp
+++ b/include/fggl/grid/hexgrid.hpp
@@ -23,65 +23,20 @@
 #include <set>
 #include <optional>
 #include <utility>
+#include <variant>
 
 #include "fggl/grid/hexagon.hpp"
+#include "fggl/grid/tokens.hpp"
+#include "fggl/grid/actions.hpp"
+
 #include "fggl/math/types.hpp"
 
 namespace fggl::grid {
 
-	class TokenType {
-		public:
-			using PropType = int64_t;
-
-			inline void setProperty(util::GUID name, PropType newVal) {
-				m_properties[name] = newVal;
-			}
-
-			[[nodiscard]]
-			inline PropType getProperty(util::GUID name, PropType unsetVal=0) const {
-				try {
-					return m_properties.at(name);
-				} catch ( std::out_of_range& e ) {
-					return unsetVal;
-				}
-			}
-		private:
-			std::map<util::GUID, PropType> m_properties;
-			std::map<util::GUID, uint64_t> m_cost;
-	};
-
-	class Token {
-		public:
-			Token() = default;
-			explicit Token(std::shared_ptr<TokenType> type) : m_type(std::move(type)) {}
-
-			inline void setProperty(util::GUID name, TokenType::PropType newVal) {
-				m_properties[name] = newVal;
-			}
-
-			[[nodiscard]]
-			inline TokenType::PropType getProperty(util::GUID name, TokenType::PropType unsetVal=0) const {
-				try {
-					auto prop = m_properties.at(name);
-					return prop;
-				} catch ( std::out_of_range& ex) {
-					return m_type->getProperty(name, unsetVal);
-				}
-			}
+	class HexGrid;
 
-			[[nodiscard]]
-			inline TokenType::PropType getPropertyDirect(util::GUID name, TokenType::PropType unsetVal=0) const {
-				try {
-					auto prop = m_properties.at(name);
-					return prop;
-				} catch ( std::out_of_range& ex) {
-					return unsetVal;
-				}
-			}
-		private:
-			std::shared_ptr<TokenType> m_type;
-			std::map<util::GUID, TokenType::PropType> m_properties;
-	};
+	using HexTarget = std::variant<TokenIdentifer, IntHex>;
+	using HexAction = Action<HexGrid, HexTarget>;
 
 	struct MaterialData {
 		std::string name;
diff --git a/include/fggl/grid/tokens.hpp b/include/fggl/grid/tokens.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..95464ab223e30179c441ba2444a0084bb43fe93a
--- /dev/null
+++ b/include/fggl/grid/tokens.hpp
@@ -0,0 +1,88 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 19/12/22.
+//
+
+#ifndef FGGL_GRID_TOKENS_HPP
+#define FGGL_GRID_TOKENS_HPP
+
+#include <cstdint>
+#include <map>
+
+#include "fggl/util/guid.hpp"
+
+namespace fggl::grid {
+
+	using TokenIdentifer = fggl::util::OpaqueName<uint64_t, struct Token>;
+
+	class TokenType {
+		public:
+			using PropType = int64_t;
+
+			inline void setProperty(util::GUID name, PropType newVal) {
+				m_properties[name] = newVal;
+			}
+
+			[[nodiscard]]
+			inline PropType getProperty(util::GUID name, PropType unsetVal=0) const {
+				try {
+					return m_properties.at(name);
+				} catch ( std::out_of_range& e ) {
+					return unsetVal;
+				}
+			}
+		private:
+			std::map<util::GUID, PropType> m_properties;
+			std::map<util::GUID, uint64_t> m_cost;
+	};
+
+	class Token {
+		public:
+			Token() = default;
+			explicit Token(std::shared_ptr<TokenType> type) : m_type(std::move(type)) {}
+
+			inline void setProperty(util::GUID name, TokenType::PropType newVal) {
+				m_properties[name] = newVal;
+			}
+
+			[[nodiscard]]
+			inline TokenType::PropType getProperty(util::GUID name, TokenType::PropType unsetVal=0) const {
+				try {
+					auto prop = m_properties.at(name);
+					return prop;
+				} catch ( std::out_of_range& ex) {
+					return m_type->getProperty(name, unsetVal);
+				}
+			}
+
+			[[nodiscard]]
+			inline TokenType::PropType getPropertyDirect(util::GUID name, TokenType::PropType unsetVal=0) const {
+				try {
+					auto prop = m_properties.at(name);
+					return prop;
+				} catch ( std::out_of_range& ex) {
+					return unsetVal;
+				}
+			}
+		private:
+			TokenIdentifer m_id;
+			std::shared_ptr<TokenType> m_type;
+			std::map<util::GUID, TokenType::PropType> m_properties;
+	};
+
+} // namespace fggl::grid
+
+#endif //FGGL_GRID_TOKENS_HPP