diff --git a/assets/tilemap.png b/assets/tilemap.png
new file mode 100644
index 0000000000000000000000000000000000000000..48ec4457cb7f48a2078e595d0f56a72cc4239534
Binary files /dev/null and b/assets/tilemap.png differ
diff --git a/source/engine/graphics/front/module/TileArray_Module.cpp b/source/engine/graphics/front/module/TileArray_Module.cpp
index b88a30dc6e86bc7c7c8574e9b59e4f3c54eb7ca4..cdc258fba5b57477d0256c5bd4f8e091b21095ff 100644
--- a/source/engine/graphics/front/module/TileArray_Module.cpp
+++ b/source/engine/graphics/front/module/TileArray_Module.cpp
@@ -34,10 +34,10 @@ namespace megu {
 
         size_t count = 0;
 
-        for(size_t y = 0; y < vertexArray.height(); ++y) {
-            for(size_t x = 0; x < vertexArray.width(); ++x) {
+        for(size_t x = 0; x < vertexArray.width(); ++x) {
+            for(size_t y = 0; y < vertexArray.height(); ++y) {
                 uOffsets.push_back(glm::translate(glm::mat4(1.f), {x, y, 0.f}));
-                uUvs.push_back(vertexArray.uvs()[y][x]);
+                uUvs.push_back(vertexArray.uvs()[x][y]);
 
                 if(count > 128) {
                     this->_program.setUniform("uOffsets", uOffsets);
diff --git a/source/engine/graphics/front/object/Renderable.hpp b/source/engine/graphics/front/object/Renderable.hpp
index 4787c74117aa4c4f1f96ddc2d5f1b6cb9008d965..e31acdfc5fb3a7c54093ed70ebda3de1d27a7d92 100644
--- a/source/engine/graphics/front/object/Renderable.hpp
+++ b/source/engine/graphics/front/object/Renderable.hpp
@@ -57,7 +57,7 @@ namespace megu {
                     return typeid(T);
                 }
 
-                T _objects;
+                T & _objects;
                 Module<T> * _module;
             };
         
diff --git a/source/engine/graphics/front/object/Sprite.cpp b/source/engine/graphics/front/object/Sprite.cpp
index 22bcf5fc028122a04456b3e04eb7e18a2d51b2ba..d9dd26c1084e14d70e7a6af5514b3233298a624e 100644
--- a/source/engine/graphics/front/object/Sprite.cpp
+++ b/source/engine/graphics/front/object/Sprite.cpp
@@ -1,9 +1,14 @@
 #include "Sprite.hpp"
 
 namespace megu {
-    Sprite::Sprite(const std::filesystem::path & path)
+    Sprite::Sprite(const std::filesystem::path & path, bool flip)
     : _frame(0, 0, 0, 0) {
-        this->load(path, true);
+        this->load(path, flip);
+    }
+
+    Sprite::Sprite(const std::filesystem::path & path, const Frame & frame, bool flip)
+    : _frame(frame) {
+        this->load(path, flip);
     }
 
     void Sprite::load(const std::filesystem::path & path, bool flip) {
diff --git a/source/engine/graphics/front/object/Sprite.hpp b/source/engine/graphics/front/object/Sprite.hpp
index 5601f375fa46e8e0a10db7f23fa9c294fef3f719..43b9a8b88e40f24e82e0e39e38d9554ef3049932 100644
--- a/source/engine/graphics/front/object/Sprite.hpp
+++ b/source/engine/graphics/front/object/Sprite.hpp
@@ -13,7 +13,8 @@ namespace megu {
         public:
             using Frame =  glm::vec4;
 
-            Sprite(const std::filesystem::path &);
+            Sprite(const std::filesystem::path &, bool = true);
+            Sprite(const std::filesystem::path &, const Frame &, bool = true);
 
             inline void setFrame(const Frame & frame) {this->_frame = frame;}
 
@@ -21,7 +22,15 @@ namespace megu {
             inline void setOrigine(const Vec2 & pos)    {this->_transformation.setOrigine(pos.x, pos.y);}
             inline void setSize(const Vec2 & size)      {this->_transformation.setScaling(size.x, size.y);}
             inline void setRotation(float a)            {this->_transformation.setRotation(a, Transformable::Axis::Z);}
-            inline void setLayer(float l)               {this->_transformation.setZ(l);}
+
+            inline const Vec3 & position()  const        {return this->_transformation.position();}
+            inline const Vec3 & origine()   const        {return this->_transformation.origine();}
+            inline const Vec3 & rotation()  const        {return this->_transformation.rotation();}
+            inline const Vec2 & size()      const        {return Vec2(this->_transformation.scaling().x, this->_transformation.scaling().y);}
+            
+            inline float x() const {return this->_transformation.x();}
+            inline float y() const {return this->_transformation.y();}
+            inline float z() const {return this->_transformation.z();}
 
             inline void move(const Vec2 & pos)          {this->_transformation.move({pos.x, pos.y, 0.f});}
             inline void scale(const Vec2 & size)        {this->_transformation.scale({size.x, size.y, 0.f});}
diff --git a/source/engine/graphics/front/object/TileArray.cpp b/source/engine/graphics/front/object/TileArray.cpp
index bf10b68084dc9acf00cce43b77f8266d6b215d84..9e1d4310a176bfb62bee19378e003a42fc6ce60a 100644
--- a/source/engine/graphics/front/object/TileArray.cpp
+++ b/source/engine/graphics/front/object/TileArray.cpp
@@ -11,17 +11,12 @@ namespace megu {
         float twidth = static_cast<float>(this->_texture.width());
         float theight = static_cast<float>(this->_texture.height());
 
-        std::cout << twidth << "/" << theight << std::endl;
-
-        for(size_t y = 0; y < height; ++y) {
+        for(size_t x = 0; x < width; ++x) {
             std::vector<glm::vec4> rows;
-            for(size_t x = 0; x < width; ++x) {
+            for(size_t y = 0; y < height; ++y) {
                 rows.push_back({0.f, 0.f, twidth, theight});
             }
             this->_uvs.push_back(rows);
         }
-
-        std::cout << this->_uvs.size() << std::endl;
-        this->_transformation.scale({size, size, 1.f});
     }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/front/object/TileArray.hpp b/source/engine/graphics/front/object/TileArray.hpp
index f88cb682b3b5055479cd4be3f5251a35f2fdbdd4..94e66b7858bca37a1e04ee36db955f7e63c090d8 100644
--- a/source/engine/graphics/front/object/TileArray.hpp
+++ b/source/engine/graphics/front/object/TileArray.hpp
@@ -29,10 +29,13 @@ namespace megu {
             inline size_t height() const {return this->_height;}
             inline float size() const {return this->_size;}
 
+            inline void setUv(size_t x, size_t y, const glm::vec4 & uv) {this->_uvs[y][x] = uv;}
+
             inline const Transformable & transformation()  const {return this->_transformation;}
             inline const Texture & texture() const {return this->_texture;}
 
             inline const std::vector<std::vector<glm::vec4>> & uvs() const {return this->_uvs;}
+            std::vector<glm::vec4> & operator[](size_t index) {return this->_uvs[index];} 
 
         private:
             Transformable _transformation;
diff --git a/source/engine/utility/type.hpp b/source/engine/utility/type.hpp
index c1b5340cdc62058750b05941a7db72cf79073a05..62e6bd50cf24a87f88235131e74b44d62b95b56c 100644
--- a/source/engine/utility/type.hpp
+++ b/source/engine/utility/type.hpp
@@ -5,7 +5,7 @@
 
 namespace megu {
     using Vec2  = glm::vec2;
-    using Vec3  = glm::vec4;
+    using Vec3  = glm::vec3;
     using Vec4  = glm::vec4;
     using Color = glm::vec4;
 
diff --git a/source/game/Game.cpp b/source/game/Game.cpp
index 1920d7af3e96a4f1502d5f694bda8054c0e33db3..b9c38e1c3c5e66585bcc6f710341838a0fa1189a 100644
--- a/source/game/Game.cpp
+++ b/source/game/Game.cpp
@@ -26,9 +26,9 @@ namespace megu::game {
             megu::game::Object object(path);
             kernel.add(&object);
             
-            megu::game::Object object2(path);
+            /*megu::game::Object object2(path);
             object2.tmp_setPos(20, 0);
-            kernel.add(&object2);
+            kernel.add(&object2);*/
             /* ------ */
 
             while(window.isOpen()) {
diff --git a/source/game/object/Test.cpp b/source/game/object/Test.cpp
index 0dbade9f6fcb3948a43bfccc476b630274027f42..bcdf5552f1f0b80412255c096cb005d84eb0b431 100644
--- a/source/game/object/Test.cpp
+++ b/source/game/object/Test.cpp
@@ -2,5 +2,13 @@
 
 namespace megu::game {
     Object::Object(std::filesystem::path & path)
-    : _physic(0, 0, 64, 64), _graphic(path) {}
+    : _physic(0, 0, 64, 64), _graphic(path), _map("assets/tilemap.png", 2, 2, 16.f, 16) {
+        this->_graphic.setFrame({0.f, 0.f, 51.f, 98.f});
+        this->_graphic.setSize({51.f, 98.f});
+
+        this->_map.setValue(0, 0, 1);
+        this->_map.setValue(1, 0, 1);
+        this->_map.setValue(0, 1, 2);
+        this->_map.setValue(1, 1, 1);
+    }
 }
\ No newline at end of file
diff --git a/source/game/object/Test.hpp b/source/game/object/Test.hpp
index 94fb9a655212d8fb3814073fa03c596e63737a24..cd3854e79afa448ea19b23e72057695d22a4d2c9 100644
--- a/source/game/object/Test.hpp
+++ b/source/game/object/Test.hpp
@@ -3,21 +3,19 @@
 #include <kernel/back/props/Props.hpp>
 #include <kernel/front/component/physic/Fixed.hpp>
 #include <kernel/front/component/graphic/Sprite.hpp>
+#include <kernel/front/component/graphic/TileMap.hpp>
 
 namespace megu::game {
     class Object : public kernel::Props {
         public:
             Object(std::filesystem::path &);
 
-            inline kernel::Physical<kernel::PhysicEngine> & getPhysicComponent() override {return this->_physic;}
-            inline kernel::Graphical<kernel::GraphicEngine> & getGraphicComponent() override {return this->_graphic;}
-
-            inline void tmp_setPos(float x, float y) {
-                this->_graphic.tmp_setPos(x, y);
-            }
+            inline kernel::Physical<kernel::PhysicEngine> * getPhysicComponent() override {return &this->_physic;}
+            inline kernel::Graphical<kernel::GraphicEngine> * getGraphicComponent() override {return &this->_map;}
 
         private:
             kernel::Fixed _physic;
             kernel::Sprite _graphic;
+            kernel::Tilemap _map;
     };
 }
\ No newline at end of file
diff --git a/source/kernel/back/engine/GraphicEngine.cpp b/source/kernel/back/engine/GraphicEngine.cpp
index 6a811a4642d14e9e102084dc5a8ecb2eceea34dc..314f19b55e312e7860d3d1a8c2e22281072c534a 100644
--- a/source/kernel/back/engine/GraphicEngine.cpp
+++ b/source/kernel/back/engine/GraphicEngine.cpp
@@ -4,10 +4,12 @@
 
 namespace megu::kernel {
     GraphicEngine::GraphicEngine(Window & window) 
-    : _engine(window), _renderer(360, 360) {}
+    : _engine(window), _renderer(360, 360), _tmp_ta("assets/textures/Tile_Test_3.png", 1, 1, 32.f) {}
 
     void GraphicEngine::boot(Kernel &) {
         this->_engine.push(0, this->_renderer);
+
+        //this->_engine.push(0, 0, this->_tmp_ta, &this->_tmp_mod);
     }
 
     void GraphicEngine::stop(Kernel &) {
diff --git a/source/kernel/back/engine/GraphicEngine.hpp b/source/kernel/back/engine/GraphicEngine.hpp
index f26ef134dfbabd6a1450e421c6c7b83253ab4de2..885d7a5705834f9a3d0bea2f1011e34612b9cc0d 100644
--- a/source/kernel/back/engine/GraphicEngine.hpp
+++ b/source/kernel/back/engine/GraphicEngine.hpp
@@ -7,6 +7,9 @@
 #include <engine/graphics/front/engine/Engine.hpp>
 #include <engine/graphics/front/engine/Renderer.hpp>
 
+#include <engine/graphics/front/module/TileArray_Module.hpp>
+#include <engine/graphics/front/object/TileArray.hpp>
+
 #include <kernel/back/props/Graphical.hpp>
 
 namespace megu::kernel {
@@ -28,5 +31,8 @@ namespace megu::kernel {
         private:
             megu::GraphicEngine _engine;
             megu::Renderer _renderer;
+
+            megu::TileArray _tmp_ta;
+            megu::TileArray_Module _tmp_mod;
     };
 }
\ No newline at end of file
diff --git a/source/kernel/back/linker/GraphicLinker.hpp b/source/kernel/back/linker/GraphicLinker.hpp
index 86b091ab66f611015e7797857522be024a435b64..12d87d04de78f318861350fe7aee28e3f57bd5af 100644
--- a/source/kernel/back/linker/GraphicLinker.hpp
+++ b/source/kernel/back/linker/GraphicLinker.hpp
@@ -1,21 +1,10 @@
 #pragma once
 
 #include "Linker.hpp"
+#include "PriorityPair.hpp"
 #include <kernel/back/engine/GraphicEngine.hpp>
 
 namespace megu::kernel {
-    struct Priority_Pair {
-        Priority layer;
-        Priority object;
-
-        bool operator<(const Priority_Pair & pp) const {
-            if(this->layer == pp.layer) {
-                return this->object < pp.object;
-            }
-            return this->layer < pp.layer;
-        }
-    };
-
     template <class T>
     class GraphicLinker : public Linker<GraphicEngine> {
         public:
diff --git a/source/kernel/back/linker/GraphicLinker.tpp b/source/kernel/back/linker/GraphicLinker.tpp
index 29fe81f69c6382dc874e9aaaa3c0fa37fd4349f2..2fccee83be8fe35cbd9154931ffc995a0cc38e52 100644
--- a/source/kernel/back/linker/GraphicLinker.tpp
+++ b/source/kernel/back/linker/GraphicLinker.tpp
@@ -16,7 +16,7 @@ namespace megu::kernel {
     template <class T>
     void GraphicLinker<T>::link(GraphicEngine & engine) {
         for(const auto & layers : this->_waiting) {
-            engine.get().push(layers.layer, layers.object , this->_objects[layers], this->_module.get());
+            engine.get().push(layers.layer, layers.object, this->_objects[layers], this->_module.get());
         }
 
         this->_waiting.clear();
diff --git a/source/kernel/back/linker/PriorityPair.hpp b/source/kernel/back/linker/PriorityPair.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..091ad26ea15bbe0bdd864aaf6bc265fb6f186f53
--- /dev/null
+++ b/source/kernel/back/linker/PriorityPair.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <engine/utility/Priority.hpp>
+
+namespace megu::kernel {
+    struct Priority_Pair {
+        Priority layer;
+        Priority object;
+
+        bool operator<(const Priority_Pair & pp) const {
+            if(this->layer == pp.layer) {
+                return this->object < pp.object;
+            }
+            return this->layer < pp.layer;
+        }
+    };
+}
\ No newline at end of file
diff --git a/source/kernel/back/linker/UniqueLinker.hpp b/source/kernel/back/linker/UniqueLinker.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9453bab77063af9d17b0f882d7fdb23e0b336649
--- /dev/null
+++ b/source/kernel/back/linker/UniqueLinker.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "Linker.hpp"
+#include "PriorityPair.hpp"
+#include <kernel/back/engine/GraphicEngine.hpp>
+
+namespace megu::kernel {
+    template <class T>
+    class UniqueGraphicLinker : public Linker<GraphicEngine> {
+        public:
+            UniqueGraphicLinker();
+
+            void link(T &, Priority, Priority);
+            void link(GraphicEngine &) override;
+            void setModule(Module<T> *);
+
+            inline bool haveModule() const {return this->_module.get() != nullptr;}
+            inline ref_set<T> & objects() {return this->_object;}
+
+        private:
+            std::unique_ptr<Module<T>> _module;
+            std::map<Priority_Pair, ref_set<T>> _objects;
+            std::set<Priority_Pair> _waiting;
+    };
+}
+
+#include "UniqueLinker.tpp"
\ No newline at end of file
diff --git a/source/kernel/back/linker/UniqueLinker.tpp b/source/kernel/back/linker/UniqueLinker.tpp
new file mode 100644
index 0000000000000000000000000000000000000000..9265d6c5541bf9649a1987a16211ed67fc55cea3
--- /dev/null
+++ b/source/kernel/back/linker/UniqueLinker.tpp
@@ -0,0 +1,31 @@
+#include "UniqueLinker.hpp"
+
+namespace megu::kernel {
+    template <class T>
+    UniqueGraphicLinker<T>::UniqueGraphicLinker() 
+    : _module(nullptr) {}
+
+    template <class T>
+    void UniqueGraphicLinker<T>::link(T & object, Priority l, Priority o) {
+        auto layers = Priority_Pair{l, o};
+
+        this->_objects[layers].insert(object);
+        this->_waiting.insert(layers);
+    }
+
+    template <class T>
+    void UniqueGraphicLinker<T>::link(GraphicEngine & engine) {
+        for(const auto & layers : this->_waiting) {
+            for(auto & object : this->_objects[layers]) {
+                engine.get().push<T>(layers.layer, layers.object, object, this->_module.get());
+            }
+        }
+
+        this->_waiting.clear();
+    }
+
+    template <class T>
+    void UniqueGraphicLinker<T>::setModule(Module<T> * mod) {
+        this->_module = std::unique_ptr<Module<T>>(mod);
+    }
+}
\ No newline at end of file
diff --git a/source/kernel/back/props/Props.hpp b/source/kernel/back/props/Props.hpp
index a83cccac18ef2884b6150416fdc62c42e3605c3f..80dbe5838d0f074d36ca63ab5a4389ccbef855ee 100644
--- a/source/kernel/back/props/Props.hpp
+++ b/source/kernel/back/props/Props.hpp
@@ -10,8 +10,8 @@
 namespace megu::kernel {
     class Props : public Identifiable {
         public:
-            virtual Physical<PhysicEngine> & getPhysicComponent() = 0;
-            virtual Graphical<GraphicEngine> & getGraphicComponent() = 0;
+            virtual Physical<PhysicEngine> * getPhysicComponent() = 0;
+            virtual Graphical<GraphicEngine> * getGraphicComponent() = 0;
             
     };
 }
\ No newline at end of file
diff --git a/source/kernel/front/Kernel.cpp b/source/kernel/front/Kernel.cpp
index c8ce770837a67edeeb6afa842a580c888161ef84..e5ab814bdf790cd1e0af09d2d9f59256fab45a48 100644
--- a/source/kernel/front/Kernel.cpp
+++ b/source/kernel/front/Kernel.cpp
@@ -26,8 +26,14 @@ namespace megu::kernel {
 
     void Kernel::add(Props * props) {
         this->_props[props->id()] = props;
-
-        this->_pEngine.add(*this, props->getPhysicComponent());
-        this->_gEngine.add(*this, props->getGraphicComponent());
+        auto * pComponent = props->getPhysicComponent();
+        if(pComponent != nullptr) {
+            this->_pEngine.add(*this, *pComponent);
+        }
+        
+        auto * gComponent = props->getGraphicComponent();
+        if(gComponent != nullptr) {
+            this->_gEngine.add(*this, *gComponent);
+        }
     }
 }
\ No newline at end of file
diff --git a/source/kernel/front/component/graphic/Sprite.cpp b/source/kernel/front/component/graphic/Sprite.cpp
index a7deac473590ed6e0c8c68825ba6a9bf820ffaa2..c5f506950b5372680b739e35504f0d5c8eb3678c 100644
--- a/source/kernel/front/component/graphic/Sprite.cpp
+++ b/source/kernel/front/component/graphic/Sprite.cpp
@@ -1,26 +1,82 @@
 #include "Sprite.hpp"
 
+//this->_sprite.setFrame({0.f, 0.f, 51.f, 98.f});
+//this->_sprite.setSize({50, 100});
+
 namespace megu::kernel {
     GraphicLinker<megu::Sprite> Sprite::_Linker = GraphicLinker<megu::Sprite>();
 
-    Sprite::Sprite(std::filesystem::path & path)
-    : _sprite(path), _animation(""), _index(0) {
-        this->_sprite.setFrame({0.f, 0.f, 51.f, 98.f});
-        this->_sprite.setSize({50, 100});
+    Sprite::Sprite(const std::filesystem::path & path)
+    : Sprite(path, {0, 0, 0, 0}) {}
 
+    Sprite::Sprite(const std::filesystem::path & path, const Frame & frame)
+    : megu::Sprite(path, frame), _animation(""), _index(0) {
         if(!Sprite::_Linker.haveModule()) {
             Sprite::_Linker.setModule(new Sprite_Module{});
         }
     }
 
-    void Sprite::update(double) {
-        if(!this->_animation.empty()) {
-            this->_sprite.setFrame(this->_frames[this->_animation][this->_index]);
+    const Frame_List & Sprite::getAnimations(const std::string & name) const {
+        if(this->_frames.contains(name)) {
+            return this->_frames.at(name);
+        }
+        throw std::runtime_error("Cannot get inexisting animation");
+    }
+
+    const Frame & Sprite::getFrame(const std::string & name, size_t index) const {
+        auto & frames = this->getAnimations(name);
+        if(frames.size() > index) {
+            return frames.at(index);
+        }
+        throw std::runtime_error("Cannot get inexisting frame");
+    }
+
+    void Sprite::setAnimation(const std::string & name) {
+        if(this->_frames.contains(name)) {
+            this->_animation = name;
+            this->_previous = 0.0;
         }
+        throw std::runtime_error("Cannot set inexisting animation");
+    }
+
+    void Sprite::push(const std::string & name, const Frame_List & frames) {
+        this->_frames[name] = frames;
+    }
+
+    void Sprite::push(const std::string & name, const Frame & frame) {
+        this->_frames[name].push_back(frame);
+    }
+
+    void Sprite::remove(const std::string & name) {
+        if(this->_frames.contains(name)) {
+            this->_frames.erase(name);
+        }
+    }
+
+    void Sprite::remove(const std::string & name, size_t index) {
+        if(this->_frames.contains(name) && this->_frames[name].size() > index) {
+            this->_frames[name].erase(this->_frames[name].begin() + index);
+        }
+    }
+
+    void Sprite::update(double time) {
+        /*if(!this->_animation.empty()) {
+            if(this->_previous == 0.0) {
+                this->setFrame(this->_frames[this->_animation][this->_index]);
+                this->_previous = time;
+            }
+            else {
+                double current = this->_previous - time;
+                if(current > this->_duration) {
+                    this->_index = (this->_index + 1) % this->_frames[this->_animation].size();
+                    this->setFrame(this->_frames[this->_animation][this->_index]);
+                }
+            }
+        }*/
     }
 
     void Sprite::apply(Kernel & kernel, GraphicEngine & engine) {
-        Sprite::_Linker.link(this->_sprite, this->getLayerPriority(), this->getObjectPriority());
+        Sprite::_Linker.link(*this, this->getLayerPriority(), this->getObjectPriority());
         Sprite::_Linker.link(engine);
     }
 }
\ No newline at end of file
diff --git a/source/kernel/front/component/graphic/Sprite.hpp b/source/kernel/front/component/graphic/Sprite.hpp
index 1f1ad3dc168afe5eac70e5eb15a11eb33f3f6607..fbc9f1624166f1bc5067b8e55fb7631f956c8731 100644
--- a/source/kernel/front/component/graphic/Sprite.hpp
+++ b/source/kernel/front/component/graphic/Sprite.hpp
@@ -14,24 +14,37 @@
 
 namespace megu::kernel {
     using Frame_List = std::vector<megu::Sprite::Frame>;
+    using Frame = megu::Sprite::Frame;
 
-    class Sprite : public Graphical<GraphicEngine> {
+    class Sprite : public Graphical<GraphicEngine>, public megu::Sprite {
         public:
-            Sprite(std::filesystem::path &);
+            Sprite(const std::filesystem::path &);
+            Sprite(const std::filesystem::path &, const Frame &);
+
+            inline size_t getCurrentFrameIndex() const {return this->_index;}
+            inline double getDuration() const {return this->_duration;}
+
+            const Frame_List & getAnimations(const std::string &) const;
+            const Frame & getFrame(const std::string &, size_t) const;
+            
+            void setAnimation(const std::string &);
+            void push(const std::string &, const Frame_List & = {});
+            void push(const std::string &, const Frame &);
+
+            void remove(const std::string &);
+            void remove(const std::string &, size_t);
 
             void update(double) override;
             void apply(Kernel &, GraphicEngine &) override;
 
-            inline void tmp_setPos(float x, float y) {
-                this->_sprite.setPosition({x, y});
-            }
+            static const GraphicLinker<megu::Sprite> & linker() {return Sprite::_Linker;}
 
         private:
-            megu::Sprite _sprite;
-
             std::map<std::string, Frame_List> _frames;
             std::string _animation;
             size_t _index;
+            double _duration;
+           double _previous;
 
             static GraphicLinker<megu::Sprite> _Linker;
     };
diff --git a/source/kernel/front/component/graphic/TileMap.cpp b/source/kernel/front/component/graphic/TileMap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..da61dc8f6f9bb9747a2cd813ed68c09cd056f7d5
--- /dev/null
+++ b/source/kernel/front/component/graphic/TileMap.cpp
@@ -0,0 +1,64 @@
+#include "TileMap.hpp"
+
+namespace megu::kernel {
+    UniqueGraphicLinker<TileArray> Tilemap::_Linker = UniqueGraphicLinker<TileArray>();
+
+    Tilemap::Tilemap(const std::filesystem::path & path, size_t width, size_t height, float size, size_t lenght) 
+    : TileArray(path, width , height, size), _tileSize(lenght) {
+        if(lenght % width != 0 && lenght % height != 0) {
+            throw std::runtime_error("Tilemap dimension not matching tiles size.");
+        }
+
+        size_t i = 0, j = 0;
+        for(size_t x = 0; x < this->texture().width(); x += this->_tileSize) {
+            j = 0;
+            for(size_t y = 0; y < this->texture().height(); y += this->_tileSize) {
+                this->_tilesPosition.push_back({j * this->_tileSize, i * this->_tileSize});
+                ++j;
+            }
+            ++i;
+        }
+        
+        i = 0;
+        for(size_t x = 0; x < width * this->_tileSize; x += this->_tileSize) {
+            this->_tilesValue.push_back({});
+            for(size_t y = 0; y < height * this->_tileSize; y += this->_tileSize) {
+                this->_tilesValue[i].push_back(0);
+            }
+            ++i;
+        }
+
+        if(!Tilemap::_Linker.haveModule()) {
+           Tilemap::_Linker.setModule(new TileArray_Module{});
+        }
+
+        this->setSize({width * size, height * size});
+    }
+
+    void Tilemap::setValue(size_t x, size_t y, size_t value) {
+        TilePosition position = this->_tilesPosition[value];
+        glm::vec4 uv = {position.x, 
+                        this->texture().height() - position.y - this->_tileSize, 
+                        this->_tileSize, 
+                        this->_tileSize};
+
+        this->setUv(x, this->width() - 1 - y, uv);
+        this->_tilesValue[x][y] = value;
+    }
+
+    size_t Tilemap::getValue(size_t x, size_t y) {
+        if(this->_tilesValue.size() > x && this->_tilesValue[x].size() > y) {
+            return this->_tilesValue[x][y];
+        }
+        throw std::runtime_error("Tilemap coords out of bound");
+    }
+
+    void Tilemap::update(double time) {
+        //... Peut-être des tiles animées si j'ai le temps 🙌 (spoiler non).
+    }
+
+    void Tilemap::apply(Kernel & kernel, GraphicEngine & engine) {
+        Tilemap::_Linker.link(*this, this->getLayerPriority(), this->getObjectPriority());
+        Tilemap::_Linker.link(engine);
+    }
+}
\ No newline at end of file
diff --git a/source/kernel/front/component/graphic/TileMap.hpp b/source/kernel/front/component/graphic/TileMap.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..38349535010d59c03aade7b4993a3547f6d44365
--- /dev/null
+++ b/source/kernel/front/component/graphic/TileMap.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <map>
+#include <vector>
+
+#include <kernel/back/engine/GraphicEngine.hpp>
+#include <kernel/back/props/Graphical.hpp>
+#include <kernel/back/linker/UniqueLinker.hpp>
+
+#include <engine/graphics/front/object/TileArray.hpp>
+#include <engine/graphics/front/module/TileArray_Module.hpp> 
+
+namespace megu::kernel {
+    class Tilemap : public Graphical<GraphicEngine>, public TileArray {
+        public:
+            struct TilePosition {
+                size_t x = 0;
+                size_t y = 0;
+
+                friend bool operator<(const TilePosition & p1, const TilePosition & p2) {
+                    if(p1.x == p2.x) {
+                        return p1.y < p2.y;
+                    }
+                    return p1.x < p1.y;
+                }
+            };
+
+            Tilemap(const std::filesystem::path &, size_t, size_t, float, size_t);
+
+            void setValue(size_t, size_t, size_t);
+            size_t getValue(size_t, size_t);
+
+            void update(double) override;
+            void apply(Kernel &, GraphicEngine &) override;
+
+        private:
+            std::vector<TilePosition> _tilesPosition;
+            std::vector<std::vector<size_t>> _tilesValue;
+            TileArray_Module _module;
+            size_t _tileSize;
+
+            static UniqueGraphicLinker<TileArray> _Linker;
+    };
+}
\ No newline at end of file
diff --git a/source/kernel/front/resolver/GraphicResolver.cpp b/source/kernel/front/resolver/GraphicResolver.cpp
index 5c7c57426e125396ceac36c9072504277642a2d7..a436473b2ebb63e9038db28a2b339de239f8b3f4 100644
--- a/source/kernel/front/resolver/GraphicResolver.cpp
+++ b/source/kernel/front/resolver/GraphicResolver.cpp
@@ -3,7 +3,10 @@
 namespace megu::kernel {
     void GraphicResolver::resolve(double time, GraphicEngine &, const Identifiable_Map<Props> & props) {
         for(auto & [id, object] : props) {
-            object->getGraphicComponent().update(time);
+            auto * component =  object->getGraphicComponent();
+            if(component != nullptr) {
+                component->update(time);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/source/kernel/front/resolver/PhysicResolver.cpp b/source/kernel/front/resolver/PhysicResolver.cpp
index 2c905275b5265f932d57868fb2015e218a0551dc..81ed40e42b57c13571647a6d60389821c54ac8e7 100644
--- a/source/kernel/front/resolver/PhysicResolver.cpp
+++ b/source/kernel/front/resolver/PhysicResolver.cpp
@@ -11,7 +11,14 @@ namespace megu::kernel {
             if(props.contains(source.id()) && props.contains(target.id())) {
                 Props * props_source = props.at(source.id()); 
                 Props * props_target = props.at(target.id());
-                props_source->getPhysicComponent().on_collide(time, target, props_target->getPhysicComponent());
+
+                auto * sComponent = props_source->getPhysicComponent();
+                auto * tComponent = props_target->getPhysicComponent();
+
+                if(sComponent != nullptr && tComponent != nullptr) {
+                    sComponent->on_collide(time, target, *tComponent);
+                }
+                
             }
         }