I recently jumped on the "Build Games with Amazon Q CLI and score a T shirt 🏆👕" challenge. As a developer who loves a good retro arcade game and is curious about AI-driven development, this was the perfect excuse to dive in. The mission was simple: build a game using Amazon Q's command-line interface, document the journey, and share the results.
The result? A fully-functional, nostalgic side-scrolling shooter called Space Conquer, and a ton of insights into pairing AI with a classic coding project. Here’s how it went down.
My Game: "Space Conquer" - A Modern-Classic Shooter
For my project, I chose to build Space Conquer, a side-scrolling space shooter inspired by the classic Space Impact from old Nokia phones.
Why a Retro Shooter?
- Nostalgia Factor: Like many, I have fond memories of playing Space Impact. I wanted to capture that simple, addictive fun but with a modern coat of paint—better graphics, dynamic sound, and smoother controls.
- A Great Test for AI: A 2D shooter involves a fantastic mix of programming challenges that are perfect for an AI assistant: managing game states, handling real-time user input, collision detection, and creating varied enemy behaviors.
- Extensibility: I didn't just want to build a game; I wanted to build a framework. My vision was a modular design where new enemies, power-ups, or levels could be added easily. This is where an AI's ability to generate structured, boilerplate code would really shine.
Space Conquer features diverse enemies, collectible power-ups, dynamic audio that changes with the game state, and even a hidden developer panel for testing.
Unlocking AI's Potential: Effective Prompting Techniques
Working with Amazon Q CLI is a conversation. The better your questions, the better the answers. I quickly learned that vague prompts like "make a game" were less effective than breaking down the problem into specific, well-defined tasks.
Here are a few prompting techniques I discovered.
Technique 1: Requesting a Modular Architecture
Instead of asking for a single, monolithic script, I prompted for a clean, organized structure from the start.
My Prompt: "Create a project structure for a PyGame-based space shooter. I need separate modules for asset management, sprites (player, enemies, bullets), UI components, and the main game loop. The asset manager should load images and sounds from manifest files."
The Result: Amazon Q generated a directory structure (src/, assets/, tools/) and starter Python files for each module (asset_loader.py, sprites.py, ui.py, main.py). The generated asset_loader.py included a function to read a JSON manifest, which was a huge head start.
Technique 2: Defining Behavior with Roles and Rules
When creating enemies, I defined their characteristics and constraints clearly.
My Prompt: "Generate a Python class
Enemythat inherits frompygame.sprite.Sprite. It needs attributes for health, speed, and score value. Then, create a subclassEliteEnemythat moves in a sine wave pattern down the screen and fires a bullet every 2 seconds."
The Result: Q provided a base Enemy class and a well-defined EliteEnemy subclass with its update() method already implementing the sine wave movement using math.sin(). This saved me from figuring out the trigonometry and timing loops myself.
How AI Handled Classic Programming Challenges
Game development is full of recurring problems. Here's how Amazon Q helped tackle some of the classics:
State Management: A game needs distinct states like 'main_menu', 'gameplay', 'settings', and 'game_over'. I prompted the AI to implement a simple state machine. It generated a
GameManagerclass that held the current state and handled transitions, ensuring that the main menu logic didn't run during gameplay and vice-versa.Collision Detection: A core mechanic of any shooter. I asked Q for an efficient way to check for collisions between player bullets and enemies, and between the player and enemy ships or bullets. It suggested using PyGame's built-in
pygame.sprite.groupcollide()function, providing a concise and performant solution that I could drop right into my main game loop.Power-Up Spawning: I wanted power-ups to drop randomly from destroyed asteroids. I prompted: "When an asteroid is destroyed, there should be a 15% chance of it dropping a power-up. The power-up type (health, speed, rapid-fire) should be chosen randomly." The AI generated a clean
if random.random() < 0.15:check and arandom.choice()call to select from a list of power-up types.
Time-Saving Automation: More Than Just Code
One of the biggest wins was using AI for automation around the code. The project summary mentions developer tools, and Q was instrumental here.
The Asset Manifest Generator
My game uses JSON files to manage all assets (images, sounds, maps). Manually keeping these in sync is tedious.
My Prompt: "Write a Python script for the
tools/directory that scans theassets/images/enemiesandassets/sounds/sfxdirectories and automatically generates amanifest.jsonfile with all the file paths."
This single prompt created a utility script that saved me countless minutes of error-prone manual editing every time I added a new enemy sprite or sound effect.
The Cross-Platform Launcher
I wanted a simple way for anyone to run the game, regardless of their OS.
My Prompt: "Create a Python script named
run_game.pythat checks the user's operating system. It should ensure all dependencies fromrequirements.txtare installed using pip and then launch themain.pyscript."
Q generated a script using the subprocess and sys modules that provided a one-click experience—a small but professional touch that I might have skipped otherwise.
AI-Generated Code That Impressed Me
It's one thing to generate boilerplate, but another to produce elegant solutions. Here are a couple of snippets that stood out.
1. Manifest-Driven Asset Loader
This function, generated early on, set the foundation for the game's modularity. It loads all assets listed in a JSON file into a dictionary, making them easily accessible throughout the game.
# Part of src/asset_loader.py
import pygame
import json
def load_assets_from_manifest(manifest_path):
"""Loads images and sounds based on a JSON manifest file."""
assets = {'images': {}, 'sounds': {}}
with open(manifest_path, 'r') as f:
manifest = json.load(f)
for category, files in manifest.items():
if category == 'images':
for key, path in files.items():
try:
assets['images'][key] = pygame.image.load(path).convert_alpha()
except pygame.error as e:
print(f"Error loading image {key} at {path}: {e}")
elif category == 'sounds':
for key, path in files.items():
try:
assets['sounds'][key] = pygame.mixer.Sound(path)
except pygame.error as e:
print(f"Error loading sound {key} at {path}: {e}")
return assets
# Example Usage in main.py
# ASSETS = load_assets_from_manifest('assets/manifest.json')
# player_img = ASSETS['images']['player_ship']
This design is clean, error-handled, and makes adding 50 new assets as easy as adding one.
- A Base Class for Animated UI Panels I wanted the UI to have a modern, "glowing" feel. I asked Q to create a reusable class for this.
# Part of src/ui.py
import pygame
class GlowingPanel(pygame.sprite.Sprite):
"""
A UI panel that has a subtle pulsing glow effect by alpha blending.
"""
def __init__(self, rect, color, glow_color):
super().__init__()
self.rect = rect
self.color = color
self.glow_color = glow_color
self.image = pygame.Surface(self.rect.size, pygame.SRCALPHA)
self.glow_alpha = 100
self.glow_direction = 2 # Rate of change for alpha
def update(self):
"""Update the pulsing glow effect."""
self.glow_alpha += self.glow_direction
if self.glow_alpha >= 180 or self.glow_alpha <= 80:
self.glow_direction *= -1
self.image.fill((0, 0, 0, 0)) # Clear with transparency
# Draw base panel
pygame.draw.rect(self.image, self.color, (0, 0, self.rect.width, self.rect.height), border_radius=8)
# Draw glow effect (a slightly larger rect with changing alpha)
glow_surface = pygame.Surface(self.rect.size, pygame.SRCALPHA)
glow_rect = pygame.Rect(0, 0, self.rect.width, self.rect.height)
glow_color_with_alpha = (*self.glow_color, self.glow_alpha)
pygame.draw.rect(glow_surface, glow_color_with_alpha, glow_rect, border_radius=10)
# Blit the glow onto the main surface
self.image.blit(glow_surface, (0,0), special_flags=pygame.BLEND_RGBA_ADD)
This self-contained class for a UI element with its own animation logic is a great example of the object-oriented code Q can produce. It's reusable for scoreboards, health bars, or any other panel in the game.
Final Thoughts
Using Amazon Q CLI for the "Build Games" challenge was a fantastic experience. It didn't just write code for me; it acted as a partner that handled the tedious, boilerplate, and sometimes complex parts of development, freeing me up to focus on the creative vision for "Space Conquer."
If you're a developer who hasn't tried integrating an AI assistant into your workflow, I highly recommend it. Pick a fun project, break it down into small pieces, and start prompting. You'll be surprised at how much you can build.
And hey, I might even get a t-shirt out of it.
Happy coding!

Top comments (0)