My First AI-Powered Game: A Retro Cricket Adventure with Amazon Q

Darshan JoshiDarshan Joshi
10 min read

Ever wondered if artificial intelligence could truly be your co-pilot in bringing a game to life? I certainly did! Embarking on the thrilling AWS Build Games Challenge, I decided to put Amazon Q Developer CLI to the ultimate test: crafting a nostalgic retro cricket game from scratch. Join me as I recount every delivery and boundary of this unique development journey, revealing how simple prompts transformed into a pixelated pitch, dynamic bowling, and the sweet sound of a six!

My Chosen Game: Why Retro Cricket?

The "retro" theme immediately sparked an idea: a classic cricket game. As someone who grew up with pixelated arcade classics, the thought of recreating that simple, addictive sporting action with a modern AI twist was incredibly appealing. I chose Pygame as my framework due to its straightforward nature and excellent compatibility with retro graphics, making it perfect for capturing that 8-bit aesthetic. My initial vision was a straightforward batting simulation – a player controlling a batsman, trying to hit dynamically bowled balls, score runs, and avoid getting out. It seemed like the ideal blend of familiar game mechanics and enough complexity to truly test Amazon Q's capabilities. Plus, who doesn't love the satisfying thwack of a well-timed shot in a retro game?

Fielding AI's Power: Effective Prompting Techniques

Diving into game development with an AI assistant like Amazon Q was a revelation. The biggest lesson? It’s not about magic, but about smart, iterative prompting. I quickly learned that you don't simply ask Q to "make a cricket game." Instead, the trick is to break down every single feature, no matter how small, into atomic prompts. Below are images for the prompt.

Analyzed the most effective prompting techniques discovered during the session:

  • Progressive complexity building (foundation → enhancement pattern)

  • Specific technical requirements with bullet points

  • Domain-specific context using cricket terminology

  • Iterative enhancement requests building on previous work

  • Multi-requirement bundling for related features

  • Visual and behavioral specifications combined

  • Problem-solution framing with clear cause-effect relationships

  • Comprehensive final requests for complete packages

  • Contextual flexibility with options and preferences

  • Documentation integration as part of development Key patterns: Foundation→ Enhancement, Specific Bullet Points, Build Upon Previous, Complete Package, Domain Expert approaches

AI on the Pitch: Handling Classic Programming Challenges

Amazon Q truly shone as a problem-solver, especially when tackling classic game development hurdles. It felt like having an expert programmer constantly ready to provide solutions.

One of the first significant challenges was collision detection between the ball and the batsman's bat, especially when factoring in the batsman's 'swing' state. Q not only generated the core collision logic but also suggested how to make the ball's bounce directional based on where it hit the bat.

# Example of AI-generated collision/bounce logic
if ball_rect.colliderect(batsman_rect) and batsman_swinging:
    ball_speed_y *= -1  # Reverse vertical direction

    # Calculate hit point relative to bat center for horizontal deflection
    hit_point = ball_rect.centerx - batsman_rect.centerx

    # Adjust horizontal speed based on hit point
    # (Q provided coefficients and explanation for this)
    ball_speed_x = hit_point * 0.05 # Adjust this coefficient based on desired angle

Beyond simple collisions, Amazon Q was instrumental in handling state management for the game (e.g., normal play, game over, batsman swinging) and even rudimentary physics for the ball's movement and trajectory after a hit.

Perhaps one of the most invaluable aspects was debugging assistance. Whenever Pygame threw an error, It would quickly identify the issue, explain why it was happening, and often provide the exact code fix. This dramatically cut down on debugging time, allowing me to stay focused on building.

Provided detailed analysis of how classic programming challenges were addressed during development:

  • Game loop & state management with clean state machines

  • Real-time input handling with dual input methods

  • Physics & collision detection with realistic ball mechanics

  • AI & pathfinding for fielder behavior

  • Audio generation without external files using procedural synthesis

  • Animation & visual effects with mathematical functions

  • Object-oriented design with clean class separation

  • Memory management with object reuse patterns

  • Event-driven programming with centralized event handling

  • Error handling & robustness with graceful degradation

  • Performance optimization for 60 FPS gameplay

  • User experience design with intuitive controls

  • Scalable architecture for future enhancements

Automating the Game: Development Time Savers

Amazon Q wasn't just a debugger; it was a significant automation engine. It acted as a rapid scaffolder, freeing me from mundane, repetitive coding tasks.

  • Boilerplate Generation: Setting up the basic Pygame window, game loop, and event handling is always the first step. Amazon Q handled this in seconds, giving me a functional foundation without having to type out standard boilerplate. This saved minutes on every new game iteration.

  • Feature Scaffolding: For every new feature, from scoring to wicket logic, Q provided the initial function and class structures. I could simply describe what I wanted (e.g., "Implement a scoring system that awards 1, 4, or 6 runs based on hit type"), and Q would lay out the basic code, including variables, update functions, and display logic. This allowed me to jump straight into refining the game mechanics rather than building them from the ground up.

  • Rapid Prototyping: This was a game-changer. I could quickly test different ideas for ball movement, scoring conditions, or even visual elements by asking Q to generate a small code snippet, integrating it, and seeing the result almost instantly. It made experimentation incredibly efficient.

Detailed examples of development automation techniques that saved significant time:

  • Cross-platform launcher automation with dependency checking

  • Procedural audio generation eliminating need for audio assets

  • Screenshot generation automation for demo materials

  • Project structure generation with automated file organization

  • Game object management with automated positioning and AI

  • Documentation generation from code structure and session history

  • State management automation with event-driven transitions

  • Animation system automation with mathematical effects

  • Build and packaging automation for distribution

  • Dependency management automation with graceful degradation

  • Performance monitoring automation with frame rate control Total estimated time saved: ~13 hours of manual work automated

Striking Solutions: Interesting AI-Generated Code Examples

Throughout the development process, Amazon Q generated some genuinely elegant and insightful code. Here are a couple of examples that particularly impressed me:

Dynamic Ball Behavior, Power-Ups, and Outcome Detection (Ball.update method)

One of the most complex parts of the game was making the ball's behavior dynamic, implementing power-ups, and determining game outcomes (runs, wickets, boundaries) based on its trajectory. Amazon Q helped craft a comprehensive update method for the Ball class that handles all of this in one place.

This method not only applies effects like fast, slow, or curve based on active power-ups (even changing the ball's color!), but also cleverly checks various conditions to determine if a run has been scored (a 'six' by going too high), if a 'wicket' has been taken (missed by batsman), or if a 'boundary' has been hit (ball goes too far from center). The return values make it easy for the main game loop to update the score and game state.

def update(self):
        # Apply power-up effects
        if self.power_up == 'fast':
            speed_multiplier = 1.5
            self.color = YELLOW
        elif self.power_up == 'slow':
            speed_multiplier = 0.7
            self.color = BLUE
        elif self.power_up == 'curve':
            speed_multiplier = 1.0
            self.speed_x += math.sin(pygame.time.get_ticks() * 0.01) * 0.1
            self.color = (255, 0, 255)  # Purple
        else:
            speed_multiplier = 1.0
            self.color = RED

        # Update position
        self.x += self.speed_x
        self.y += self.speed_y * speed_multiplier

        # Add to trail
        self.trail.append((int(self.x), int(self.y)))
        if len(self.trail) > 10:
            self.trail.pop(0)

        # Boundary checks
        if self.x - self.radius <= 0 or self.x + self.radius >= SCREEN_WIDTH:
            self.speed_x *= -0.8
            self.x = max(self.radius, min(SCREEN_WIDTH - self.radius, self.x))

        # Check boundaries
        center_x, center_y = SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2
        distance_from_center = math.sqrt((self.x - center_x)**2 + (self.y - center_y)**2)

        if distance_from_center > 300:  # Hit boundary
            self.reset_position()
            return "boundary"
        elif self.y > SCREEN_HEIGHT // 2 + 180:  # Missed by batsman
            self.reset_position()
            return "wicket"
        elif self.y < SCREEN_HEIGHT // 2 - 200:  # Ball went too high (6 runs)
            self.reset_position()
            return "six"

        return None

    def check_collision(self, batsman):
        bat_x = batsman.x + batsman.width // 2
        bat_y = batsman.y + batsman.height // 2
        bat_width = 35 if batsman.stance == 'swing' else 25
        bat_height = 10

        if (bat_x - bat_width//2 <= self.x <= bat_x + bat_width//2 and
            bat_y - bat_height//2 <= self.y + self.radius <= bat_y + bat_height//2 and
            self.speed_y > 0):

            hit_position = (self.x - bat_x) / (bat_width // 2)
            hit_position = max(-1, min(1, hit_position))

            # Power depends on stance
            if batsman.stance == 'swing':
                power = 8
            elif batsman.stance == 'defensive':
                power = 4
            else:
                power = 6

            self.speed_y = -power
            self.speed_x = hit_position * 5

            # Add randomness
            self.speed_x += random.uniform(-0.5, 0.5)
            self.speed_y += random.uniform(-1, 0.5)

            return True
        return False

Adding Flair: Dynamic Celebration Animations (draw_celebration method)

Beyond just core mechanics, Amazon Q also helped me add significant visual flair to the game, particularly with the celebration animations. This draw_celebration method is a testament to how AI can assist with more artistic and dynamic elements of game design, not just logic.

This function handles:

  • Pulsing Text: Creating a vibrant, pulsating effect for the celebration messages.

  • Contextual Messaging: Displaying different messages for 'boundary', 'six', or batting 'milestones' (fifty, century, etc.).

  • Background Flashes: Adding a subtle, alpha-blended flash effect to the screen, with different colors for boundaries/sixes versus milestones.

  • Shadow Effects: Enhancing text readability and visual pop with shadow rendering.

  • Milestone Animations: For bigger achievements like fifties or centuries, it draws animated, rotating stars around the central message, adding a delightful retro sparkle.

# This function handles all visual aspects of in-game celebrations for runs and milestones.

def draw_celebration(self):
    """Draw celebration animations and messages"""
    # Create pulsing effect for text
    pulse = int(abs(math.sin(self.celebration_timer * 0.1)) * 50)

    # Dictionary of celebration messages
    messages = {
        'boundary': "BOUNDARY! 4 RUNS!",
        'six': "SIX! MAXIMUM!",
        'fifty': "FIFTY! WELL PLAYED!",
        'century': "CENTURY! FANTASTIC!",
        'one_fifty': "150 RUNS! AMAZING!"
    }

    if self.celebration_type in messages:
        # Background flash effect for impact
        flash_alpha = int((self.celebration_timer / 180) * 100) # Fades in and out
        flash_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        flash_surface.set_alpha(flash_alpha) # Set transparency

        if self.celebration_type in ['boundary', 'six']:
            flash_surface.fill(YELLOW) # Yellow flash for runs
        else: # Milestones
            flash_surface.fill((255, 215, 0)) # Gold flash for milestones

        self.screen.blit(flash_surface, (0, 0)) # Draw flash over screen

        # Main celebration text (pulsing color)
        celebration_color = (255, 255 - pulse, 0) # Pulsing yellow-red
        celebration_text = self.large_font.render(messages[self.celebration_type], True, celebration_color)
        text_rect = celebration_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))

        # Add shadow effect for text
        shadow_text = self.large_font.render(messages[self.celebration_type], True, BLACK)
        shadow_rect = shadow_text.get_rect(center=(SCREEN_WIDTH//2 + 3, SCREEN_HEIGHT//2 + 3))
        self.screen.blit(shadow_text, shadow_rect)
        self.screen.blit(celebration_text, text_rect)

        # Additional effects for milestones (e.g., drawing stars)
        if self.celebration_type in ['fifty', 'century', 'one_fifty']:
            for i in range(8): # Draw 8 rotating stars
                angle = (i * 45) + (self.celebration_timer * 2) # Angle for star position and rotation
                star_x = SCREEN_WIDTH//2 + math.cos(math.radians(angle)) * 100
                star_y = SCREEN_HEIGHT//2 + math.sin(math.radians(angle)) * 50
                pygame.draw.polygon(self.screen, YELLOW, [ # Coordinates for a simple star shape
                    (star_x, star_y - 10), (star_x + 3, star_y - 3), (star_x + 10, star_y - 3),
                    (star_x + 5, star_y + 2), (star_x + 8, star_y + 10), (star_x, star_y + 6),
                    (star_x - 8, star_y + 10), (star_x - 5, star_y + 2), (star_x - 10, star_y - 3),
                    (star_x - 3, star_y - 3)
                ])

Gameplay Showcase: My Final Creation!

After many rounds of prompting, refining, and testing, my retro cricket game came to life! It features a moving batsman, dynamic bowling, clear scoring for 1s, 2s, 3s, 4s, and 6s, and even basic 'out' conditions like bowled and missed shots. The static fielders and stadium elements add to the nostalgic atmosphere, making it feel like a genuine throwback.

Here are a few screenshots showcasing the game in action:

Conclusion: Beyond the Boundary!

Building this retro cricket game for the AWS Build Games Challenge was an incredibly insightful experience. Amazon Q Developer CLI proved to be an invaluable assistant, transforming the coding process from a solo endeavor into a dynamic collaboration with AI. It's clear that generative AI isn't here to replace developers, but to empower us, accelerating development, automating tedious tasks, and providing instant solutions to programming challenges.

This project demonstrated the true power of iterative prompting and how AI acts as an intelligent co-pilot, helping you to rapidly prototype ideas and focus on the creative aspects of game design. If you're looking to speed up your development workflow or just curious about AI's practical applications, I highly recommend giving Amazon Q a try.

Feel free to check out the full code on my GitHub repository here: Repository

And there you have it – the full innings of my retro cricket game, bowled and batted with the intelligent assistance of Amazon Q. This journey proved that AI can be a powerful co-pilot, turning concepts into code with remarkable speed. Now it's your turn! Have you used AI in your game development, or are you inspired to start? Share your thoughts, questions, or even links to your own creations in the comments below. Let's keep building!

0
Subscribe to my newsletter

Read articles from Darshan Joshi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Darshan Joshi
Darshan Joshi

A dedicated Computer Engineering graduate from SCET. Throughout my academic journey, I navigated the dynamic landscape of education during the challenging Covid era, which instilled in me resilience and adaptability. My experience in the field of Data Engineering spans across Transact SQL, MS SQL Server, Agile Methodologies, and a foundational understanding of Azure Data Factory and various cloud services. These experiences have not only honed my technical acumen but also reinforced my capacity to thrive in diverse and evolving environments. My current pursuits reflect a keen interest in expanding my knowledge in both DevOps and Cloud Engineering. Alongside these technical endeavors, I'm fervently learning Full Stack Web Development from the ground up, eager to explore the intricate interplay of front-end and back-end systems. Embracing a holistic approach to problem-solving, I'm delving into the intricacies of System Design, striving to develop comprehensive and efficient solutions within the IT industry. Building on approximately 6 months to 1-year of hands-on industry experience, I'm driven to continuously enhance my skill set, contributing meaningfully to the technological landscape. Beyond the realms of technology, I find solace in capturing the ephemeral beauty of sunsets through photography, letting the time freeze those breathtaking moments. Music is my constant companion, offering relaxation and inspiration. As an avid cricket enthusiast, the game brings camaraderie and excitement. I'm always open to connecting with fellow professionals, learning from shared experiences, and contributing to the ever-evolving tech sphere. Let's connect and explore the limitless possibilities together!