← Back to home
Workshop

How I Build HTML5 Games with AI Agents and My Own SDK

AI-assisted HTML5 game development cover

AI helps a lot with writing code, but AI alone is not enough for game development.

If you ask an agent to “make a game”, it can quickly produce a prototype. The problems usually start later: when you need to add mechanics, fix bugs, change layout, optimize loading, support resize, audio, animations, and scene transitions.

Games have a lot of state and side effects. Without architecture, AI starts generating different solutions for the same types of problems.

My approach is simple: AI agents write code, but they work inside a predefined architecture.

That is why I built my own HTML5 game SDK:

Block Puzzle is a complete game built on this SDK. It has a boot scene, preload, layout JSON, prefab JSON, FSM, commands, scene services, a domain model, components, drag-and-drop, score, game over, best score, sounds, and a production build.

Why the SDK Exists

The SDK is not there to hide all game code.

Its job is to define the project rules:

  • scene flow: lifecycle, FSM, commands, scene services, domain model;
  • visual composition: layout nodes, components, actions, prefabs;
  • runtime systems: assets, input, tweens, audio, screen state, persistence;
  • boundaries: what belongs to the game and what belongs to the SDK.

After that, an agent does not have to invent the structure every time. It should work inside the existing boundaries.

In Block Puzzle, the scene class is almost empty:

export class GameScene extends FsmDrivenScene {}

That is a good state for a scene. The scene should not contain all gameplay logic.

The two main flows are separated:

Scene flow
FSM Command Scene Service Domain Model
Visual layer
Layout JSON Node Component / Action

This matters for AI-assisted development. It is much easier for an agent to change a small class with one responsibility than to work with a large scene file that mixes game rules, PIXI objects, animations, input, and progress saving.

Example: Placing a Block

Take the main action in Block Puzzle: the player drags a shape onto the board.

The Problem

The bad version is to put everything into one component.

God component

  • pointer events
  • placement preview
  • board mutation
  • line clearing
  • score calculation
  • UI update
  • effects
  • game over check

This code can work, but it is hard to evolve.

The Actual Flow

In the current architecture, the simplified flow is:

1 Drag component handles input and preview, then emits PlacementRequested
2 FSM + command moves to resolvingPlacement and runs PlaceBlockCommand
3 Gameplay service validates placement and updates session state
4 Board / Slots / Score domain model applies the game rules
5 Events + visual components PlacementCompleted, BoardChanged, BlocksChanged, ScoreChanged update the screen

As a result, game rules do not depend on PIXI, and visual components do not calculate score.

This is not architecture for its own sake. This is how I keep the project in a state where a new task can be given to an agent with a clear scope.

Code Shape

The top-level code stays small. The FSM decides when placement should be resolved:

playing: {
  on: {
    [BlockPuzzleEvents.PlacementRequested]: {
      target: 'resolvingPlacement',
      actions: ['PlaceBlockCommand'],
    },
  },
}

The command is only a boundary between the FSM event and the scene service:

export class PlaceBlockCommand extends BaseTypedCommand<PlaceBlockCommandPayload> {
  protected override readonly inputDecoder =
    BlockPuzzleEventSchemas.PlacementRequest;

  protected override execute(payload: PlaceBlockCommandPayload): void {
    this.getSceneService(BlockPuzzleServices.Gameplay).place(payload);
  }
}

The service owns the session update and delegates the rules to the domain model:

export class BlockPuzzleGameplayService extends BaseSceneService {
  place(request: PlacementRequest): void {
    // Read current session state and validate the requested shape.
    // Apply board, slots, line-clear, and scoring domain rules.
    // Build a MoveResult for visual components and follow-up commands.
    // Emit placement, board, blocks, line-clear, and score events.
  }
}

What Belongs in the SDK

I try to keep game code focused on the specific game.

Reusable infrastructure should move into the SDK when it appears across projects.

Orchestration

  • scene lifecycle
  • FSM
  • commands
  • events
  • scene services
  • scene-scoped DI

Layout and interaction

  • layout nodes
  • components and actions
  • prefabs
  • responsive layout
  • input routing
  • drag interactions

Data and assets

  • typed config decoding
  • settings and storage
  • asset manifest
  • asset bundles
  • texture resolution

Runtime and safety

  • screen manager
  • audio
  • tween ownership
  • async scope safety
  • physics and particles
  • platform integrations
  • fail-fast errors

How I Work with AI Agents

My usual workflow:

  1. Describe the task and limit the scope.
  2. Let the agent read local project rules and the current implementation.
  3. Make the change inside the existing architecture.
  4. If game code starts getting repeated helpers, check whether they should become part of the SDK.
  5. Run typecheck and lint after the change.
  6. Review the result like a normal code review.

The main rule: the agent should not replace the project architecture.

When I add a new feature, I first choose where it belongs:

Problem Where it belongs
gameplay rule domain
use-case step command
scene runtime state scene service
visual behavior component / action
repeated visual structure prefab
authored values layout / config JSON
generic lifecycle / input / assets / tween problem SDK

This way AI helps write code faster without breaking the project structure.

Why Not Everything Belongs in Game Code

You can keep the SDK minimal and solve everything inside a specific game. On the first project, that may look faster.

The problem appears on the next projects. Lifecycle guards, asset helpers, responsive helpers, prefab helpers, and debug hooks start getting copied. After a while, it becomes unclear which version is the correct one.

So I keep the same boundary from the workflow above: game-specific rules stay in game code, reusable infrastructure moves to the SDK, and authored presentation data stays in layout/config files. This boundary helps both the developer and the AI agent.

Next Topics

Next, I want to cover the individual parts and practical details of working with my SDK on real projects:

  • adaptive and responsive layout;
  • smart resource loading;
  • FSM in game scenes;
  • components and actions;
  • safe tweens and async operations;
  • debug services for DevTools;
  • workflow with Codex, VS Code, Figma, and Photopea;
  • gameplay iterations using Block Puzzle as an example;
  • and other similar practical topics.

The main idea: AI is useful in game development when the project has clear boundaries.

Without boundaries, AI accelerates chaos. With boundaries, AI accelerates development.