Dev Log — 24 April 2026
I addressed three items this session:
- Level Complete screen:
ShipDisplayhad no texture in the editor, making the ship invisible and preventing thruster alignment - Wave warning redesigned with new text “Warning Asteroids Incoming!” and full-width red lines above and below
- Debug shortcut added: F5 instantly triggers the Level Complete screen during debug builds for rapid testing of the level-up flow
Root cause The ShipDisplay node in LevelComplete.tscn had no texture assigned. The ship texture is set at runtime by _populate() based on GameManager.selected_ship, so in-game it works correctly. However, in the Godot editor the node appeared completely empty. This made it impossible to see the ship in the scene view and therefore impossible to align the ThrusterDisplay below it.
Fix
I added CX16-X1.png (the default ship, ship index 0) as a new ext_resource in the scene file and assigned it as the default texture on ShipDisplay:
The LevelComplete.gd script overwrites this texture at runtime with the player’s actual selected ship, so the default only acts as an editor placeholder. The ship is now visible in the Godot editor scene view, and the ThrusterDisplay can be repositioned visually to align with the ship’s engine nozzle.
ThrusterDisplay offsets to align with the ship engine.Changed The wave warning was previously a single flashing red label reading “WAVE X”. I updated it to read “Warning Asteroids Incoming!” with a full-width red line above and below the text for a more dramatic, broadcast-style look.
Layout
| Element | Y range | Size |
|---|---|---|
| Red line (top) | 446–450 | 4px tall, full 1920px wide |
| Warning label | 456–578 | 72px Neuropol, red |
| Red line (bottom) | 582–586 | 4px tall, full 1920px wide |
Architecture
A root Control node (full-rect) is added to the temporary CanvasLayer. All three elements (top line, label, bottom line) are children of that root. The flash tween targets the root’s modulate:a. Children inherit it automatically, so all three elements flash in sync with a single tween:
I reduced the font size from 96px to 72px to fit the longer string on one line at 1920px width. Total flash duration is unchanged (~1.8 s).
New Added a debug-only keyboard shortcut to instantly trigger the Level Complete flow without playing through all three waves. This is essential for testing rank progression, star awarding, the Continue/Retry buttons, and next-level unlock logic.
How to use
- Launch the game in the Godot editor (debug build)
- Start any level and press F5
- The Level Complete screen appears immediately using the current session score and health
- Stars awarded reflect actual player health at the moment F5 is pressed (3hp = 3 stars, etc.)
Implementation
Guarded by OS.is_debug_build(), so the shortcut is completely absent from exported release builds. Also checks not event.echo to avoid repeat-triggers from holding the key, and not is_game_over to prevent conflict with the game-over state.
What this tests
- Level Complete screen loads without errors
- Correct ship image displayed for the selected ship
- Score and Best values populated correctly
- Star animation plays (1, 2, or 3 stars based on health)
- Rank name shown in promotion message
- Continue button advances to next level (or Level Select if last level)
- Retry button returns to the same level
- Level stars saved correctly (check Level Select after continuing)
New Added an animated star layer (background_01_Starrs_parallax_02.png, 1920×1270, transparent PNG) to all major scenes. The layer sits between the static space background and the game/UI content, drifting gently left-right in a sine wave to give the impression of depth.
Layering
| Scene type | Method | Result |
|---|---|---|
| GameScene (Node2D) | Sprite2D, z_index = -5, between Background (z=-10) and game nodes (z=0) |
Stars behind player & asteroids, in front of static BG |
| MainMenu / LevelSelect (Node2D) | Sprite2D inserted after Background in tree, before planets/UI CanvasLayer | Stars above BG, behind planets and all CanvasLayer UI |
| LevelComplete (CanvasLayer root) | Sprite2D injected programmatically at tree index 1 inside Root Control, after Background | Stars above BG, behind Dimmer and all menu elements |
Animation: StarParallax.gd
A shared script (scripts/effects/StarParallax.gd) is applied to the Sprite2D in every Node2D scene, and loaded dynamically for LevelComplete. It moves the sprite with two overlapping sine waves: a larger horizontal drift and a subtle vertical one with a different frequency so the motion never feels repetitive:
Because the star image has a transparent background (only the star dots are opaque), the edges drifting slightly off-screen simply reveals the background, with no visible seam or gap. Adjust AMP_X / AMP_Y or SPEED_X / SPEED_Y in the script to fine-tune the feel.
Edge-Spawned Powerups (Health, Shield, Nuke)
All three powerup types now also drift in from outside the screen, in addition to health/shield dropping from destroyed asteroids. Edge-spawned powerups travel faster than dropped ones to keep them visible and reachable:
| Source | Types | Speed | Direction |
|---|---|---|---|
| Asteroid drop | Health, Shield | 35 px/s | Random angle |
| Edge spawn | Health (40%), Shield (30%), Nuke (30%) | 120 px/s | Toward screen centre |
Edge spawns happen every 18 seconds (first spawn at 12 s). Spawn point is one of the existing 8 fixed edge positions used by asteroids. The velocity is set on the PowerUp node before add_child() via the new edge_velocity property, so _ready() sees it and skips the random-drift logic.
Nuke Pickup: Instant Fire
When the player collects a Nuke powerup it immediately fires a NukeMissile in the player’s current facing direction. No button press or inventory step; the pickup is the trigger. The missile is instantiated and added to the current scene from within PowerUp._fire_nuke().
NukeMissile
New scene: scenes/entities/NukeMissile.tscn / scripts/entities/NukeMissile.gd
- Area2D, collision_layer=4, collision_mask=2 (detects asteroids, invisible to player)
- Sprite: Nuke Missile.png (34×64). Sprite rotated to align with travel direction
- Speed: 550 px/s
- Detonates on: asteroid body contact (
body_entered) OR approaching within 60px of any screen edge - A
_detonatedbool prevents double-detonation if both triggers fire on the same frame
NukeExplosion
New scene: scenes/entities/NukeExplosion.tscn / scripts/entities/NukeExplosion.gd
- Destroys all asteroids in front of the player, so asteroids behind the player’s position are safe
- The dividing line is the player’s position at fire time, perpendicular to their facing direction. A dot-product test determines which side each asteroid is on:
(asteroid_pos - fire_origin).dot(direction) > 0= in front = destroyed - Each destroyed asteroid gets its own
Explosion.tscnspawned at its location so every kill has a visual - Asteroids are destroyed via
nuke_destroy(), which skips HP and skips splits so no fragments survive. Still emitsdestroyedso score and wave-completion run normally - The player’s position (
fire_origin) and facing direction are stored on the missile at fire time, then passed to the explosion on detonation - Animation: starts at scale 0.2, pops to 1.2 (TRANS_EXPO, NE1 frame), switches to NE2, expands to 1.7 while fading to alpha 0 (total ~0.7 s)
- z_index = 5 so the fireball renders above everything
Bug fixed Initial implementation called asteroid.hit() once per asteroid. Asteroids have 3–4 HP (one per damage-state image) so a single hit only damaged them, so nothing actually died. Fixed by adding nuke_destroy() to Asteroid.gd which bypasses HP entirely and skips split-spawning.
Assets used
- Game Assests/Powerups/Nuke-PU.png: 100×100 pickup icon
- Game Assests/Powerups/Nuke Missile.png: 34×64 missile sprite
- Game Assests/Nuke Explosion/NE1.png: 600×600 explosion frame 1
- Game Assests/Nuke Explosion/Ne2.png: 600×600 explosion frame 2
- Level Complete: ThrusterDisplay position still needs manual alignment in the editor now that the ship is visible
- Level Complete: remaining visual polish pass (user identified layout tweaks needed)
- Star parallax: consider adding to PauseMenu, Settings, and CharacterShop scenes if they need the effect too (Splash now covered)
- Mobile joystick input not wired to player movement
- Audio bus muting on session start (respect saved music_enabled / sfx_enabled)
- HUD nuke count display:
update_nukes()is still a stub (pass); needs icon + counter in HUD scene - Rank-up nukes (stored in
nukes_held) still have no activation; separate from the pickup nuke, it needs a button or gesture - Coin shop / IAP integration
- Endless mode difficulty scaling (currently stays at level-0 speed forever)