public ServerLoop(IHubContext <GameHub> hubContext, IMapLoader mapLoader) { _gameContextList = new List <GameContext>(MaxLobbyCount); for (var i = 0; i < MaxLobbyCount; i++) { _gameContextList.Add(new GameContext(id: i, maps: mapLoader.LoadMaps())); } var broadCastLoop = new Timer(BroadcastInterval); //Every set interval, send lobbies to clients broadCastLoop.Elapsed += (sender, args) => { Parallel.ForEach(_gameContextList, async context => { GameContext valContext = null; await context.Update(); //If blocks have not changed, then do not send to frontend to save bandwidth if (!context.BlocksHaveChanged) { //Create new Object to avoid mutating properties valContext = new GameContext(context.Players, context.Ball, new GameMap(), context.ScoreBoard, context.LobbyState); } await hubContext.Clients.Group($"lobby{context.Id}").SendAsync("ReceiveContextUpdate", context.BlocksHaveChanged ? context : valContext);//send to frontend }); }; broadCastLoop.Start(); }