diff --git a/half-earth/Half-earth.csproj b/half-earth/Half-earth.csproj
new file mode 100644
index 0000000..29905c2
--- /dev/null
+++ b/half-earth/Half-earth.csproj
@@ -0,0 +1,6 @@
+
+  
+    net472
+    Halfearth
+  
+
\ No newline at end of file
diff --git a/half-earth/Half-earth.sln b/half-earth/Half-earth.sln
new file mode 100644
index 0000000..a7cf826
--- /dev/null
+++ b/half-earth/Half-earth.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Half-earth", "Half-earth.csproj", "{C894A75C-991B-4000-9BD9-9B0B186304C4}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+	Debug|Any CPU = Debug|Any CPU
+	ExportDebug|Any CPU = ExportDebug|Any CPU
+	ExportRelease|Any CPU = ExportRelease|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
+		{C894A75C-991B-4000-9BD9-9B0B186304C4}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/half-earth/materials/tile.tres b/half-earth/materials/tile.tres
new file mode 100644
index 0000000..4bc4d4a
--- /dev/null
+++ b/half-earth/materials/tile.tres
@@ -0,0 +1,8 @@
+[gd_resource type="ShaderMaterial" load_steps=2 format=2]
+
+[ext_resource path="res://shaders/tile_shader.gdshader" type="Shader" id=1]
+
+[resource]
+resource_local_to_scene = true
+shader = ExtResource( 1 )
+shader_param/c = null
diff --git a/half-earth/nodes/game.tscn b/half-earth/nodes/game.tscn
new file mode 100644
index 0000000..c7bf9d9
--- /dev/null
+++ b/half-earth/nodes/game.tscn
@@ -0,0 +1,11 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://nodes/grid.tscn" type="PackedScene" id=1]
+[ext_resource path="res://nodes/grid_cursor.tscn" type="PackedScene" id=2]
+
+[node name="Root" type="Node2D"]
+
+[node name="Grid" parent="." instance=ExtResource( 1 )]
+
+[node name="Cursor" parent="." instance=ExtResource( 2 )]
+Grid = NodePath("../Grid")
diff --git a/half-earth/nodes/grid.tscn b/half-earth/nodes/grid.tscn
new file mode 100644
index 0000000..3a19d57
--- /dev/null
+++ b/half-earth/nodes/grid.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://scripts/WorldGrid.cs" type="Script" id=1]
+[ext_resource path="res://nodes/tile.tscn" type="PackedScene" id=2]
+
+[node name="Grid" type="Node2D"]
+script = ExtResource( 1 )
+TileScene = ExtResource( 2 )
+Size = 10
+CellSize = 64
diff --git a/half-earth/nodes/tile.tscn b/half-earth/nodes/tile.tscn
new file mode 100644
index 0000000..5861ee1
--- /dev/null
+++ b/half-earth/nodes/tile.tscn
@@ -0,0 +1,8 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://materials/tile.tres" type="Material" id=1]
+[ext_resource path="res://textures/icon.png" type="Texture" id=2]
+
+[node name="Tile" type="Sprite"]
+material = ExtResource( 1 )
+texture = ExtResource( 2 )
diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs
new file mode 100644
index 0000000..e03923b
--- /dev/null
+++ b/half-earth/scripts/WorldGrid.cs
@@ -0,0 +1,93 @@
+using Godot;
+using System;
+
+public class WorldGrid : Node2D
+{
+    [Export]
+    private PackedScene TileScene { get; set; }
+
+    [Export]
+    public int Size { get; set; }
+    
+    [Export]
+    public int CellSize { get; set; }
+    
+    private struct Tile
+    {
+        public float data;
+        public ShaderMaterial material;
+    }
+    private Tile[,] _tiles;
+
+    // Called when the node enters the scene tree for the first time.
+    public override void _Ready()
+    {
+        GenerateGrid(Size);
+    }
+
+    public override void _Process(float delta)
+    {
+        base._Process(delta);
+        
+        for (int x = 0; x < Size; x++)
+        {
+            for (int y = 0; y < Size; y++)
+            {
+                var tile = _tiles[x, y];
+                var material = tile.material;
+                material.SetShaderParam("c", tile.data);
+            }
+        }
+    }
+    
+    public void GetGridPos(Vector2 position, out int x, out int y)
+    {
+        int GetCoord(float f) =>
+            Mathf.Clamp(Mathf.FloorToInt(f / CellSize), 0, CellSize -1);
+
+        x = GetCoord(position.x);
+        y = GetCoord(position.y);
+    }
+
+    private void Clear()
+    {
+        _tiles = null;
+
+        int children = this.GetChildCount();
+        GD.Print(children);
+        for (int i = 0; i < children; i++)
+        {
+            var child = this.GetChild(i);
+            child.QueueFree();
+        }
+    }
+
+    private void GenerateGrid(int size)
+    {
+        this.Clear();
+        
+        _tiles = new Tile[size, size];
+
+        for (int x = 0; x < size; x++)
+        {
+            for (int y = 0; y < size; y++)
+            {
+                var tile = new Tile();
+                tile.data = (float)(y * size + x) / 100f;
+                
+                var node = TileScene.Instance();
+                this.AddChild(node);
+                var position = new Vector2
+                {
+                    x = (x + .5f) * CellSize,
+                    y = (y + .5f) * CellSize
+                };
+                node.Position = position;
+                var canvasItem = (CanvasItem)node;
+                tile.material = (ShaderMaterial)canvasItem.Material;
+                
+                _tiles[x, y] = tile;
+            }
+        }
+    }
+}
diff --git a/half-earth/shaders/tile_shader.gdshader b/half-earth/shaders/tile_shader.gdshader
new file mode 100644
index 0000000..e948f41
--- /dev/null
+++ b/half-earth/shaders/tile_shader.gdshader
@@ -0,0 +1,7 @@
+shader_type canvas_item;
+
+uniform float c;
+
+void fragment() {
+	COLOR = vec4(c, 0.0, 0.0, 1.0);
+}