From 7b086fbd8fb6da1051758326a187b0db7c0cb88d Mon Sep 17 00:00:00 2001 From: Josh Creek <8179928+jcreek@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:53:15 +0100 Subject: [PATCH] perf(ship): share per-team accent material instead of allocating per ship _apply_team_color() allocated a fresh StandardMaterial3D on every call, and ran at least twice per ship (once from _ready at the default team, once from the team setter when the game mode assigns the real team). Cache one StandardMaterial3D per team in a static dict on Ship and reuse it across every ship on that team. --- Game/scripts/ship.gd | 29 +++++++++++++++++++++-------- TODO.md | 1 - 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Game/scripts/ship.gd b/Game/scripts/ship.gd index 9751e258..b9e9990a 100644 --- a/Game/scripts/ship.gd +++ b/Game/scripts/ship.gd @@ -38,6 +38,26 @@ var team: int = 0: team = value _apply_team_color() +# Shared per-team accent material, built once per team and reused by every +# ship — avoids allocating a fresh StandardMaterial3D from both _ready and +# the team setter (previously ran at least twice per ship). +static var _team_materials: Dictionary = {} # team:int -> StandardMaterial3D + + +static func _get_team_material(team: int) -> StandardMaterial3D: + if _team_materials.has(team): + return _team_materials[team] + var color: Color = TEAM_COLORS.get(team, TEAM_COLORS[0]) + var accent := StandardMaterial3D.new() + accent.albedo_color = color + accent.metallic = 0.3 + accent.roughness = 0.5 + accent.emission_enabled = true + accent.emission = color + accent.emission_energy_multiplier = 0.35 + _team_materials[team] = accent + return accent + var controller: ShipController var _current_action: ShipAction = ShipAction.new() var _boundary: ArenaBoundary @@ -93,14 +113,7 @@ func _ready(): func _apply_team_color() -> void: if not is_inside_tree(): return - var color: Color = TEAM_COLORS.get(team, TEAM_COLORS[0]) - var accent := StandardMaterial3D.new() - accent.albedo_color = color - accent.metallic = 0.3 - accent.roughness = 0.5 - accent.emission_enabled = true - accent.emission = color - accent.emission_energy_multiplier = 0.35 + var accent := _get_team_material(team) for mesh_name in ["Nose", "TailFin"]: var mesh := get_node_or_null(mesh_name) as MeshInstance3D if mesh: diff --git a/TODO.md b/TODO.md index e2241962..81d6c004 100644 --- a/TODO.md +++ b/TODO.md @@ -25,7 +25,6 @@ Bugs found in an adversarial review. None are gameplay- or physics-affecting, so ## Performance -- [ ] Shared per-team materials instead of `Ship._apply_team_color()` allocating a fresh `StandardMaterial3D` and assigning it as `material_override` (and running at least twice per ship — once from `_ready`, once from the `team` setter). Removes the allocation and lets same-team ships batch. - [ ] Merge the four non-tinted ship meshes (Hull/Canopy/EngineGlowL/R) into one — 6 draw calls per ship down to 3. Irrelevant at 1v1; 36 calls before VFX at 3v3. - [ ] Name collision layers in `project.godot` and assign them — nothing configures `collision_layer`/`collision_mask` today, so every body tests against every other. - [ ] Measure `nebula_dust.gdshader`'s per-fragment depth-texture sample across 500 large soft billboards before adding more particle work.