Mini Space Shooter
- 4 Devlogs
- 11 Total hours
Mini Space Shooting Game
Mini Space Shooting Game
I’ll take that as: write the release-version devlog. Here it is (under 4000 characters):
Devlog: Space Shooter — v1.0 Complete 🚀
Status: Finished and playable
Wrapping up development on my Pygame arcade space shooter. Full loop is in, polished, and stable. Here’s the rundown of what shipped.
The game
Vertical arcade shooter — dodge and blast descending aliens, survive as long as possible, level up every 150 points. Everything renders from a single Python file with zero external art assets; every sprite is built at runtime from primitive shapes (polygons, ellipses, circles) layered with shading.
Final feature set
Ship & enemies: Hand-built ship sprite (glowing cockpit, thruster fins, nav lights) and three alien variants with distinct color palettes
Combat: Standard laser fire plus a Multi-shot power-up that fires a 3-way spread; Rapid Fire halves cooldown
Power-ups: Shield (temporary invincibility), Multi-shot, Rapid Fire, and extra Life — each spawns randomly, pulses with a glow ring, and runs on its own timed duration
Progression: Score-based leveling that scales enemy speed and spawn rate, cycling through three distinct background themes (deep space, magenta nebula, red giant) as you climb levels
Atmosphere: Three-layer parallax starfield with per-star twinkle, drifting rotating asteroids with seeded procedural craters, random comet streaks with fading tails, a soft vignette, and glow-text HUD rendering
Feedback: Explosion particles (debris + spark types), expanding shockwave rings, camera shake, and a red damage flash on hit
Game loop: Clean reset-and-restart via a single reset() call, full game-over screen with final score and level reached
Technical highlights
Asteroids generated once via seeded RNG for unique jagged silhouettes, then just rotated/tinted per frame — cheap and visually rich
Bullets share one update path regardless of straight vs. angled trajectory via a vx field
All power-up timers live in one dict, decremented per frame — no separate timer objects
Collision detection is straightforward rect-based checks; performant at this entity density
Reflection
The biggest win here was proving how much atmosphere you can generate procedurally — no sprite sheets, no external assets, just math and layered shapes. The gradient backgrounds, particle systems, and glow effects did most of the heavy lifting for “game feel.”
What’s not included (by choice)
No sound, no persistent high scores, no boss fights — kept scope tight to ship a complete, polished core loop rather than sprawl into unfinished extras.
That’s a wrap on v1.0. Solid, self-contained, single-file arcade shooter.
Devlog — Visual Pass on the Space Shooter
Went back into the shooter today because the core loop felt good but the screen was still kind of flat and empty between waves. Didn’t touch gameplay balance — this was purely a “make it feel alive” pass.
Background depth. The nebula/planet gradients were already there but nothing moved in front of them, so the parallax felt thin. Added a slow-drifting asteroid field behind the stars — reused the same “irregular polygon + a couple of craters” trick as the alien sprites, just tinted down and desaturated so they read as background clutter instead of threats. Took a bit of fiddling to get the tint right; too dark and they disappear into the gradient, too bright and they compete with the actual enemies.
Also added rare comet streaks that cut across the top of the screen every few seconds. Small thing, but it breaks up long stretches where nothing new is happening on screen.
Combat feedback. Explosions were just round particles before — added a handful of streaky “spark” debris mixed in with the dots so hits feel punchier, plus floating +10 score popups and booster name popups so pickups/kills give you something to actually read instead of just a number ticking up in the corner. Bullets now drag a short fading trail, which sounds minor but makes rapid-fire actually look rapid instead of just spawning dots.
Danger telegraph. Aliens now get a pulsing red glow under them once they cross into the bottom third of the screen — a cheap way to warn the player before a collision without adding any new mechanics. Also gave the ship a faint thruster trail so movement has some weight to it.
HUD. Added a thin progress bar under the score bar showing how close you are to the next level, since before the only signal was the banner popping up out of nowhere. Engine flame now shifts gold when rapid-fire is active, just a small color-coded readability thing.
Polish. Threw a soft vignette over the whole scene (precomputed once, not per-frame — learned that lesson the hard way on an earlier project) to pull focus toward the center. Star colors are no longer uniform blue-white; ~1 in 4 get a warm tint so the field doesn’t look like a uniform noise texture.
Didn’t touch: spawn rates, scoring, lives, booster durations. All of it should feel exactly the same to play, just louder and busier to look at. If it turns out the asteroid field is too distracting during heavy waves I’ll dial the tint/count down — for now it’s 7 rocks max on screen which felt like the sweet spot.
Next up, probably: giving the aliens some actual variation in movement patterns instead of straight-down drift, since right now the visual noise is doing more work than the AI is.
devlog: made a space shooter, drew every sprite with pygame.draw
had an itch to build a little arcade shooter — dodge and shoot aliens, grab power-ups, level up, don’t die. gave myself one dumb rule first: no image files. no sprite sheets, no downloading pixel art. every ship, alien, laser and icon gets built out of circles/polygons at startup and cached. mostly so I didn’t have to deal with asset folders, but also just to see if it’d look decent. mostly does, once you cheat with alpha blending enough.
the ship is like six polygons wearing a trenchcoat
get_ship_img() is genuinely a pile of triangles and ellipses stacked up — two wing shapes, two SMALLER brighter polygons on top of those, a nose triangle, a cockpit ellipse, a white highlight blob. that second brighter polygon on the wings does basically all the work — first draft with flat single-color wings looked like clipart from 2004. one lighter layer on top and it suddenly reads as “metal panel” instead of “shape.” cheap trick, huge payoff.
aliens (get_alien_img) are the same idea, cycling through 3 base colors so a wave doesn’t look like clones (they are clones but shh). the eyes were an afterthought that became my favorite detail — two yellow circles with dark pupils, pulsed with sin(ticks * 0.006 + phase) at draw time so each alien blinks out of sync with the others. kills the “identical enemies marching in lockstep” feeling.
backgrounds took longer than they should have
didn’t want a static black screen with some stars, so each level has a theme — gradient colors, a couple nebula blobs, a planet in a corner. gradient’s just a line per row lerping color, baked once per level into bg_cache instead of redrawing every frame (felt dumb I didn’t do that from the start).
the nebula thing (add_nebula_blob) is my favorite bit for how little code it is — ~10 shrinking, increasingly transparent circles with BLEND_RGBA_ADD so overlaps brighten instead of turning muddy. expected to need noise textures, got a for loop instead.
explosions, and the cheapest screen shake ever
on death (spawn_explosion) 16 particles fly out with gravity, plus a separate expanding ring. particles alone felt weak, ring alone felt bloodless, both together actually sells it.
screen shake: render the whole frame to an offscreen surface, blit THAT onto the real window with a random offset for a few frames after a hit. no shaking individual sprites, no camera object. one extra surface and a randint call.
power-ups + difficulty as basically one line of math
four boosters — rapid fire, shield, 3-way spread, extra life — drift down on a timer. active ones live in a dict with a countdown, so stacking effects and drawing HUD bars was just one loop, no special-casing per power-up.
difficulty is deliberately dumb: every 150 points = next level, speeds up enemies, spawns more often, capped so it’s not unplayable by level 20. background palette also cycles on level-up, which sells “progress” more than the actual curve does. never underestimate just changing the sky color.
why it’s async even though it’s not a web app yet
main loop is async def main() with await asyncio.sleep(0) per frame instead of blocking while True. weird for desktop pygame, but means I can run it through pygbag later in an actual browser tab without freezing the page. easier to start async than retrofit it.
still on the list
enemies are all “same alien but faster” — want real patterns or a boss
zero sound, biggest thing making it feel unfinished
no persistent high score
shield + multi-shot together trivialize a level, needs tuning
A space shooting game that should look like this i have made the basic outline of it which is similer but it doesnt have any spaceships or a baground it only has basic colors and shapes instead of spaceships