IEnumerator GameLoop() { Stopwatch watch = new Stopwatch(); //Main loop while (true) { CallTurnStartGlobal(); //Player turn sequence player.AddEnergy(energyPerTurn); while (player.energy > 0) { //Set up local turn player.StartTurn(); //Run the actual turn itself IEnumerator turn = player.LocalTurn(); while (player.energy > 0 && turn.MoveNext()) { if (turn.Current != GameAction.StateCheck) { yield return(turn.Current); } } //Turn is ended! player.EndTurn(); } watch.Restart(); for (int i = 0; i < Map.current.monsters.Count; i++) { //Taken too much time? Quit then! (Done before monster update to handle edge case on last call) if (watch.ElapsedMilliseconds > MONSTER_UPDATE_MS) { watch.Stop(); yield return(null); watch.Restart(); } Monster m = Map.current.monsters[i]; m.AddEnergy(energyPerTurn); while (m.energy > 0 && !m.IsDead()) { //Set up local turn m.StartTurn(); //Run the actual turn itself IEnumerator turn = m.LocalTurn(); while (m.energy > 0 && turn.MoveNext()) { if (turn.Current != GameAction.StateCheck) { watch.Stop(); yield return(turn.Current); watch.Restart(); } else { //Edge case - take a break during a check if we need to! //Should make things a lot more fluid with complicated monster turns if (watch.ElapsedMilliseconds > MONSTER_UPDATE_MS) { watch.Stop(); yield return(null); watch.Restart(); } } } //Turn is ended! m.EndTurn(); } } watch.Stop(); //Clean up anybody who's dead for (int i = Map.current.monsters.Count - 1; i >= 0; i--) { Monster monster = Map.current.monsters[i]; if (monster.IsDead()) { Map.current.monsters.RemoveAt(i); Destroy(monster.gameObject); } } CallTurnEndGlobal(); turn++; if (nextLevel != -1) { MoveLevel(); } } }