+ ctrl->Update(dt);
+ }
+}
+
+
+void Spawner::CheckDespawn() noexcept {
+ const Entity &reference = world.Player();
+ for (auto iter = controllers.begin(), end = controllers.end(); iter != end;) {
+ Entity &e = (*iter)->Controlled();
+ glm::vec3 diff(reference.AbsoluteDifference(e));
+ if (dot(diff, diff) > despawn_range) {
+ e.Remove();
+ delete *iter;
+ iter = controllers.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
+void Spawner::TrySpawn() {
+ if (controllers.size() >= max_entities) return;
+
+ glm::ivec3 chunk(
+ (rand() % (chunk_range * 2 + 1)) - chunk_range,
+ (rand() % (chunk_range * 2 + 1)) - chunk_range,
+ (rand() % (chunk_range * 2 + 1)) - chunk_range
+ );
+
+ glm::ivec3 pos(
+ rand() % Chunk::width,
+ rand() % Chunk::height,
+ rand() % Chunk::depth
+ );
+
+
+ // distance check
+ glm::vec3 diff(glm::vec3(chunk * Chunk::Extent() - pos) + world.Player().Position());
+ float dist = dot(diff, diff);
+ if (dist > despawn_range || dist < spawn_distance) {
+ return;