Beispiel #1
0
 async def run_game_loop(self, interval: float = 0.02) -> None:  # pylint: disable=function-redefined
     # pylint: disable=missing-docstring
     if self._game_state_store.get_game_state(
     ).game_status == GameStatus.get("Paused"):
         self._game_state_store.push_update(
             GameStateUpdate(
                 self._game_state_store.get_game_state().time_order + 1,
                 game_status=GameStatus.get("Active")))
     game_state = self._game_state_store.get_game_state()
     dt = interval
     self._game_loop_is_running = True
     logger.info(
         f"State machine starting game loop with interval of {interval} seconds."
     )
     while game_state.game_status == GameStatus.get("Active"):
         t0 = time.time()
         update_dict = self.time_step(game_state, dt)
         while not self._event_queue.empty():
             event = await self._event_queue.get()
             event_update = await self._universal_event_handler.handle(
                 event, game_state=game_state, dt=dt)
             update_dict.update(event_update)
             if time.time() - t0 > 0.95 * interval:
                 break
         self._game_state_store.push_update(
             GameStateUpdate(game_state.time_order + 1, **update_dict))
         game_state = self._game_state_store.get_game_state()
         dt = max(interval, time.time() - t0)
         await curio.sleep(max(0, interval - dt))
         self.game_time += dt
     logger.info("Game loop stopped.")
     self._game_loop_is_running = False
Beispiel #2
0
 def test_safe_concurrent_cache_access(self):
     store = GameStateStore()
     store.push_update(GameStateUpdate(2))
     counter = 0
     for update in store.get_update_cache():
         counter += 1
         if update.time_order == 2:
             store.push_update(GameStateUpdate(3))
     assert counter == 2
     counter = 0
     for update in store.get_update_cache():
         counter += 1
         if update.time_order == 0:
             del store._game_state_update_cache[2]
     assert counter == 3
     assert len(store.get_update_cache()) == 2
Beispiel #3
0
 def test_cache_size(self):
     store = GameStateStore()
     for i in range(2 * store._update_cache_size):
         assert len(store.get_update_cache()) == min(
             i + 1, store._update_cache_size)
         store.push_update(GameStateUpdate(i + 1))
         assert sum(store.get_update_cache()).time_order == i + 1
Beispiel #4
0
 def __init__(self, initial_game_state: GameState = None):
     logger.debug("Creating GameStateStore instance.")
     self._game_state = initial_game_state if initial_game_state is not None else GameState(
     )
     if not isinstance(self._game_state, GameState):
         raise TypeError(
             f"'initial_game_state' should be of type 'GameState', not '{self._game_state.__class__.__name__}'."
         )
     self._game_state_update_cache = [GameStateUpdate(0)]
Beispiel #5
0
 def _create_next_package(self):
     """Override #Connection._create_next_package to include game state updates."""
     update_cache = self.game_state_store.get_update_cache()
     # Respond by sending the sum of all updates since the client's time-order point.
     # Or the whole game state if the client doesn't have it yet.
     if self.last_client_time_order == 0:
         logger.debug(
             f"Sending full game state to client {self.remote_address}.")
         game_state = self.game_state_store.get_game_state()
         update = GameStateUpdate(**game_state.__dict__)
     else:
         update_base = GameStateUpdate(self.last_client_time_order)
         update = sum((upd for upd in update_cache if upd > update_base),
                      update_base)
         logger.debug((
             f"Sending update from time order {self.last_client_time_order} "
             f"to {update.time_order} to client {self.remote_address}."))
     return ServerPackage(
         Header(self.local_sequence, self.remote_sequence,
                self.ack_bitfield), update)
Beispiel #6
0
 def from_datagram(cls, datagram: bytes) -> "ServerPackage":
     """Override #Package.from_datagram to include `game_state_update`."""
     header, payload = Header.deconstruct_datagram(datagram)
     state_update_bytesize = int.from_bytes(payload[:2], "big")
     game_state_update = GameStateUpdate.from_bytes(
         payload[2:state_update_bytesize + 2])
     payload = payload[state_update_bytesize + 2:]
     events = cls._read_out_event_block(payload)
     result = cls(header, game_state_update, events)
     result._datagram = datagram  # pylint: disable=protected-access
     return result
Beispiel #7
0
 async def stop(self, timeout: float = 1.0) -> bool:  # pylint: disable=function-redefined
     # pylint: disable=missing-docstring
     logger.info("Trying to stop game loop ...")
     if self._game_state_store.get_game_state(
     ).game_status == GameStatus.get("Active"):
         self._game_state_store.push_update(
             GameStateUpdate(
                 self._game_state_store.get_game_state().time_order + 1,
                 game_status=GameStatus.get("Paused")))
     t0 = time.time()
     while self._game_loop_is_running:
         if time.time() - t0 > timeout:
             break
         await curio.sleep(0)
     return not self._game_loop_is_running
Beispiel #8
0
    def __init__(self, game_state_store, server):
        super().__init__(game_state_store)
        self.server = server
        self.player_characters = {}
        self.npc_actors = {}
        test_enemy = actors.TestEnemyActor("Test Enemy")
        test_enemy.position = (200, 100)
        test_enemy.direction = (-1, 0)
        test_enemy.velocity = (-1 * actors.ENEMY_VELOCITY, 0)
        self.npc_actors[0] = test_enemy
        add_enemy = GameStateUpdate(
            self._game_state_store.get_game_state().time_order + 1,
            npcs={0: test_enemy.get_state()}
        )
        self._game_state_store.push_update(add_enemy)
        self.register_event_handler("JOIN", self.on_join)
        self.register_event_handler("MOVE", self.on_move)
        self.register_event_handler("LEAVE", self.on_leave)

        self.learn_counter = 0
        global GRAPH
        GRAPH = tensorflow.get_default_graph()
Beispiel #9
0
 def test_update_arithmetic(self):
     game_state = GameState(time_order=0, game_status=GameStatus.get("Paused"))
     update = GameStateUpdate(time_order=0, test=0)
     game_state += update
     assert not hasattr(game_state, "test") and game_state.time_order == 0
     update.time_order = 1
     game_state += update
     assert game_state.test == 0 and game_state.time_order == 1
     update.time_order = 2
     update.test = TO_DELETE
     game_state += update
     assert not hasattr(game_state, "test") and game_state.time_order == 2
     update.time_order = 1
     update.test = 2
     game_state += update
     assert not hasattr(game_state, "test") and game_state.time_order == 2
     game_state.test = 0
     update += GameStateUpdate(time_order=3, test=TO_DELETE)
     assert update.time_order == 3 and update.test == TO_DELETE
     assert hasattr(game_state, "test") and game_state.time_order == 2
     game_state += update
     assert not hasattr(game_state, "test") and game_state.time_order == 3
     update += GameStateUpdate(time_order=4, test="test")
     assert update.test == "test" and update > game_state
     game_state += (
         GameStateUpdate(time_order=3, test={1: TO_DELETE})
         + GameStateUpdate(time_order=5, test={1: "test1", 2: "test2"})
         + update
     )
     assert game_state.time_order == 5 and game_state.test[1] == "test1"
Beispiel #10
0
 def test_bytepacking(self):
     update = GameStateUpdate(5)
     bytepack = update.to_bytes()
     unpacked_update = GameStateUpdate.from_bytes(bytepack)
     assert update == unpacked_update
Beispiel #11
0
 def test_push_update(self):
     store = GameStateStore()
     store.push_update(GameStateUpdate(1, test="foobar"))
     assert len(store._game_state_update_cache) == 2
     assert store.get_game_state().time_order == 1
     assert store.get_game_state().test == "foobar"
Beispiel #12
0
 def test_instantiation(self):
     store = GameStateStore()
     assert store._game_state == GameState()
     assert store._game_state_update_cache == [GameStateUpdate(0)]
Beispiel #13
0
 def test_instantiation(self):
     state_machine = GameStateMachine(GameStateStore())
     assert state_machine.game_time == 0
     assert state_machine._game_state_store._game_state_update_cache == [
         GameStateUpdate(0)
     ]
Beispiel #14
0
 def test_bytepacking(self):
     package = ServerPackage(Header(4, 5, "10" * 16), GameStateUpdate(2),
                             [Event("TEST", "Foo", "Bar")])
     datagram = package.to_datagram()
     unpacked_package = ServerPackage.from_datagram(datagram)
     assert package == unpacked_package