fix(assets): remove unreferenced duplicate planet_surface texture

assets/textures/planet_surface.png was byte-identical to and unused
in favor of assets/models/nebula_planet_planet_surface.png, the
sidecar Godot's glTF importer actually extracted from nebula_planet.glb
and uses at runtime. Deleted the orphan (+ its .import) and stopped
gen_planet_surface.py from writing it.

Also measured nebula_dust.gdshader's per-fragment depth-texture sample
cost (~0.07ms/frame at 500 particles, within noise) -- negligible, so
no budgeting concern for further particle work.
This commit is contained in:
Josh Creek
2026-08-05 09:51:33 +01:00
parent 9bdeb73fa7
commit 401d882ff0
4 changed files with 11 additions and 76 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 KiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bxsadfd04v6r2"
path="res://.godot/imported/planet_surface.png-d3aaf8310508e4c85b26a3d093bcf9c8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/textures/planet_surface.png"
dest_files=["res://.godot/imported/planet_surface.png-d3aaf8310508e4c85b26a3d093bcf9c8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
-21
View File
@@ -10,18 +10,6 @@ The training pipeline is built — see `TRAINING.md` (self-play PPO via the vend
- [ ] Frozen-opponent league: train the live policy against a *pool* of past exported checkpoints, sampled per-episode (today's `--opponent-mode=frozen` only supports one fixed model per run) to prevent self-play strategy collapse on long runs. - [ ] Frozen-opponent league: train the live policy against a *pool* of past exported checkpoints, sampled per-episode (today's `--opponent-mode=frozen` only supports one fixed model per run) to prevent self-play strategy collapse on long runs.
- [ ] Richer state setter / curriculum: aerial states, wall plays, rebound scenarios as skill grows (beyond the score/defend/draw staging already in place). - [ ] Richer state setter / curriculum: aerial states, wall plays, rebound scenarios as skill grows (beyond the score/defend/draw staging already in place).
## Correctness
Bugs found in an adversarial review. None are gameplay- or physics-affecting, so all are safe to land against the current `Game/bots/` checkpoints.
- [x] ~~Goal scoring volume (3.5 x 1.5, `objects/goal.tscn`) is smaller than the drawn mouth (3.7 x 1.65, `ArenaBoundary.GOAL_APERTURE_*`) — a ball crossing the visible edge doesn't score.~~ Fixed: `GOAL_APERTURE_HALF_WIDTH`/`HEIGHT` now match the sensor exactly (1.75/1.5).
- [ ] Delete the duplicate 1 MB texture — `assets/textures/planet_surface.png` and `assets/models/nebula_planet_planet_surface.png` are byte-identical.
## Performance
- [ ] Measure `nebula_dust.gdshader`'s per-fragment depth-texture sample across 500 large soft billboards before adding more particle work.
- [x] ~~Bake `ArenaBoundary`'s ~160 runtime-generated `CollisionShape3D` nodes into the scene.~~ Done: `ArenaBoundary.bake_colliders()` + `Game/tools/bake_arena_boundary.gd` (re-run after any future geometry change). `_ready()` self-heals — skips regenerating when a bake already matches the current `goal_mode`, regenerates at runtime otherwise (e.g. the `_elevated` arena variants, not yet baked).
## Presentation / AAA polish ## Presentation / AAA polish
The largest gap between this and a AAA-feeling product is presentation, not code. Sequenced after the above for pragmatic reasons, but this is the highest impact per hour. The largest gap between this and a AAA-feeling product is presentation, not code. Sequenced after the above for pragmatic reasons, but this is the highest impact per hour.
@@ -37,15 +25,6 @@ The largest gap between this and a AAA-feeling product is presentation, not code
- [ ] Custom font + a real `Theme` resource for the HUD. The procedural instruments are well-engineered, but `ThemeDB.fallback_font` at 10-13 px reads as a debug overlay. - [ ] Custom font + a real `Theme` resource for the HUD. The procedural instruments are well-engineered, but `ThemeDB.fallback_font` at 10-13 px reads as a debug overlay.
- [ ] Post-processing beyond glow: DoF, motion blur, vignette, chromatic aberration on turbo. - [ ] Post-processing beyond glow: DoF, motion blur, vignette, chromatic aberration on turbo.
## Resolved — trained-bot compatibility (2026-08-05 retrain-from-scratch reset)
The four items below all took their architecturally-correct form instead of their zero-risk form, since `Game/bots/promoted/*.json` are being retrained from scratch anyway (those two checkpoints are left in place and are expected to go stale, not migrated). Scoped up further mid-implementation to a genuine 5v5 ceiling with a proportionally resized arena, since the observation-space plumbing is the expensive part to redo twice.
- [x] **Per-tick drag** (`ship.gd`) — delta-scaled via `_tick_scaled(k, state.step)`, invariant to `physics_ticks_per_second`.
- [x] **Goal aperture** — real navigable hole cut into each end wall's collision (`ArenaBoundary._build_end_wall_colliders`), sized to the actual scoring sensor and correct for both FLOOR and ELEVATED goal modes.
- [x] **Collider bake** — done alongside the geometry changes above (see Performance).
- [x] **Beyond 1v1**`ShipObservations` now takes padded teammate/opponent arrays (`MAX_TEAMMATES=4`, `MAX_OPPONENTS=5`, `SIZE=83`), ordered by a new persistent `Ship.spawn_index` so slots never reorder mid-match. `training_mode.gd`/`match_mode.gd` gained a `team_size` export (default 1, so existing 1v1 behaviour is unchanged) and the arena was resized 1.5x to fit 5v5. This pass is plumbing only: no 2v2+ curriculum, no team-play reward design, and no match-mode UI to pick team size — those are still open work.
## Multiplayer (long term) ## Multiplayer (long term)
- [ ] `RemoteShipController extends ShipController` — feeds replicated `ShipAction`s from a network peer into the local ship simulation. - [ ] `RemoteShipController extends ShipController` — feeds replicated `ShipAction`s from a network peer into the local ship simulation.
+11 -15
View File
@@ -1,11 +1,11 @@
"""Generates Game/assets/textures/planet_surface.png (and the byte-identical """Generates Game/assets/models/nebula_planet_planet_surface.png, the sidecar
Game/assets/models/nebula_planet_planet_surface.png sidecar that actually feeds that actually feeds the live nebula_planet.glb material -- Godot's glTF
the live nebula_planet.glb material -- Godot's glTF importer extracted the importer extracted the embedded image there at import time, so the imported
embedded image there at import time, so the imported scene references that scene references that external file, not the glb's internal binary. A
external file, not the glb's internal binary): a 2048x1024 equirectangular 2048x1024 equirectangular decorative planet with latitude bands, storm
decorative planet with latitude bands, storm vortices, and a lit/unlit vortices, and a lit/unlit terminator, via layered FFT/domain-warped noise in
terminator, via layered FFT/domain-warped noise in the same style as the same style as gen_nebula_sky.py (helpers duplicated here to keep both
gen_nebula_sky.py (helpers duplicated here to keep both scripts standalone). scripts standalone).
""" """
from pathlib import Path from pathlib import Path
@@ -178,12 +178,8 @@ color = np.clip(color, 0.0, 1.0)
print("saving planet surface...") print("saving planet surface...")
root = Path(__file__).resolve().parents[2] root = Path(__file__).resolve().parents[2]
out_paths = [ out_path = root / "Game" / "assets" / "models" / "nebula_planet_planet_surface.png"
root / "Game" / "assets" / "textures" / "planet_surface.png",
root / "Game" / "assets" / "models" / "nebula_planet_planet_surface.png",
]
img = Image.fromarray((color * 255).astype(np.uint8), "RGB") img = Image.fromarray((color * 255).astype(np.uint8), "RGB")
for p in out_paths: img.save(out_path)
img.save(p) print("saved:", out_path)
print("saved:", p)
print("done") print("done")