From 718d98e2266663313425e7ed7a5700fb3dac71c6 Mon Sep 17 00:00:00 2001 From: Erik Varga Date: Tue, 15 Oct 2024 22:15:21 +0200 Subject: [PATCH] More small fixes to the game engine - prrrrobably the last release before the competition. Adding a more proper fix for the startup race condition, fixing arcade system in compat mode updating and pinning deps. --- 2024/hackceler8/handout/game.nix | 12 ++++++------ .../game/engine/arcade_system/arcade_system.py | 18 ++++++++++++++---- .../handout/game/engine/save_file.py | 11 ----------- 2024/hackceler8/handout/game/venator.py | 9 ++++++--- 2024/hackceler8/handout/game/venator_gui.py | 5 ++++- 2024/hackceler8/handout/requirements.txt | 14 +++++++------- 2024/hackceler8/server/game.nix | 12 ++++++------ .../game/engine/arcade_system/arcade_system.py | 18 ++++++++++++++---- .../hackceler8/server/game/engine/save_file.py | 11 ----------- 2024/hackceler8/server/game/venator.py | 9 ++++++--- 2024/hackceler8/server/game/venator_gui.py | 5 ++++- 2024/hackceler8/server/requirements.txt | 14 +++++++------- 12 files changed, 74 insertions(+), 64 deletions(-) diff --git a/2024/hackceler8/handout/game.nix b/2024/hackceler8/handout/game.nix index 39be0b2d5..37aea160a 100644 --- a/2024/hackceler8/handout/game.nix +++ b/2024/hackceler8/handout/game.nix @@ -1,6 +1,6 @@ -{ stdenv, python3Packages, fetchPypi, fetchFromGitHub, pkgs, runtimeShell }: +{ stdenv, python312Packages, fetchPypi, fetchFromGitHub, pkgs, runtimeShell }: let - latestCython0 = python3Packages.cython_0.overrideAttrs (self: super: rec { + latestCython0 = python312Packages.cython_0.overrideAttrs (self: super: rec { version = "0.29.37"; src = fetchPypi { pname = "Cython"; @@ -8,8 +8,8 @@ let hash = "sha256-+BPUpt2Ure5dT/JmGR0dlb9tQWSk+sxTVCLAIbJQTPs="; }; }); - imgui = { python3Packages, pkg-config, imgui, fetchPypi, fetchFromGitHub }: - with python3Packages; + imgui = { python312Packages, pkg-config, imgui, fetchPypi, fetchFromGitHub }: + with python312Packages; buildPythonPackage rec { pname = "imgui"; version = "2.0.0"; @@ -26,7 +26,7 @@ let doCheck = false; }; # moderngl-window with applied fix - moderngl-window = python3Packages.moderngl-window.overrideAttrs + moderngl-window = python312Packages.moderngl-window.overrideAttrs (self: super: { src = fetchFromGitHub { owner = "implr"; @@ -35,7 +35,7 @@ let hash = "sha256-d+1Q+D4RKIHxToAi+d8q8G43kSCTRVt0PsKMk+WECCQ="; }; }); - pythonEnv = pkgs.python3.withPackages (p: + pythonEnv = pkgs.python312.withPackages (p: with p; [ pip moderngl diff --git a/2024/hackceler8/handout/game/engine/arcade_system/arcade_system.py b/2024/hackceler8/handout/game/engine/arcade_system/arcade_system.py index 495d5dec6..1011a8b32 100644 --- a/2024/hackceler8/handout/game/engine/arcade_system/arcade_system.py +++ b/2024/hackceler8/handout/game/engine/arcade_system/arcade_system.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import dataclasses import logging import os import subprocess @@ -151,9 +151,19 @@ def draw(self): self._draw_tiles() return assert all(i < self.MAX_TILE_ID for i in buf) - # The sprite shader wants a buffer of indexes into the sprite descriptor SSBO. We never _move_ the sprite - # positions here, just change their textures, so we can Simply push the entire index buffer to the gpu. - self.layer.txs_buffer.write(buf.astype(np.uint32).tobytes()) + if not gfx.GL410_COMPAT: + # The sprite shader wants a buffer of indexes into the sprite descriptor SSBO. We never _move_ the sprite + # positions here, just change their textures, so we can Simply push the entire index buffer to the gpu. + self.layer.txs_buffer.write(buf.astype(np.uint32).tobytes()) + else: + texids = list(self.layer.draws_per_tex.keys()) + assert len(texids) == 1 + assert len(self.layer.draws_per_tex[texids[0]]) == len(buf) + for i in range(len(buf)): + old = self.layer.draws_per_tex[texids[0]][i] + self.layer.draws_per_tex[texids[0]][i] = dataclasses.replace( + old, tex=dataclasses.replace(old.tex, region_id=buf[i])) + self.layer.update_all_buffers() self._draw_tiles() def _draw_tiles(self): diff --git a/2024/hackceler8/handout/game/engine/save_file.py b/2024/hackceler8/handout/game/engine/save_file.py index b76b7b887..02551f26c 100644 --- a/2024/hackceler8/handout/game/engine/save_file.py +++ b/2024/hackceler8/handout/game/engine/save_file.py @@ -74,14 +74,3 @@ def apply_save_state(state, game): game.items = load_items_from_save(state["items"]) if "win_timestamp" in state: game.win_timestamp = state["win_timestamp"] - try: - for o in list(game.tiled_map.objects): - if o.nametype == "Item": - if check_item_loaded(game.items, o): - logging.info(f"Duplicate object {o.nametype, o.name} detected") - if o in game.objects: - game.objects.remove(o) - game.tiled_map.objects.remove(o) - game.physics_engine.remove_generic_object(o) - except: - pass diff --git a/2024/hackceler8/handout/game/venator.py b/2024/hackceler8/handout/game/venator.py index 74b7a7096..2cf38baa5 100644 --- a/2024/hackceler8/handout/game/venator.py +++ b/2024/hackceler8/handout/game/venator.py @@ -65,6 +65,7 @@ def __init__(self, net, is_server: bool, save_file_path: str = "save_state", self.win_timestamp = 0 self.tics = 0 self.ready = True + self.map_loaded = False self.waiting_for_server_txt = False if not is_server and self.net is not None: @@ -154,8 +155,6 @@ def __init__(self, net, is_server: bool, save_file_path: str = "save_state", self.raw_pressed_keys: set[Keys] = set() self.pressed_keys = set() - self.setup() - @property def won(self): # Game is won if the time is neither None nor 0 @@ -447,7 +446,7 @@ def cleanup(): self.screen_fader = ScreenFader(close, cleanup) def _save(self): - if self.is_server and not self.save_cooldown and not self.player.dead: + if self.is_server and not self.save_cooldown and (self.player is None or not self.player.dead): logging.info(f"Saving state, items: {self.items}") self.save_file.save(self) self.save_cooldown = True @@ -471,6 +470,10 @@ def tick(self): self.recv_from_server() return + if not self.map_loaded: + self.map_loaded = True + self.setup() + self.pressed_keys = self.tracked_keys & self.raw_pressed_keys self.newly_pressed_keys = self.pressed_keys.difference( self.prev_pressed_keys diff --git a/2024/hackceler8/handout/game/venator_gui.py b/2024/hackceler8/handout/game/venator_gui.py index 9a567efd4..887ba0c6d 100644 --- a/2024/hackceler8/handout/game/venator_gui.py +++ b/2024/hackceler8/handout/game/venator_gui.py @@ -56,6 +56,9 @@ def on_resize(self, width, height): pass def _center_camera_to_player(self): + if not self.game.ready or not self.game.map_loaded: + return + screen_center_x = self.game.player.x - (self.camera.viewport_width / 2) screen_center_y = self.game.player.y - (self.camera.viewport_height / 2) @@ -77,7 +80,7 @@ def _center_camera_to_player(self): self.camera.move_to(player_centered) def draw(self): - if self.game is None: + if self.game is None or not self.game.ready or not self.game.map_loaded: mglw.ContextRefs.WINDOW.set_icon(os.path.abspath("resources/character/32bit/main32.PNG")) self.wnd.ctx.clear(color=(0, 0.5, 0, 1)) gfx.draw_txt("loading", gfx.FONT_PIXEL[60], "Loading game...", diff --git a/2024/hackceler8/handout/requirements.txt b/2024/hackceler8/handout/requirements.txt index 2fd090cb9..990fe1866 100644 --- a/2024/hackceler8/handout/requirements.txt +++ b/2024/hackceler8/handout/requirements.txt @@ -1,10 +1,10 @@ -numpy >= 1.25.2 -xxhash >= 3.3.0 -dill >= 0.3.7 -pylint-venv >= 3.0.0 -pylint >= 3.0.0 -imgui >= 2.0.0 -pillow >= 10.3.0 +numpy == 1.26.4 +xxhash == 3.4.1 +dill == 0.3.8 +pylint-venv == 3.0.3 +pylint == 3.1.1 +imgui == 2.0.0 +pillow == 10.3.0 pyrr >= 0.10.3 # 5.11 breaks renderdoc, TODO report this moderngl == 5.10.0 diff --git a/2024/hackceler8/server/game.nix b/2024/hackceler8/server/game.nix index 39be0b2d5..37aea160a 100644 --- a/2024/hackceler8/server/game.nix +++ b/2024/hackceler8/server/game.nix @@ -1,6 +1,6 @@ -{ stdenv, python3Packages, fetchPypi, fetchFromGitHub, pkgs, runtimeShell }: +{ stdenv, python312Packages, fetchPypi, fetchFromGitHub, pkgs, runtimeShell }: let - latestCython0 = python3Packages.cython_0.overrideAttrs (self: super: rec { + latestCython0 = python312Packages.cython_0.overrideAttrs (self: super: rec { version = "0.29.37"; src = fetchPypi { pname = "Cython"; @@ -8,8 +8,8 @@ let hash = "sha256-+BPUpt2Ure5dT/JmGR0dlb9tQWSk+sxTVCLAIbJQTPs="; }; }); - imgui = { python3Packages, pkg-config, imgui, fetchPypi, fetchFromGitHub }: - with python3Packages; + imgui = { python312Packages, pkg-config, imgui, fetchPypi, fetchFromGitHub }: + with python312Packages; buildPythonPackage rec { pname = "imgui"; version = "2.0.0"; @@ -26,7 +26,7 @@ let doCheck = false; }; # moderngl-window with applied fix - moderngl-window = python3Packages.moderngl-window.overrideAttrs + moderngl-window = python312Packages.moderngl-window.overrideAttrs (self: super: { src = fetchFromGitHub { owner = "implr"; @@ -35,7 +35,7 @@ let hash = "sha256-d+1Q+D4RKIHxToAi+d8q8G43kSCTRVt0PsKMk+WECCQ="; }; }); - pythonEnv = pkgs.python3.withPackages (p: + pythonEnv = pkgs.python312.withPackages (p: with p; [ pip moderngl diff --git a/2024/hackceler8/server/game/engine/arcade_system/arcade_system.py b/2024/hackceler8/server/game/engine/arcade_system/arcade_system.py index 495d5dec6..1011a8b32 100644 --- a/2024/hackceler8/server/game/engine/arcade_system/arcade_system.py +++ b/2024/hackceler8/server/game/engine/arcade_system/arcade_system.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import dataclasses import logging import os import subprocess @@ -151,9 +151,19 @@ def draw(self): self._draw_tiles() return assert all(i < self.MAX_TILE_ID for i in buf) - # The sprite shader wants a buffer of indexes into the sprite descriptor SSBO. We never _move_ the sprite - # positions here, just change their textures, so we can Simply push the entire index buffer to the gpu. - self.layer.txs_buffer.write(buf.astype(np.uint32).tobytes()) + if not gfx.GL410_COMPAT: + # The sprite shader wants a buffer of indexes into the sprite descriptor SSBO. We never _move_ the sprite + # positions here, just change their textures, so we can Simply push the entire index buffer to the gpu. + self.layer.txs_buffer.write(buf.astype(np.uint32).tobytes()) + else: + texids = list(self.layer.draws_per_tex.keys()) + assert len(texids) == 1 + assert len(self.layer.draws_per_tex[texids[0]]) == len(buf) + for i in range(len(buf)): + old = self.layer.draws_per_tex[texids[0]][i] + self.layer.draws_per_tex[texids[0]][i] = dataclasses.replace( + old, tex=dataclasses.replace(old.tex, region_id=buf[i])) + self.layer.update_all_buffers() self._draw_tiles() def _draw_tiles(self): diff --git a/2024/hackceler8/server/game/engine/save_file.py b/2024/hackceler8/server/game/engine/save_file.py index b76b7b887..02551f26c 100644 --- a/2024/hackceler8/server/game/engine/save_file.py +++ b/2024/hackceler8/server/game/engine/save_file.py @@ -74,14 +74,3 @@ def apply_save_state(state, game): game.items = load_items_from_save(state["items"]) if "win_timestamp" in state: game.win_timestamp = state["win_timestamp"] - try: - for o in list(game.tiled_map.objects): - if o.nametype == "Item": - if check_item_loaded(game.items, o): - logging.info(f"Duplicate object {o.nametype, o.name} detected") - if o in game.objects: - game.objects.remove(o) - game.tiled_map.objects.remove(o) - game.physics_engine.remove_generic_object(o) - except: - pass diff --git a/2024/hackceler8/server/game/venator.py b/2024/hackceler8/server/game/venator.py index 74b7a7096..2cf38baa5 100644 --- a/2024/hackceler8/server/game/venator.py +++ b/2024/hackceler8/server/game/venator.py @@ -65,6 +65,7 @@ def __init__(self, net, is_server: bool, save_file_path: str = "save_state", self.win_timestamp = 0 self.tics = 0 self.ready = True + self.map_loaded = False self.waiting_for_server_txt = False if not is_server and self.net is not None: @@ -154,8 +155,6 @@ def __init__(self, net, is_server: bool, save_file_path: str = "save_state", self.raw_pressed_keys: set[Keys] = set() self.pressed_keys = set() - self.setup() - @property def won(self): # Game is won if the time is neither None nor 0 @@ -447,7 +446,7 @@ def cleanup(): self.screen_fader = ScreenFader(close, cleanup) def _save(self): - if self.is_server and not self.save_cooldown and not self.player.dead: + if self.is_server and not self.save_cooldown and (self.player is None or not self.player.dead): logging.info(f"Saving state, items: {self.items}") self.save_file.save(self) self.save_cooldown = True @@ -471,6 +470,10 @@ def tick(self): self.recv_from_server() return + if not self.map_loaded: + self.map_loaded = True + self.setup() + self.pressed_keys = self.tracked_keys & self.raw_pressed_keys self.newly_pressed_keys = self.pressed_keys.difference( self.prev_pressed_keys diff --git a/2024/hackceler8/server/game/venator_gui.py b/2024/hackceler8/server/game/venator_gui.py index 9a567efd4..887ba0c6d 100644 --- a/2024/hackceler8/server/game/venator_gui.py +++ b/2024/hackceler8/server/game/venator_gui.py @@ -56,6 +56,9 @@ def on_resize(self, width, height): pass def _center_camera_to_player(self): + if not self.game.ready or not self.game.map_loaded: + return + screen_center_x = self.game.player.x - (self.camera.viewport_width / 2) screen_center_y = self.game.player.y - (self.camera.viewport_height / 2) @@ -77,7 +80,7 @@ def _center_camera_to_player(self): self.camera.move_to(player_centered) def draw(self): - if self.game is None: + if self.game is None or not self.game.ready or not self.game.map_loaded: mglw.ContextRefs.WINDOW.set_icon(os.path.abspath("resources/character/32bit/main32.PNG")) self.wnd.ctx.clear(color=(0, 0.5, 0, 1)) gfx.draw_txt("loading", gfx.FONT_PIXEL[60], "Loading game...", diff --git a/2024/hackceler8/server/requirements.txt b/2024/hackceler8/server/requirements.txt index 2fd090cb9..990fe1866 100644 --- a/2024/hackceler8/server/requirements.txt +++ b/2024/hackceler8/server/requirements.txt @@ -1,10 +1,10 @@ -numpy >= 1.25.2 -xxhash >= 3.3.0 -dill >= 0.3.7 -pylint-venv >= 3.0.0 -pylint >= 3.0.0 -imgui >= 2.0.0 -pillow >= 10.3.0 +numpy == 1.26.4 +xxhash == 3.4.1 +dill == 0.3.8 +pylint-venv == 3.0.3 +pylint == 3.1.1 +imgui == 2.0.0 +pillow == 10.3.0 pyrr >= 0.10.3 # 5.11 breaks renderdoc, TODO report this moderngl == 5.10.0