diff --git a/Cargo.lock b/Cargo.lock
index d8426940ff..d394200d4c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5699,6 +5699,7 @@ name = "veloren-plugin-api"
 version = "0.1.0"
 dependencies = [
  "serde",
+ "veloren-common",
 ]
 
 [[package]]
diff --git a/assets/plugins/hello.wasm b/assets/plugins/hello.wasm
new file mode 100644
index 0000000000..71c52f6d82
Binary files /dev/null and b/assets/plugins/hello.wasm differ
diff --git a/assets/plugins/plugin1.plugin.tar b/assets/plugins/plugin1.plugin.tar
index cec6c45c96..0e9f0e9b60 100644
Binary files a/assets/plugins/plugin1.plugin.tar and b/assets/plugins/plugin1.plugin.tar differ
diff --git a/common/Cargo.toml b/common/Cargo.toml
index 76aaca36c1..b0137d163f 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -13,6 +13,11 @@ bin_csv = ["csv", "structopt"]
 default = ["simd"]
 
 [dependencies]
+
+# Serde
+serde = { version = "1.0.110", features = ["derive", "rc"] }
+
+[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 approx = "0.4.0"
 arraygen = "0.1.13"
 crossbeam-utils = "0.8.1"
@@ -22,20 +27,34 @@ lazy_static = "1.4.0"
 num-derive = "0.3"
 num-traits = "0.2"
 ordered-float = { version = "2.0.1", default-features = false }
-rand = "0.8"
 rayon = "1.5"
 roots = "0.0.6"
 spin_sleep = "1.0"
 tracing = { version = "0.1", default-features = false }
 vek = { version = "=0.12.0", features = ["serde"] }
 uuid = { version = "0.8.1", default-features = false, features = ["serde", "v4"] }
+rand = "0.8"
 
 # Assets
-assets_manager = {version = "0.4.2", features = ["bincode", "ron", "json", "hot-reloading"]}
 directories-next = "2.0"
 dot_vox = "4.0"
 image = { version = "0.23.12", default-features = false, features = ["png"] }
 
+# Assets
+assets_manager = {version = "0.4.2", features = ["bincode", "ron", "json", "hot-reloading"]}
+# Serde
+ron = { version = "0.6", default-features = false }
+serde_json = "1.0.50"
+serde_repr = "0.1.6"
+
+# esv export
+csv = { version = "1.1.3", optional = true }
+structopt = { version = "0.3.13", optional = true }
+
+# Tracy
+tracy-client = { version = "0.10.0", optional = true }
+
+
 # Data structures
 hashbrown = { version = "0.9", features = ["rayon", "serde", "nightly"] }
 slotmap = { version = "1.0", features = ["serde"] }
@@ -45,18 +64,6 @@ slab = "0.4.2"
 # ECS
 specs = { git = "https://github.com/amethyst/specs.git", features = ["serde", "storage-event-control", "nightly"], rev = "d4435bdf496cf322c74886ca09dd8795984919b4" }
 specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "9fab7b396acd6454585486e50ae4bfe2069858a9" }
-# Serde
-ron = { version = "0.6", default-features = false }
-serde = { version = "1.0.110", features = ["derive", "rc"] }
-serde_json = "1.0.50"
-serde_repr = "0.1.6"
-
-#esv export
-csv = { version = "1.1.3", optional = true }
-structopt = { version = "0.3.13", optional = true }
-
-# Tracy
-tracy-client = { version = "0.10.0", optional = true }
 
 [dev-dependencies]
 #bench
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 37739b9b68..841fa50135 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -18,45 +18,66 @@
     trait_alias,
     type_alias_impl_trait
 )]
-
+#[cfg(not(target_arch = "wasm32"))]
 pub mod assets;
-pub mod astar;
+#[cfg(not(target_arch = "wasm32"))] pub mod astar;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod character;
-pub mod clock;
-pub mod cmd;
+#[cfg(not(target_arch = "wasm32"))] pub mod clock;
+#[cfg(not(target_arch = "wasm32"))] pub mod cmd;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod combat;
-pub mod comp;
+#[cfg(not(target_arch = "wasm32"))] pub mod comp;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod consts;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod effect;
-pub mod event;
+#[cfg(not(target_arch = "wasm32"))] pub mod event;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod explosion;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod figure;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod generation;
-pub mod grid;
+#[cfg(not(target_arch = "wasm32"))] pub mod grid;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod lottery;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod metrics;
-pub mod npc;
+#[cfg(not(target_arch = "wasm32"))] pub mod npc;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod outcome;
-pub mod path;
-pub mod ray;
+#[cfg(not(target_arch = "wasm32"))] pub mod path;
+#[cfg(not(target_arch = "wasm32"))] pub mod ray;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod recipe;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod region;
 pub mod resources;
-pub mod rtsim;
+#[cfg(not(target_arch = "wasm32"))] pub mod rtsim;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod skillset_builder;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod spiral;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod states;
-pub mod store;
+#[cfg(not(target_arch = "wasm32"))] pub mod store;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod terrain;
-pub mod time;
-pub mod trade;
-pub mod typed;
+#[cfg(not(target_arch = "wasm32"))] pub mod time;
+#[cfg(not(target_arch = "wasm32"))] pub mod trade;
+#[cfg(not(target_arch = "wasm32"))] pub mod typed;
 pub mod uid;
-pub mod util;
-pub mod vol;
+#[cfg(not(target_arch = "wasm32"))] pub mod util;
+#[cfg(not(target_arch = "wasm32"))] pub mod vol;
+#[cfg(not(target_arch = "wasm32"))]
 pub mod volumes;
 
+#[cfg(not(target_arch = "wasm32"))]
 pub use combat::{Damage, DamageSource, GroupTarget, Knockback, KnockbackDir};
+#[cfg(not(target_arch = "wasm32"))]
 pub use comp::inventory::loadout_builder::LoadoutBuilder;
+#[cfg(not(target_arch = "wasm32"))]
 pub use explosion::{Explosion, RadiusEffect};
+#[cfg(not(target_arch = "wasm32"))]
 pub use skillset_builder::SkillSetBuilder;
diff --git a/common/src/uid.rs b/common/src/uid.rs
index 22c5eb347f..1899a06299 100644
--- a/common/src/uid.rs
+++ b/common/src/uid.rs
@@ -1,5 +1,7 @@
+#[cfg(not(target_arch = "wasm32"))]
 use hashbrown::HashMap;
 use serde::{Deserialize, Serialize};
+#[cfg(not(target_arch = "wasm32"))]
 use specs::{
     saveload::{Marker, MarkerAllocator},
     world::EntitiesRes,
@@ -22,10 +24,12 @@ impl fmt::Display for Uid {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
 }
 
+#[cfg(not(target_arch = "wasm32"))]
 impl Component for Uid {
     type Storage = FlaggedStorage<Self, VecStorage<Self>>;
 }
 
+#[cfg(not(target_arch = "wasm32"))]
 impl Marker for Uid {
     type Allocator = UidAllocator;
     type Identifier = u64;
@@ -37,11 +41,14 @@ impl Marker for Uid {
     }
 }
 
+#[cfg(not(target_arch = "wasm32"))]
+#[derive(Debug)]
 pub struct UidAllocator {
     index: u64,
     mapping: HashMap<u64, Entity>,
 }
 
+#[cfg(not(target_arch = "wasm32"))]
 impl UidAllocator {
     pub fn new() -> Self {
         Self {
@@ -55,10 +62,12 @@ impl UidAllocator {
     pub fn remove_entity(&mut self, id: u64) -> Option<Entity> { self.mapping.remove(&id) }
 }
 
+#[cfg(not(target_arch = "wasm32"))]
 impl Default for UidAllocator {
     fn default() -> Self { Self::new() }
 }
 
+#[cfg(not(target_arch = "wasm32"))]
 impl MarkerAllocator<Uid> for UidAllocator {
     fn allocate(&mut self, entity: Entity, id: Option<u64>) -> Uid {
         let id = id.unwrap_or_else(|| {
diff --git a/common/sys/src/plugin/memory_manager.rs b/common/sys/src/plugin/memory_manager.rs
index b242587a45..353909439b 100644
--- a/common/sys/src/plugin/memory_manager.rs
+++ b/common/sys/src/plugin/memory_manager.rs
@@ -1,49 +1,105 @@
-use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};
+use std::sync::atomic::{AtomicI32, AtomicPtr, AtomicU32, AtomicU64, Ordering};
 
-use serde::{Serialize, de::DeserializeOwned};
+use serde::{de::DeserializeOwned, Serialize};
+use specs::World;
 use wasmer::{Function, Memory, Value};
 
 use super::errors::{MemoryAllocationError, PluginModuleError};
 
+// This structure wraps the ECS pointer to ensure safety
+pub struct EcsAccessManager {
+    ecs_pointer: AtomicPtr<World>,
+}
+
+impl Default for EcsAccessManager {
+
+    fn default() -> Self {
+        Self {
+            ecs_pointer: AtomicPtr::new(std::ptr::null_mut::<_>())
+        }
+    }
+}
+
+impl EcsAccessManager {
+
+    pub fn execute_with<T>(&self, world: &World, func: impl FnOnce() -> T) -> T {
+        self.ecs_pointer.store(world as *const _ as *mut _, Ordering::SeqCst);
+        let out = func();
+        self.ecs_pointer.store(std::ptr::null_mut::<_>(), Ordering::SeqCst);
+        out
+    }
+
+    pub fn get(&self) -> Option<&World> {
+        // ptr::as_ref will automatically check for null
+        unsafe {self.ecs_pointer.load(Ordering::SeqCst).as_ref()}
+    }
+}
 
 pub struct MemoryManager {
     pub pointer: AtomicI32,
-    pub length: AtomicU32
+    pub length: AtomicU32,
 }
 
-impl MemoryManager {
-
-    pub fn new() -> Self{
+impl Default for MemoryManager {
+    fn default() -> Self {
         Self {
             pointer: AtomicI32::new(0),
             length: AtomicU32::new(0),
         }
     }
+}
 
-    // This function check if the buffer is wide enough if not it realloc the buffer calling the `wasm_prepare_buffer` function
-    // Note: There is probably optimizations that can be done using less restrictive ordering
-    pub fn get_pointer(&self, object_length: u32, allocator: &Function) -> Result<i32,MemoryAllocationError> {
+impl MemoryManager {
+
+    // This function check if the buffer is wide enough if not it realloc the buffer
+    // calling the `wasm_prepare_buffer` function Note: There is probably
+    // optimizations that can be done using less restrictive ordering
+    pub fn get_pointer(
+        &self,
+        object_length: u32,
+        allocator: &Function,
+    ) -> Result<i32, MemoryAllocationError> {
         if self.length.load(Ordering::SeqCst) >= object_length {
             return Ok(self.pointer.load(Ordering::SeqCst));
         }
         let pointer = allocator
             .call(&[Value::I32(object_length as i32)])
             .map_err(MemoryAllocationError::CantAllocate)?;
-        let pointer= pointer[0].i32().ok_or(MemoryAllocationError::InvalidReturnType)?;
+        let pointer = pointer[0]
+            .i32()
+            .ok_or(MemoryAllocationError::InvalidReturnType)?;
         self.length.store(object_length, Ordering::SeqCst);
         self.pointer.store(pointer, Ordering::SeqCst);
         Ok(pointer)
     }
-    
-    // This function writes an object to WASM memory returning a pointer and a length. Will realloc the buffer is not wide enough
-    pub fn write_data<T: Serialize>(&self, memory: &Memory, allocator: &Function ,object: &T) -> Result<(i32,u32),PluginModuleError> {
-        self.write_bytes(memory,allocator,&bincode::serialize(object).map_err(PluginModuleError::Encoding)?)
+
+    // This function writes an object to WASM memory returning a pointer and a
+    // length. Will realloc the buffer is not wide enough
+    pub fn write_data<T: Serialize>(
+        &self,
+        memory: &Memory,
+        allocator: &Function,
+        object: &T,
+    ) -> Result<(i32, u32), PluginModuleError> {
+        self.write_bytes(
+            memory,
+            allocator,
+            &bincode::serialize(object).map_err(PluginModuleError::Encoding)?,
+        )
     }
 
-    // This function writes an raw bytes to WASM memory returning a pointer and a length. Will realloc the buffer is not wide enough
-    pub fn write_bytes(&self, memory: &Memory, allocator: &Function ,array: &[u8]) -> Result<(i32,u32),PluginModuleError> {
+    // This function writes an raw bytes to WASM memory returning a pointer and a
+    // length. Will realloc the buffer is not wide enough
+    pub fn write_bytes(
+        &self,
+        memory: &Memory,
+        allocator: &Function,
+        array: &[u8],
+    ) -> Result<(i32, u32), PluginModuleError> {
         let len = array.len();
-        let mem_position = self.get_pointer(len as u32, allocator).map_err(PluginModuleError::MemoryAllocation)? as usize;
+        let mem_position = self
+            .get_pointer(len as u32, allocator)
+            .map_err(PluginModuleError::MemoryAllocation)? as usize;
         memory.view()[mem_position..mem_position + len]
             .iter()
             .zip(array.iter())
@@ -52,9 +108,14 @@ impl MemoryManager {
     }
 }
 
-// This function read data from memory at a position with the array length and converts it to an object using bincode
-pub fn read_data<T: DeserializeOwned>(memory: &Memory, position: i32, length: u32) -> Result<T, bincode::Error> {
-    bincode::deserialize(&read_bytes(memory,position,length))
+// This function read data from memory at a position with the array length and
+// converts it to an object using bincode
+pub fn read_data<T: DeserializeOwned>(
+    memory: &Memory,
+    position: i32,
+    length: u32,
+) -> Result<T, bincode::Error> {
+    bincode::deserialize(&read_bytes(memory, position, length))
 }
 
 // This function read raw bytes from memory at a position with the array length
@@ -63,4 +124,4 @@ pub fn read_bytes(memory: &Memory, position: i32, length: u32) -> Vec<u8> {
         .iter()
         .map(|x| x.get())
         .collect::<Vec<_>>()
-}
\ No newline at end of file
+}
diff --git a/common/sys/src/plugin/mod.rs b/common/sys/src/plugin/mod.rs
index c393dacf13..2d2c0a8342 100644
--- a/common/sys/src/plugin/mod.rs
+++ b/common/sys/src/plugin/mod.rs
@@ -1,7 +1,7 @@
 pub mod errors;
+pub mod memory_manager;
 pub mod module;
 pub mod wasm_env;
-pub mod memory_manager;
 
 use common::assets::ASSETS_PATH;
 use serde::{Deserialize, Serialize};
diff --git a/common/sys/src/plugin/module.rs b/common/sys/src/plugin/module.rs
index fe314936cc..a150d5af03 100644
--- a/common/sys/src/plugin/module.rs
+++ b/common/sys/src/plugin/module.rs
@@ -1,19 +1,19 @@
-use std::{collections::HashSet, convert::TryInto, marker::PhantomData, sync::{Arc, Mutex, atomic::AtomicI32}};
 
-use specs::World;
-use wasmer::{
-    imports, Cranelift, Function, Instance, Memory, Module,
-    Store, Value, JIT,
-};
+use std::{collections::HashSet, convert::TryInto, marker::PhantomData, sync::{Arc, Mutex}};
 
-use super::{errors::{PluginError, PluginModuleError}, memory_manager::{self, MemoryManager}, wasm_env::HostFunctionEnvironement};
+use common::{comp::Player, uid::UidAllocator};
+use common_net::sync::WorldSyncExt;
+use specs::{World, WorldExt, saveload::MarkerAllocator};
+use wasmer::{imports, Cranelift, Function, Instance, Memory, Module, Store, Value, JIT};
 
-use plugin_api::{Action, Event};
+use super::{errors::{PluginError, PluginModuleError}, memory_manager::{self, EcsAccessManager, MemoryManager}, wasm_env::HostFunctionEnvironement};
+
+use plugin_api::{Action, Event, Retreive};
 
 #[derive(Clone)]
 // This structure represent the WASM State of the plugin.
 pub struct PluginModule {
-    ecs: Arc<AtomicI32>,
+    ecs: Arc<EcsAccessManager>,
     wasm_state: Arc<Mutex<Instance>>,
     memory_manager: Arc<MemoryManager>,
     events: HashSet<String>,
@@ -43,13 +43,42 @@ impl PluginModule {
             });
         }
 
-        let ecs = Arc::new(AtomicI32::new(i32::MAX));
-        let memory_manager = Arc::new(MemoryManager::new());
+        fn raw_retreive_action(env: &HostFunctionEnvironement, ptr: u32, len: u32) -> i64 {
+
+            println!("HOST DEBUG 1");
+            // TODO: Handle correctly the error
+            let data: Retreive = env.read_data(ptr as _, len).unwrap();
+            println!("HOST DEBUG 2");
+
+            let out = match data {
+                Retreive::GetEntityName(e) => {
+                    println!("HOST DEBUG 3 {:?}",env.ecs.get().is_some());
+                    let world = env.ecs.get().expect("Can't get entity name because ECS pointer isn't set");
+                    println!("HOST DEBUG 4 {}",world.has_value::<UidAllocator>());
+                    println!("HOST DEBUG 5 {:?}",&*world.read_resource::<UidAllocator>());
+                    let player = world.read_resource::<UidAllocator>().retrieve_entity_internal(e.0).expect("Invalid uid");
+                    println!("HOST DEBUG 6");
+                    format!("{:?}",world.read_component::<Player>().get(player))
+                }
+            };
+            println!("{}",out);
+            let (ptr,len) = env.write_data(&out).unwrap();
+            to_i64(ptr, len as _)
+        }
+
+        fn dbg(a: i32) {
+            println!("WASM DEBUG: {}",a);
+        }
+
+        let ecs = Arc::new(EcsAccessManager::default());
+        let memory_manager = Arc::new(MemoryManager::default());
 
         // Create an import object.
         let import_object = imports! {
             "env" => {
                 "raw_emit_actions" => Function::new_native_with_env(&store, HostFunctionEnvironement::new(name.clone(), ecs.clone(),memory_manager.clone()), raw_emit_actions),
+                "raw_retreive_action" => Function::new_native_with_env(&store, HostFunctionEnvironement::new(name.clone(), ecs.clone(),memory_manager.clone()), raw_retreive_action),
+                "dbg" => Function::new_native(&store, dbg),
             }
         };
 
@@ -59,8 +88,16 @@ impl PluginModule {
         Ok(Self {
             memory_manager,
             ecs,
-            memory: instance.exports.get_memory("memory").map_err(PluginModuleError::MemoryUninit)?.clone(),
-            allocator: instance.exports.get_function("wasm_prepare_buffer").map_err(PluginModuleError::MemoryUninit)?.clone(),
+            memory: instance
+                .exports
+                .get_memory("memory")
+                .map_err(PluginModuleError::MemoryUninit)?
+                .clone(),
+            allocator: instance
+                .exports
+                .get_function("wasm_prepare_buffer")
+                .map_err(PluginModuleError::MemoryUninit)?
+                .clone(),
             events: instance
                 .exports
                 .iter()
@@ -86,21 +123,17 @@ impl PluginModule {
             return None;
         }
         // Store the ECS Pointer for later use in `retreives`
-        self.ecs.store((&ecs) as *const _ as i32, std::sync::atomic::Ordering::SeqCst);
-        let bytes = {
+        let bytes = match self.ecs.execute_with(ecs, || {
             let mut state = self.wasm_state.lock().unwrap();
-            match execute_raw(self,&mut state,event_name,&request.bytes) {
-                Ok(e) => e,
-                Err(e) => return Some(Err(e)),
-            }
+            execute_raw(self, &mut state, event_name, &request.bytes)
+        }) {
+            Ok(e) => e,
+            Err(e) => return Some(Err(e)),
         };
-        // Remove the ECS Pointer to avoid UB
-        self.ecs.store(i32::MAX, std::sync::atomic::Ordering::SeqCst);
         Some(bincode::deserialize(&bytes).map_err(PluginModuleError::Encoding))
     }
 }
 
-
 // This structure represent a Pre-encoded event object (Useful to avoid
 // reencoding for each module in every plugin)
 pub struct PreparedEventQuery<T> {
@@ -122,9 +155,18 @@ impl<T: Event> PreparedEventQuery<T> {
     }
 }
 
-fn from_i64(i: i64) -> (i32,i32) {
+fn from_i64(i: i64) -> (i32, i32) {
     let i = i.to_le_bytes();
-    (i32::from_le_bytes(i[0..4].try_into().unwrap()),i32::from_le_bytes(i[4..8].try_into().unwrap()))
+    (
+        i32::from_le_bytes(i[0..4].try_into().unwrap()),
+        i32::from_le_bytes(i[4..8].try_into().unwrap()),
+    )
+}
+
+pub fn to_i64(a: i32, b: i32) -> i64 {
+    let a = a.to_le_bytes();
+    let b = b.to_le_bytes();
+    i64::from_le_bytes([a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]])
 }
 
 // This function is not public because this function should not be used without
@@ -136,10 +178,13 @@ fn execute_raw(
     event_name: &str,
     bytes: &[u8],
 ) -> Result<Vec<u8>, PluginModuleError> {
+    // This write into memory `bytes` using allocation if necessary returning a
+    // pointer and a length
 
-    // This write into memory `bytes` using allocation if necessary returning a pointer and a length
-
-    let (mem_position,len) = module.memory_manager.write_bytes(&module.memory, &module.allocator, bytes)?;
+    let (mem_position, len) =
+        module
+            .memory_manager
+            .write_bytes(&module.memory, &module.allocator, bytes)?;
 
     // This gets the event function from module exports
 
@@ -153,16 +198,23 @@ fn execute_raw(
     let function_result = func
         .call(&[Value::I32(mem_position as i32), Value::I32(len as i32)])
         .map_err(PluginModuleError::RunFunction)?;
-    
-    // Waiting for `multi-value` to be added to LLVM. So we encode the two i32 as an i64
 
-    let (pointer,length) = from_i64(function_result[0]
-        .i64()
-        .ok_or_else(PluginModuleError::InvalidArgumentType)?);
+    // Waiting for `multi-value` to be added to LLVM. So we encode the two i32 as an
+    // i64
+
+    let (pointer, length) = from_i64(
+        function_result[0]
+            .i64()
+            .ok_or_else(PluginModuleError::InvalidArgumentType)?,
+    );
 
     // We read the return object and deserialize it
 
-    Ok(memory_manager::read_bytes(&module.memory, pointer, length as u32))
+    Ok(memory_manager::read_bytes(
+        &module.memory,
+        pointer,
+        length as u32,
+    ))
 }
 
 fn handle_actions(actions: Vec<Action>) {
diff --git a/common/sys/src/plugin/wasm_env.rs b/common/sys/src/plugin/wasm_env.rs
index fc332fc505..ddacc968b2 100644
--- a/common/sys/src/plugin/wasm_env.rs
+++ b/common/sys/src/plugin/wasm_env.rs
@@ -1,22 +1,23 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicI32;
+use std::sync::{atomic::AtomicI32, Arc};
 
-use serde::{Serialize, de::DeserializeOwned};
+use serde::{de::DeserializeOwned, Serialize};
 use wasmer::{Function, HostEnvInitError, Instance, LazyInit, Memory, WasmerEnv};
 
-use super::{errors::PluginModuleError, memory_manager::{self, MemoryManager}};
+use super::{errors::PluginModuleError, memory_manager::{self, EcsAccessManager, MemoryManager}};
 
 #[derive(Clone)]
 pub struct HostFunctionEnvironement {
-    pub ecs: Arc<AtomicI32>, // This represent the pointer to the ECS object (set to i32::MAX if to ECS is availible)
+    pub ecs: Arc<EcsAccessManager>, /* This represent the pointer to the ECS object (set to i32::MAX if
+                              * to ECS is availible) */
     pub memory: LazyInit<Memory>, // This object represent the WASM Memory
     pub allocator: LazyInit<Function>, // Linked to: wasm_prepare_buffer
-    pub memory_manager: Arc<MemoryManager>, // This object represent the current buffer size and pointer 
+    pub memory_manager: Arc<MemoryManager>, /* This object represent the current buffer size and
+                                             * pointer */
     pub name: String, // This represent the plugin name
 }
 
 impl HostFunctionEnvironement {
-    pub fn new(name: String,ecs: Arc<AtomicI32>,memory_manager: Arc<MemoryManager>) -> Self {
+    pub fn new(name: String, ecs: Arc<EcsAccessManager>, memory_manager: Arc<MemoryManager>) -> Self {
         Self {
             memory_manager,
             ecs,
@@ -26,13 +27,23 @@ impl HostFunctionEnvironement {
         }
     }
 
-    // This function is a safe interface to WASM memory that writes data to the memory returning a pointer and length
-    pub fn write_data<T: Serialize>(&self, object: &T) -> Result<(i32,u32),PluginModuleError> {
-        self.memory_manager.write_data(self.memory.get_ref().unwrap(), self.allocator.get_ref().unwrap(), object)
+    // This function is a safe interface to WASM memory that writes data to the
+    // memory returning a pointer and length
+    pub fn write_data<T: Serialize>(&self, object: &T) -> Result<(i32, u32), PluginModuleError> {
+        self.memory_manager.write_data(
+            self.memory.get_ref().unwrap(),
+            self.allocator.get_ref().unwrap(),
+            object,
+        )
     }
 
-    // This function is a safe interface to WASM memory that reads memory from pointer and length returning an object
-    pub fn read_data<T: DeserializeOwned>(&self, position: i32, length: u32) -> Result<T, bincode::Error> {
+    // This function is a safe interface to WASM memory that reads memory from
+    // pointer and length returning an object
+    pub fn read_data<T: DeserializeOwned>(
+        &self,
+        position: i32,
+        length: u32,
+    ) -> Result<T, bincode::Error> {
         memory_manager::read_data(self.memory.get_ref().unwrap(), position, length)
     }
 }
@@ -41,8 +52,11 @@ impl WasmerEnv for HostFunctionEnvironement {
     fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
         let memory = instance.exports.get_memory("memory").unwrap();
         self.memory.initialize(memory.clone());
-        let allocator = instance.exports.get_function("wasm_prepare_buffer").expect("Can't get allocator");
+        let allocator = instance
+            .exports
+            .get_function("wasm_prepare_buffer")
+            .expect("Can't get allocator");
         self.allocator.initialize(allocator.clone());
         Ok(())
     }
-}
\ No newline at end of file
+}
diff --git a/common/sys/src/state.rs b/common/sys/src/state.rs
index a58cdfd26f..3f0bad997a 100644
--- a/common/sys/src/state.rs
+++ b/common/sys/src/state.rs
@@ -208,12 +208,14 @@ impl State {
         #[cfg(feature = "plugins")]
         ecs.insert(match PluginMgr::from_assets() {
             Ok(plugin_mgr) => {
-                if let Err(e) = plugin_mgr
-                    .execute_event(&ecs,"on_load", &plugin_api::event::PluginLoadEvent { game_mode: match game_mode {
-                        resources::GameMode::Server => plugin_api::GameMode::Server,
-                        resources::GameMode::Client => plugin_api::GameMode::Client,
-                        resources::GameMode::Singleplayer => plugin_api::GameMode::Singleplayer,
-                    } })
+                if let Err(e) =
+                    plugin_mgr.execute_event(&ecs, "on_load", &plugin_api::event::PluginLoadEvent {
+                        game_mode: match game_mode {
+                            resources::GameMode::Server => plugin_api::GameMode::Server,
+                            resources::GameMode::Client => plugin_api::GameMode::Client,
+                            resources::GameMode::Singleplayer => plugin_api::GameMode::Singleplayer,
+                        },
+                    })
                 {
                     tracing::error!(?e, "Failed to run plugin init");
                     tracing::info!(
diff --git a/plugin/api/Cargo.toml b/plugin/api/Cargo.toml
index db865e87e5..84d8e9b270 100644
--- a/plugin/api/Cargo.toml
+++ b/plugin/api/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2018"
 
 [dependencies]
 serde = { version = "1.0.118", features = ["derive"] }
+common = { package = "veloren-common", path = "../../common", features = ["no-assets"] }
diff --git a/plugin/api/src/lib.rs b/plugin/api/src/lib.rs
index 510169de17..ffaf761e94 100644
--- a/plugin/api/src/lib.rs
+++ b/plugin/api/src/lib.rs
@@ -1,8 +1,7 @@
-
-use std::fmt;
-
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
 
+pub use common::{resources::GameMode, uid::Uid};
+
 #[derive(Deserialize, Serialize, Debug)]
 pub enum Action {
     ServerClose,
@@ -20,35 +19,6 @@ pub trait Event: Serialize + DeserializeOwned + Send + Sync {
     type Response: Serialize + DeserializeOwned + Send + Sync;
 }
 
-#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
-pub struct Uid(pub u64);
-
-impl Into<u64> for Uid {
-    fn into(self) -> u64 { self.0 }
-}
-
-impl From<u64> for Uid {
-    fn from(uid: u64) -> Self { Self(uid) }
-}
-
-impl fmt::Display for Uid {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
-}
-
-#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
-pub enum GameMode {
-    /// The game is being played in server mode (i.e: the code is running
-    /// server-side)
-    Server,
-    /// The game is being played in client mode (i.e: the code is running
-    /// client-side)
-    Client,
-    /// The game is being played in singleplayer mode (i.e: both client and
-    /// server at once)
-    // To be used later when we no longer start up an entirely new server for singleplayer
-    Singleplayer,
-}
-
 pub mod event {
     use super::*;
     use serde::{Deserialize, Serialize};
diff --git a/plugin/rt/examples/hello.rs b/plugin/rt/examples/hello.rs
index 2f596f1a02..6bf7c836a9 100644
--- a/plugin/rt/examples/hello.rs
+++ b/plugin/rt/examples/hello.rs
@@ -3,7 +3,7 @@ use veloren_plugin_rt::{
     *,
 };
 
-#[veloren_plugin_rt::event_handler]
+#[event_handler]
 pub fn on_load(load: PluginLoadEvent) {
     match load.game_mode {
         GameMode::Server => emit_action(Action::Print("Hello, server!".to_owned())),
@@ -15,13 +15,11 @@ pub fn on_load(load: PluginLoadEvent) {
 #[event_handler]
 pub fn on_command_testplugin(command: ChatCommandEvent) -> Result<Vec<String>, String> {
     Ok(vec![format!(
-        "Player of id {:?} sended command with args {:?}",
-        command.player, command.command_args
+        "Player of id {:?} named {} sended command with args {:?}",
+        command.player, command.player.get_entity_name(), command.command_args
     )])
 }
 
-
-
 #[event_handler]
 pub fn on_player_join(input: PlayerJoinEvent) -> PlayerJoinResult {
     emit_action(Action::PlayerSendMessage(
diff --git a/plugin/rt/src/lib.rs b/plugin/rt/src/lib.rs
index d8aa0d4006..c5872f1d05 100644
--- a/plugin/rt/src/lib.rs
+++ b/plugin/rt/src/lib.rs
@@ -4,6 +4,8 @@ pub extern crate plugin_derive;
 
 pub mod retreive;
 
+pub use retreive::*;
+
 use std::convert::TryInto;
 
 pub use retreive::*;
@@ -16,22 +18,28 @@ use serde::{de::DeserializeOwned, Serialize};
 #[cfg(target_arch = "wasm32")]
 extern "C" {
     fn raw_emit_actions(ptr: *const u8, len: usize);
-    //fn raw_retreive_action(ptr: *const u8, len: usize) -> (i32, u32);
+    fn raw_retreive_action(ptr: *const u8, len: usize) -> i64;
+    pub fn dbg(i: i32);
 }
 
-// pub fn retreive_action<T: DeserializeOwned>(_actions: &api::Retreive) -> Result<T,bincode::Error> {
-//     #[cfg(target_arch = "wasm32")]
-//     {
-//         let ret = bincode::serialize(&_actions).expect("Can't serialize action in emit");
-//         unsafe {
-//             let (ptr,len) = raw_retreive_action(ret.as_ptr(), ret.len());
-//             let a = ::std::slice::from_raw_parts(ptr as _, len as _);
-//             bincode::deserialize(&a)
-//         }
-//     }
-//     #[cfg(not(target_arch = "wasm32"))]
-//     unreachable!()
-// }
+pub fn retreive_action<T: DeserializeOwned>(_actions: &api::Retreive) -> Result<T,bincode::Error> {     
+    #[cfg(target_arch = "wasm32")]
+    {
+        unsafe{dbg(0);}
+        let ret = bincode::serialize(&_actions).expect("Can't serialize action in emit");  
+        unsafe{dbg(1);}     
+        unsafe {
+            dbg(2);
+            let (ptr,len) = from_i64(raw_retreive_action(ret.as_ptr(), ret.len()));
+            dbg(3);
+            let a = ::std::slice::from_raw_parts(ptr as _, len as _);
+            dbg(4);
+            bincode::deserialize(&a)
+        }
+    }
+    #[cfg(not(target_arch = "wasm32"))]
+    unreachable!()
+}
 
 pub fn emit_action(action: api::Action) { emit_actions(vec![action]) }
 
@@ -53,10 +61,18 @@ where
     bincode::deserialize(slice).map_err(|_| "Failed to deserialize function input")
 }
 
+pub fn from_i64(i: i64) -> (i32, i32) {
+    let i = i.to_le_bytes();
+    (
+        i32::from_le_bytes(i[0..4].try_into().unwrap()),
+        i32::from_le_bytes(i[4..8].try_into().unwrap()),
+    )
+}
+
 pub fn to_i64(a: i32, b: i32) -> i64 {
     let a = a.to_le_bytes();
     let b = b.to_le_bytes();
-    i64::from_le_bytes([a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3]])
+    i64::from_le_bytes([a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]])
 }
 
 pub fn write_output(value: impl Serialize) -> i64 {
diff --git a/plugin/rt/src/retreive.rs b/plugin/rt/src/retreive.rs
index 1a805307ed..b214009776 100644
--- a/plugin/rt/src/retreive.rs
+++ b/plugin/rt/src/retreive.rs
@@ -1,13 +1,15 @@
 use crate::api::Retreive;
 
-trait GetEntityName {
+pub trait GetEntityName {
     fn get_entity_name(&self) -> String;
 }
 
 impl GetEntityName for crate::api::event::Player {
-
     fn get_entity_name(&self) -> String {
-        // crate::retreive_action(&Retreive::GetEntityName(self.id)).expect("Can't get entity name")
-        String::new()
+        #[cfg(target_arch = "wasm32")]
+        unsafe {
+            crate::dbg(-1);
+        }
+        crate::retreive_action(&Retreive::GetEntityName(self.id)).expect("Can't get entity name")
     }
-}
\ No newline at end of file
+}
diff --git a/server/src/lib.rs b/server/src/lib.rs
index c45175d2a8..70a3bd2aec 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -1037,12 +1037,15 @@ impl Server {
                         command: kwd.clone(),
                         command_args: args.split(' ').map(|x| x.to_owned()).collect(),
                         player: plugin_api::event::Player {
-                            id: plugin_api::Uid((self
-                                .state
-                                .ecs()
-                                .read_storage::<Uid>()
-                                .get(entity)
-                                .expect("Can't get player UUID [This should never appen]")).0),
+                            id: plugin_api::Uid(
+                                (self
+                                    .state
+                                    .ecs()
+                                    .read_storage::<Uid>()
+                                    .get(entity)
+                                    .expect("Can't get player UUID [This should never appen]"))
+                                .0,
+                            ),
                         },
                     },
                 );