diff --git a/sharedstate.lua b/sharedstate.lua
index 3243680..fcb45fe 100644
--- a/sharedstate.lua
+++ b/sharedstate.lua
@@ -3,7 +3,7 @@ local logging=require((...):gsub("(.)$", "%1.") .. 'logging')
 
 -- function names
 local is_initialized, callback_value, set_value,
-get_value, resolve_key, resolve_index
+get_value, resolve_key, resolve_index, get_table
 
 --schema: similar to state_table, nested table only contains value
 local state_queue={}
@@ -128,6 +128,17 @@ do
 		logging.trace("resolve_index", key)
 		return state_table[key]["index"]
 	end
+
+	--- Get table
+	--Internal; Gets a copy of the shared state table with internal data
+	--removed
+	function get_table()
+		local t={}
+		for k, v in pairs(state_table) do
+			t[k]={ ["value"]=v["value"] }
+		end
+		return t
+	end
 end
 
 ---Add an item to the shared state store.
@@ -167,6 +178,7 @@ end
 --- Internal; unpack a table of state into the local state store
 ---@param tbl table Table to unpack
 function pings.sharedstate_recv_table(tbl)
+	logging.debug("Table sync received")
 	for k, v in pairs(tbl) do
 		set_value(k, v["value"])
 	end
@@ -231,6 +243,14 @@ function sharedstate.clear(key)
 	end
 end
 
+--- Sync full state
+--Syncs the full shared state table. This should be used sparsely
+function sharedstate.sync()
+	if host:isHost() then
+		ping.sharedstate_recv_table(get_table())
+	end
+end
+
 -- this can be copied directly from the internal functions as it is read only
 sharedstate.get=get_value