<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Amitesh</title>
    <description>The latest articles on DEV Community by Amitesh (@amirated).</description>
    <link>https://dev.to/amirated</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4006105%2F0c8d2867-ce5d-4a4b-a00c-ec9d6816ec86.jpg</url>
      <title>DEV Community: Amitesh</title>
      <link>https://dev.to/amirated</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amirated"/>
    <language>en</language>
    <item>
      <title>Building a Fully Automated Asset Generation AI Pipeline</title>
      <dc:creator>Amitesh</dc:creator>
      <pubDate>Sun, 09 Aug 2026 06:48:29 +0000</pubDate>
      <link>https://dev.to/amirated/building-a-fully-automated-weekly-racing-challenge-generator-1j7o</link>
      <guid>https://dev.to/amirated/building-a-fully-automated-weekly-racing-challenge-generator-1j7o</guid>
      <description>&lt;p&gt;What if a racing game didn't need a developer to manually prepare its next challenge?&lt;/p&gt;

&lt;p&gt;Instead of creating a track, selecting an environment, composing a soundtrack, exporting assets, uploading files, and publishing a new build every week, the entire process could run as an automated content pipeline.&lt;/p&gt;

&lt;p&gt;That was the idea behind &lt;strong&gt;Weekly Race Generator&lt;/strong&gt;: a system that creates and publishes a new playable racing challenge on a recurring schedule.&lt;/p&gt;

&lt;p&gt;The important distinction is that the racing track itself is &lt;strong&gt;procedurally generated&lt;/strong&gt;, while the surrounding creative assets—skybox, music, artwork, and loading screen—are generated using AI.&lt;/p&gt;

&lt;p&gt;The result is a pipeline that combines deterministic procedural generation with generative AI and cloud infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;A weekly racing challenge consists of several pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A procedurally generated racing track&lt;/li&gt;
&lt;li&gt;An AI-generated skybox/environment&lt;/li&gt;
&lt;li&gt;AI-generated background music&lt;/li&gt;
&lt;li&gt;AI-generated promotional artwork&lt;/li&gt;
&lt;li&gt;A loading screen derived from the generated environment&lt;/li&gt;
&lt;li&gt;Metadata describing the competition&lt;/li&gt;
&lt;li&gt;All of the assets required by the game&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to make these pieces come together automatically.&lt;/p&gt;

&lt;p&gt;Once the system is running, the intended workflow looks roughly like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5pt44wf2c1of6dz75q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5pt44wf2c1of6dz75q9.png" alt=" " width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The interesting part isn't any individual generator. It is connecting all of them into a reliable pipeline.&lt;/p&gt;




&lt;h1&gt;
  
  
  How the system works
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. A competition is the unit of generation
&lt;/h2&gt;

&lt;p&gt;The system treats each weekly challenge as a competition with an identifier such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s1-w22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current competition is stored in a &lt;code&gt;current.json&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;This became important because the generator should not depend on an environment variable to determine which week comes next.&lt;/p&gt;

&lt;p&gt;Instead, the pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads the current competition.&lt;/li&gt;
&lt;li&gt;Determines the next competition.&lt;/li&gt;
&lt;li&gt;Generates the new challenge.&lt;/li&gt;
&lt;li&gt;Publishes it.&lt;/li&gt;
&lt;li&gt;Updates the current competition only after successful generation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes the competition state part of the generated content rather than deployment configuration.&lt;/p&gt;

&lt;p&gt;It also means that invoking the generator again naturally advances the competition.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Procedural track generation
&lt;/h1&gt;

&lt;p&gt;The track is deliberately &lt;strong&gt;not AI-generated&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The geometry is generated algorithmically according to the rules of the racing game.&lt;/p&gt;

&lt;p&gt;This provides something that generative image models aren't particularly good at guaranteeing: a track that is actually usable by the game.&lt;/p&gt;

&lt;p&gt;A procedural generator can enforce constraints such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track continuity&lt;/li&gt;
&lt;li&gt;Closed-loop topology&lt;/li&gt;
&lt;li&gt;Start/finish placement&lt;/li&gt;
&lt;li&gt;Appropriate curvature&lt;/li&gt;
&lt;li&gt;Track length&lt;/li&gt;
&lt;li&gt;Driving direction&lt;/li&gt;
&lt;li&gt;Valid checkpoints&lt;/li&gt;
&lt;li&gt;Game-specific gameplay requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output is therefore deterministic in structure even though the resulting layout can vary from one competition to another.&lt;/p&gt;

&lt;p&gt;This separation of responsibilities is useful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Algorithms guarantee gameplay; generative AI provides atmosphere and creative variation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  3. Generating the world around the track
&lt;/h1&gt;

&lt;p&gt;Once the track theme is established, the system generates the visual environment.&lt;/p&gt;

&lt;p&gt;The skybox is produced using a generative image model.&lt;/p&gt;

&lt;p&gt;For example, a futuristic city theme might produce an environment containing elevated highways, towers, neon lighting and atmospheric effects.&lt;/p&gt;

&lt;p&gt;The generated skybox then becomes an input to another stage of the pipeline.&lt;/p&gt;

&lt;p&gt;This was an important design decision.&lt;/p&gt;

&lt;p&gt;Initially, the loading screen and skybox were generated independently. Even when both were generated from the same textual theme, they could look like two completely different worlds.&lt;/p&gt;

&lt;p&gt;The solution was to make the generated skybox the &lt;strong&gt;visual source of truth&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Theme
                   │
                   ▼
              Skybox AI
                   │
                   ▼
            Generated Skybox
                   │
                   ├──────────────► Game environment
                   │
                   ▼
          Image-to-image generation
                   │
                   ▼
             Loading Screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loading screen is therefore treated as a cinematic crop of the same generated world rather than a separate interpretation of the theme.&lt;/p&gt;

&lt;p&gt;This produces much stronger visual consistency.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Music generation
&lt;/h1&gt;

&lt;p&gt;The visual assets aren't the only generative component.&lt;/p&gt;

&lt;p&gt;Each competition also gets its own music.&lt;/p&gt;

&lt;p&gt;The music generation stage uses Google's generative music capabilities through the Genblaze integration.&lt;/p&gt;

&lt;p&gt;The generator produces a soundtrack based on the theme and desired mood of the competition.&lt;/p&gt;

&lt;p&gt;This means that a weekly challenge can have its own combination of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Track layout + environment + soundtrack + artwork&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;without requiring a human to manually assemble those assets every week.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Genblaze as the generation layer
&lt;/h1&gt;

&lt;p&gt;The Python application uses the &lt;strong&gt;Genblaze SDK&lt;/strong&gt; as the foundation for interacting with the generative media providers.&lt;/p&gt;

&lt;p&gt;Rather than writing the entire application around one particular provider implementation, the project keeps generation behind application-level interfaces.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Competition Builder
        │
        ├── Track Generator
        ├── Skybox Generator
        ├── Music Generator
        ├── Artwork Generator
        └── Loading Screen Generator
                │
                ▼
           Genblaze / Providers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation makes the pipeline easier to evolve.&lt;/p&gt;

&lt;p&gt;For example, changing how a particular asset is generated does not need to change the competition orchestration itself.&lt;/p&gt;

&lt;p&gt;The application is responsible for deciding &lt;strong&gt;what needs to be generated&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The provider integrations are responsible for deciding &lt;strong&gt;how it is generated&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Backblaze B2 as the content store
&lt;/h1&gt;

&lt;p&gt;Once generation is complete, the resulting assets need somewhere to live.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Backblaze B2 Cloud Storage&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;The generated challenge is packaged with its assets and uploaded to B2.&lt;/p&gt;

&lt;p&gt;The storage hierarchy effectively becomes the content distribution layer for the game.&lt;/p&gt;

&lt;p&gt;A simplified representation looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;B2
└── competitions/
    ├── s1-w21/
    │   ├── current.json
    │   ├── manifest.json
    │   ├── skybox.png
    │   ├── loading.png
    │   ├── artwork.png
    │   ├── music.wav
    │   └── track...
    │
    └── s1-w22/
        └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important architectural decision here is that &lt;strong&gt;B2 becomes the source of truth for published content&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The generator doesn't need to remain available after a challenge has been published.&lt;/p&gt;

&lt;p&gt;The game only needs to retrieve the published challenge.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Temporary files and cleanup
&lt;/h1&gt;

&lt;p&gt;One surprisingly important part of the system was temporary file management.&lt;/p&gt;

&lt;p&gt;Some generation operations naturally produce files locally before they can be uploaded.&lt;/p&gt;

&lt;p&gt;That works differently in a serverless environment.&lt;/p&gt;

&lt;p&gt;AWS Lambda provides a writable temporary filesystem through &lt;code&gt;/tmp&lt;/code&gt;, while the deployed application itself is effectively read-only.&lt;/p&gt;

&lt;p&gt;The application therefore uses a dedicated temporary directory during generation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/tmp/scr-weekly-assets/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lifecycle is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate
   │
   ▼
Write temporary asset
   │
   ▼
Upload to B2
   │
   ▼
Delete local asset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleanup is part of the successful generation lifecycle rather than an optional housekeeping operation.&lt;/p&gt;

&lt;p&gt;After a successful run, the temporary generation directory should contain no leftover assets.&lt;/p&gt;

&lt;p&gt;This became particularly important before moving the application into Lambda because a locally working application can accidentally depend on filesystem behavior that doesn't exist in a serverless environment.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Running the generator on AWS Lambda
&lt;/h1&gt;

&lt;p&gt;The generator is packaged as a Python AWS Lambda function.&lt;/p&gt;

&lt;p&gt;The Lambda entry point is intentionally thin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda handler
      │
      ▼
build_default_app()
      │
      ▼
CompetitionApp.run()
      │
      ▼
CompetitionBuilder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generation logic does not live inside the Lambda handler.&lt;/p&gt;

&lt;p&gt;This keeps the application executable in two ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local CLI ───────┐
                ├──► CompetitionApp
Lambda handler ─┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same application code can therefore be tested locally and executed by Lambda.&lt;/p&gt;

&lt;p&gt;This was useful during development because I could run the generator locally while developing the pipeline, then deploy essentially the same execution path to AWS.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Making Python dependencies Lambda-compatible
&lt;/h1&gt;

&lt;p&gt;One of the more interesting problems appeared only after deploying the application.&lt;/p&gt;

&lt;p&gt;The initial Lambda invocation failed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No module named 'pydantic_core._pydantic_core'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Python package was present, but one of its native components had been built for the wrong platform.&lt;/p&gt;

&lt;p&gt;This is an easy problem to encounter when building Lambda deployment packages on macOS.&lt;/p&gt;

&lt;p&gt;My local machine was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;macOS
Python 3.11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while Lambda runs on AWS's Linux environment.&lt;/p&gt;

&lt;p&gt;Python dependencies containing native extensions therefore cannot always simply be copied from the local virtual environment.&lt;/p&gt;

&lt;p&gt;The deployment package needs dependencies built for the environment Lambda actually uses.&lt;/p&gt;

&lt;p&gt;This is one of those issues that isn't obvious from the application's Python code itself.&lt;/p&gt;

&lt;p&gt;Everything can work perfectly locally and still fail immediately in Lambda because the binary dependencies target a different operating system or architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. EventBridge turns the generator into an autonomous system
&lt;/h1&gt;

&lt;p&gt;With the generator working as a Lambda function, the final piece is scheduling.&lt;/p&gt;

&lt;p&gt;AWS EventBridge Scheduler invokes the Lambda periodically.&lt;/p&gt;

&lt;p&gt;The resulting architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                EventBridge
                    │
             scheduled trigger
                    │
                    ▼
             AWS Lambda
                    │
                    ▼
         Weekly Race Generator
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
    Generative AI          Procedural
      providers             systems
          │                   │
          └─────────┬─────────┘
                    ▼
               B2 Storage
                    │
                    ▼
                Game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generator no longer needs a human to start it.&lt;/p&gt;

&lt;p&gt;A scheduled event starts the process, the application determines the next competition, generates the content, publishes it to B2, and updates the competition state.&lt;/p&gt;

&lt;p&gt;That is what turns a collection of generators into an &lt;strong&gt;autonomous content pipeline&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Reliability matters more than generation
&lt;/h1&gt;

&lt;p&gt;Generating an image or a piece of music is relatively straightforward.&lt;/p&gt;

&lt;p&gt;The harder problem is making the entire operation reliable.&lt;/p&gt;

&lt;p&gt;A weekly generation job needs to answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens if an AI request fails?&lt;/li&gt;
&lt;li&gt;What happens if an asset uploads successfully but cleanup fails?&lt;/li&gt;
&lt;li&gt;What happens if the Lambda invocation is interrupted?&lt;/li&gt;
&lt;li&gt;When should the competition number advance?&lt;/li&gt;
&lt;li&gt;What happens if the same job is invoked twice?&lt;/li&gt;
&lt;li&gt;Where is the published version of the challenge?&lt;/li&gt;
&lt;li&gt;How can I determine what happened after the job finishes?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions shaped the architecture more than the individual generation APIs did.&lt;/p&gt;

&lt;p&gt;The application has explicit configuration validation, structured logging, temporary-file cleanup and a clear publishing lifecycle.&lt;/p&gt;

&lt;p&gt;AWS CloudWatch provides the execution logs, making it possible to inspect a generation run after the fact.&lt;/p&gt;




&lt;h1&gt;
  
  
  The complete pipeline
&lt;/h1&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    EventBridge
                        │
                        │ schedule
                        ▼
                  AWS Lambda
                        │
                        ▼
              Read current.json
                        │
                        ▼
             Determine next week
                        │
          ┌─────────────┼─────────────┐
          │             │             │
          ▼             ▼             ▼
     Procedural      Skybox AI     Music AI
       Track            │
          │             │
          │             ▼
          │       Loading Screen
          │        Image-to-Image
          │             │
          └──────┬──────┴──────┐
                 ▼             ▼
             Artwork       Challenge
                 │          Metadata
                 └──────┬──────┘
                        ▼
                   Upload to B2
                        │
                        ▼
                 Publish challenge
                        │
                        ▼
                 Update current.json
                        │
                        ▼
                   Cleanup /tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The game doesn't need to know how any of this happened.&lt;/p&gt;

&lt;p&gt;It simply consumes the latest published challenge.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I found most interesting
&lt;/h1&gt;

&lt;p&gt;The most interesting part of this project wasn't generating the individual assets.&lt;/p&gt;

&lt;p&gt;It was discovering how different technologies complement each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Procedural generation&lt;/strong&gt; is good at producing structured, rule-constrained content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generative AI&lt;/strong&gt; is good at producing creative, visual and musical content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Genblaze&lt;/strong&gt; provides an abstraction layer for connecting the application to generative providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Lambda&lt;/strong&gt; provides an execution environment without needing a continuously running server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EventBridge&lt;/strong&gt; provides the recurring trigger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backblaze B2&lt;/strong&gt; provides persistent storage for the generated content.&lt;/p&gt;

&lt;p&gt;Together, they form something that is more interesting than any one component:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A system that can continuously create new game content without requiring a developer to manually assemble and publish every update.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  What's next
&lt;/h1&gt;

&lt;p&gt;The natural extension is to make the generation pipeline increasingly autonomous.&lt;/p&gt;

&lt;p&gt;For example, future versions could use gameplay telemetry to influence generation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Player telemetry
      │
      ▼
Difficulty analysis
      │
      ▼
Generation parameters
      │
      ▼
New procedural track
      │
      ├──► New environment
      ├──► New music
      └──► New artwork
              │
              ▼
          Next challenge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of simply generating a new challenge every week, the system could learn what makes a challenge interesting and adapt future challenges accordingly.&lt;/p&gt;

&lt;p&gt;That would turn a scheduled content generator into a feedback-driven content system.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Weekly Race Generator started with a relatively simple question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Could a racing game continuously produce new content without someone manually building each week's challenge?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is yes—but the interesting engineering challenge is not simply calling generative AI APIs.&lt;/p&gt;

&lt;p&gt;It is building the infrastructure around them.&lt;/p&gt;

&lt;p&gt;By combining procedural game-content generation, generative media, Genblaze, AWS Lambda, EventBridge and Backblaze B2, it is possible to build a pipeline where the creation and publication of new game content becomes an automated operation rather than a recurring manual task.&lt;/p&gt;

&lt;p&gt;The broader idea extends well beyond racing games.&lt;/p&gt;

&lt;p&gt;The same architecture could be used for games that need continuously changing environments, levels, quests, artwork, music or other forms of generated content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The game becomes the consumer of a content pipeline that can keep creating new experiences on its own.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gamedev</category>
      <category>genblaze</category>
      <category>backblaze</category>
    </item>
    <item>
      <title>Building Gridzo: A Scalable Competitive Gaming Platform with Unity WebGL, Next.js and DynamoDB</title>
      <dc:creator>Amitesh</dc:creator>
      <pubDate>Sun, 28 Jun 2026 07:35:09 +0000</pubDate>
      <link>https://dev.to/amirated/building-gridzo-a-scalable-competitive-gaming-platform-with-unity-webgl-nextjs-and-dynamodb-4p24</link>
      <guid>https://dev.to/amirated/building-gridzo-a-scalable-competitive-gaming-platform-with-unity-webgl-nextjs-and-dynamodb-4p24</guid>
      <description>&lt;h1&gt;
  
  
  Building Gridzo: A Scalable Competitive Gaming Platform with Unity WebGL, Next.js and DynamoDB
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article was created as part of my submission for the H0 Hackathon.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most online competitive games are built as isolated ecosystems. Every new game typically starts from scratch with its own authentication system, leaderboards, player profiles, and progression. As an indie game developer, I wanted to build something reusable instead—a platform where competitive games could plug into a common infrastructure.&lt;/p&gt;

&lt;p&gt;That idea became &lt;strong&gt;Gridzo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gridzo is a cloud-native gaming platform that provides shared player identities, persistent profiles, leaderboards, statistics, and competitive infrastructure. The first game running on the platform is &lt;strong&gt;Sky City Rush – Competitive&lt;/strong&gt;, a Unity WebGL racing game where players compete globally across multiple tracks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I built Gridzo
&lt;/h2&gt;

&lt;p&gt;As I continued developing games, I noticed that every multiplayer or competitive title required solving the same set of backend problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Player profiles&lt;/li&gt;
&lt;li&gt;Leaderboards&lt;/li&gt;
&lt;li&gt;Match history&lt;/li&gt;
&lt;li&gt;Statistics&lt;/li&gt;
&lt;li&gt;Persistent storage&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These systems rarely depend on the gameplay itself.&lt;/p&gt;

&lt;p&gt;I wanted to separate the &lt;strong&gt;competitive platform&lt;/strong&gt; from the &lt;strong&gt;games&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That led to Gridzo—a platform where each game focuses on gameplay while Gridzo provides the competitive ecosystem.&lt;/p&gt;

&lt;p&gt;Sky City Rush became the first proof-of-concept demonstrating this architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem with game-specific competitive systems
&lt;/h2&gt;

&lt;p&gt;Traditional online games tightly couple gameplay with backend services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Game
 ├── Authentication
 ├── Profiles
 ├── Leaderboards
 ├── Statistics
 ├── Rankings
 └── Match History
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for one title but becomes increasingly difficult to maintain as additional games are introduced.&lt;/p&gt;

&lt;p&gt;Gridzo instead follows a platform approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            Gridzo Platform
         ┌────────────────────┐
         │ Authentication     │
         │ Player Profiles    │
         │ Leaderboards       │
         │ Statistics         │
         │ Game Registry      │
         └────────────────────┘
                 ▲
        ┌────────┼─────────┐
        │                  │
Sky City Rush        Future Games
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every game shares the same identity and competitive systems while remaining independent in terms of gameplay.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture overview
&lt;/h2&gt;

&lt;p&gt;The frontend is built with &lt;strong&gt;Next.js&lt;/strong&gt; and deployed on &lt;strong&gt;Vercel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The racing experience is developed in &lt;strong&gt;Unity&lt;/strong&gt; and exported as a &lt;strong&gt;WebGL&lt;/strong&gt; application hosted on &lt;strong&gt;Amazon S3&lt;/strong&gt; and delivered globally through &lt;strong&gt;Amazon CloudFront&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Player authentication is handled using &lt;strong&gt;Firebase Authentication&lt;/strong&gt;, while all persistent game data is stored in &lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The communication flow looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwyd9s1zkewk2okgnf52h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwyd9s1zkewk2okgnf52h.png" alt=" " width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This architecture cleanly separates gameplay from backend services while allowing both to evolve independently.&lt;/p&gt;




&lt;h2&gt;
  
  
  Unity ↔ Next.js communication
&lt;/h2&gt;

&lt;p&gt;One of the most interesting technical challenges was enabling communication between Unity WebGL and the Next.js application.&lt;/p&gt;

&lt;p&gt;When a player finishes a race:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unity collects the race data.&lt;/li&gt;
&lt;li&gt;A JavaScript bridge exposes browser functions to Unity.&lt;/li&gt;
&lt;li&gt;Unity submits the race result to the Next.js API.&lt;/li&gt;
&lt;li&gt;The backend validates and stores the run.&lt;/li&gt;
&lt;li&gt;Updated competitive information (such as leaderboard rank and personal best) is sent back into Unity.&lt;/li&gt;
&lt;li&gt;Unity displays an in-game result screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This creates a seamless experience where the player never leaves the game while all competitive logic is handled by the web application.&lt;/p&gt;




&lt;h2&gt;
  
  
  DynamoDB data model
&lt;/h2&gt;

&lt;p&gt;Instead of storing game-specific information, the database is designed around reusable platform concepts.&lt;/p&gt;

&lt;p&gt;Some of the primary tables include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Players&lt;/strong&gt; — Global player identities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PlayerProfiles&lt;/strong&gt; — Shared profile information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Games&lt;/strong&gt; — Registry of games available on Gridzo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GameRuns&lt;/strong&gt; — Every competitive run submitted by players&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usernames&lt;/strong&gt; — Username lookup and uniqueness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A single &lt;strong&gt;GameRuns&lt;/strong&gt; table serves as the source of truth for competitive data.&lt;/p&gt;

&lt;p&gt;Leaderboards, race history, and statistics are generated from these runs, making the architecture flexible enough to support very different types of games without redesigning the database.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scalability considerations
&lt;/h2&gt;

&lt;p&gt;Although Gridzo currently hosts only one game, it was designed with future growth in mind.&lt;/p&gt;

&lt;p&gt;Several architectural decisions contribute to scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Independent hosting for the web application and Unity assets&lt;/li&gt;
&lt;li&gt;Global asset delivery using CloudFront&lt;/li&gt;
&lt;li&gt;Stateless backend APIs&lt;/li&gt;
&lt;li&gt;DynamoDB partitioning for horizontal scaling&lt;/li&gt;
&lt;li&gt;Shared authentication across multiple games&lt;/li&gt;
&lt;li&gt;Centralized game registry&lt;/li&gt;
&lt;li&gt;Generic data models that are not tied to a specific game&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding another game should primarily involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registering the game in the &lt;strong&gt;Games&lt;/strong&gt; table&lt;/li&gt;
&lt;li&gt;Uploading the WebGL build&lt;/li&gt;
&lt;li&gt;Defining how its competitive metrics are interpreted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The existing player identities, statistics, and profile systems can then be reused without modification.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;Building Gridzo required solving several integration challenges.&lt;/p&gt;

&lt;p&gt;The biggest was establishing reliable communication between Unity WebGL and the React application. Creating a JavaScript bridge that allowed asynchronous communication between Unity and Next.js took several iterations.&lt;/p&gt;

&lt;p&gt;Deploying Unity assets separately from the frontend also introduced challenges around CORS configuration, CloudFront caching, and browser security policies.&lt;/p&gt;

&lt;p&gt;Designing a database schema that works for multiple future games instead of only Sky City Rush also required several revisions before arriving at a more generic platform-oriented model.&lt;/p&gt;

&lt;p&gt;Finally, balancing gameplay responsiveness with backend persistence was important. Race submissions needed to feel instantaneous while still updating competitive rankings reliably.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future roadmap
&lt;/h2&gt;

&lt;p&gt;Gridzo is intended to become more than a single-game platform.&lt;/p&gt;

&lt;p&gt;Future work includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-service developer onboarding&lt;/li&gt;
&lt;li&gt;Multi-game leaderboards&lt;/li&gt;
&lt;li&gt;Game-specific profile pages&lt;/li&gt;
&lt;li&gt;Ghost sharing between players&lt;/li&gt;
&lt;li&gt;Competitive tournaments&lt;/li&gt;
&lt;li&gt;Seasonal rankings&lt;/li&gt;
&lt;li&gt;Cross-game achievements&lt;/li&gt;
&lt;li&gt;Player matchmaking&lt;/li&gt;
&lt;li&gt;REST APIs and SDKs for third-party developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The long-term goal is to allow developers to publish competitive games on Gridzo while sharing a common player ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Gridzo started as an experiment in building competitive infrastructure that could outlive a single game.&lt;br&gt;
Experience Gridzo here: &lt;a href="https://gridzo.loen.in" rel="noopener noreferrer"&gt;https://gridzo.loen.in&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sky City Rush – Competitive demonstrates that vision by combining Unity WebGL, Next.js, Firebase Authentication, DynamoDB, CloudFront, and Vercel into a unified gaming platform.&lt;/p&gt;

&lt;p&gt;While there is still plenty of work ahead, the project establishes a strong foundation for a future where independent developers can build games on top of a shared competitive platform instead of rebuilding the same backend systems every time.&lt;/p&gt;

&lt;p&gt;If this hackathon marks the beginning of Gridzo's journey, I hope many more games will eventually join the platform.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! This article was created as part of my submission for the **H0 Hackathon&lt;/em&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#H0Hackathon&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webgl</category>
      <category>nextjs</category>
      <category>aws</category>
      <category>vercel</category>
    </item>
  </channel>
</rss>
