/// <summary> /// Callback executed on each game tick. /// </summary> /// <param name="_">game object that is passed by the timer</param> private async Task GameTick(double delta) { Design.Delta = delta < 0.0001 ? 1 : delta; if (!enemySpawnLimiter.IsCooldownActive()) { SpawnEnemy(Design.SpawnRange); } RemoveDeadHeroes(); foreach (var h in heroes) { h.IsControlledByAlgorithm = false; h.Algorithm.Execute(GameState); } UpdateStateWithControls(delta); foreach (var h in heroes) { h.Move(delta); } foreach (var enemy in enemies) { enemy.VelocityTowardsClosestEntity(heroes); enemy.Move(delta); if (enemy is Shooter shooter) { TryAddEnemyProjectile(shooter); } } foreach (var projectile in enemyProjectiles) { projectile.Move(delta); } foreach (var h in heroes) { foreach (var projectile in h.Projectiles) { projectile.Move(delta); } } CheckForCollisionsAndUpdateGame(); RemoveProjectilesOutsideOfMap(); await hubContext.SendUpdatesToClients(GameState); foreach (var h in heroes) { h.WipeSyntheticControls(); if (h.HasCodeChanged) { h.HasCodeChanged = false; await hubContext.SendCodeUpdate(h.Algorithm, h.Id); } } }