diff --git a/world.gd b/world.gd
index 0a84b76..126d194 100644
--- a/world.gd
+++ b/world.gd
@@ -39,7 +39,9 @@ var cell_instance
 var generation: int = 1
 var is_paused: int = false
 var total_living: int = 0
-var world: Array = []
+
+var cell_ids: Array = [] # Store cell RIDs
+var cell_states: Array = []
 
 
 func _ready() -> void:
@@ -89,11 +91,11 @@ func start_conway() -> void:
 	camera.position.y = world_size.y * cell_size.y / 2
 
 
-## Check a cell against the Conway rules and return True if cell shoudl be alive
+## Check a cell against the Conway rules and return True if cell should be alive
 ##  The logic in this could be cleaned up pretty easily. Only verbose for understanding.
 func cell_is_alive(pos: Vector2) -> bool:
 	var neighbors := count_living_neighbors(pos)
-	var currently_alive = world[pos.x][pos.y] is RID
+	var currently_alive = cell_states[pos.x][pos.y] == CellStates.ALIVE
 
 	# Rule 1 - Any live cell with fewer than two live neighbours dies (underpopulation)
 	if currently_alive and neighbors < 2:
@@ -124,36 +126,36 @@ func count_living_neighbors(pos: Vector2) -> int:
 	for x in range(x_min, x_max):
 		for y in range(y_min, y_max):
 			if x == pos.x and y == pos.y: continue # Current cell - Don't count
-			if world[x][y] is RID:
+			if cell_states[x][y] == CellStates.ALIVE:
 				count += 1
 	return count
 
-## Loop through the world and create or kill cells depending on rules
+## Loop through world to generate cell states, hide/show cells depending on state
 func process_generation() -> void:
 	if is_paused: return
 
 	generation += 1
 	total_living = 0
 
-	var new_world: Array= []
+	var rs := RenderingServer
+
+	var new_states: Array= []
 	for x in range(world_size.x):
-		new_world.append([])
-		new_world[x].resize(world_size.x)
+		new_states.append([])
+		new_states[x].resize(world_size.x)
 		for y in range(world_size.y):
 			var pos = Vector2(x, y)
-			if cell_is_alive(pos):
-				total_living += 1
-				new_world[x][y] = create_cell(pos)
-			else:
-				new_world[x][y] = kill_cell(pos)
+			var is_alive = cell_is_alive(pos)
+			total_living += int(is_alive)
+			new_states[x][y] = int(is_alive)
+			rs.canvas_item_set_visible(cell_ids[x][y], is_alive)
 
-	world = new_world
+	cell_states = new_states
 
 
 ## Create the cell using the rendering server
-func create_cell(pos: Vector2) -> RID:
-	if world[pos.x][pos.y] is RID: return world[pos.x][pos.y]
-
+##  This is only performed on initial world generation
+func create_cell(pos: Vector2, visible_cell: bool = true) -> RID:
 	var rs = RenderingServer
 
 	cell_instance = rs.canvas_item_create()
@@ -166,26 +168,22 @@ func create_cell(pos: Vector2) -> RID:
 	var trans = Transform2D(0, pos_fixed)
 	rs.canvas_item_set_transform(cell_instance, trans)
 
-	return cell_instance
-
-## Remove the cell from the RenderingServer, if it exists
-func kill_cell(pos: Vector2) -> CellStates:
-	if world[pos.x][pos.y] is RID:
-		RenderingServer.free_rid(world[pos.x][pos.y])
-	return CellStates.DEAD
+	rs.canvas_item_set_visible(cell_instance, visible_cell)
 
+	return cell_instance
 
 ## Generate the world with cells in random states (alive or dead)
 func generate_world() -> void:
 	for x in range(world_size.x):
-		world.append([])
-		world[x].resize(world_size.x)
+		cell_ids.append([])
+		cell_ids[x].resize(world_size.x)
+		cell_states.append([])
+		cell_states[x].resize(world_size.x)
 		for y in range(world_size.y):
-			if randi_range(0, 1):
-				total_living += 1
-				world[x][y] = create_cell(Vector2(x, y))
-			else:
-				world[x][y] = CellStates.DEAD
+			var is_alive: int = randi_range(0, 1)
+			total_living += is_alive
+			cell_states[x][y] = is_alive
+			cell_ids[x][y] = create_cell(Vector2(x, y), bool(is_alive))
 
 
 func _on_generation_timer_timeout() -> void: