Skip to content

Type safe Game Development, is it possible?

My struggle with game development and type safety continues. It all hinges on a simple question: is it possible for a single indie developer to implement a complex game in less time with the help of types?


Games
3 min read
On this page

"I have a simple idea for a game" πŸ€”

That's how all games start. How hard could it be to create a PokΓ©mon clone after all?

And then you get smashed by complexity on your first step 🫠

This is what you are facing πŸ‘‡


Why things need to be mutable?

My conflict with game development is all around mutability (or maintainability in a broader sense).

I know for a fact that code complexity originates from unpredictable/dynamic logic. In fact, for standard apps you can get close to 100% type safety and sail safe 🚣

But not game development. Games are the wild west of mutable and scattered code. Deceptively not indie-friendly (despite so many indie games out there).

That's (part of) the origin of years and years of development for even simple games when you go solo 🀯

The complexity of an object moving on the screen

A game starts with getting something moving on the screen.

Even at this step you are flooded by complexity:

  • Game loop: in sync with the platform, synchronous, working on any machine
  • Collisions: good luck manually dealing with physics
  • Assets: asynchronous loading and performance optimization
  • Animations: state machines and sync them with frame rate and game loop

My context is mostly the web, therefore Promise, requestAnimationFrame, and static assets πŸ—οΈ

All of these get you a player moving on the screen, with a decent walking animation, stopping when hitting a wall. Not much 🫠

Adding features

This is how your future looks like:

  1. Sprite rendering
  2. Player movement and animation
  3. Tile map loading and rendering
  4. Collision detection with map
  5. Basic camera following player
  6. NPCs placed on map (static, non-moving)
  7. Simple interaction (press button to start dialogue)
  8. Basic event system (trigger dialogue, get items)

Can you spot the trick?

Each of these systems is related/dependent to each other πŸ”—

Some innocuous examples:

  • What if an NPC is moving but you want to interact with it?
  • What if you start moving on an empty tile but at the same time an NPC is moving there as well?
  • Should you be able to move behind a building (tile map layers)?

And when everything can depend on everything else, complexity spreads to the whole system 🀯

Tame complexity with types

Outside of game dev, libraries like effect tame complexity with types.

Dependencies and errors are tracked on a type level. You control their spread, and deal with it 🫑

Can this be done as well with games? I am in the process of finding out πŸ€”

First step was building an ECS library (@typeonce/ecs). It solves some problems, but not others:

  • Values are still mutable
  • Async code is not "expected"
  • Dependencies are mostly implicit (not typed)

The more I ventures into these flaws, the more it all started to resemble effect πŸ™Œ

export class SnakeGrowSystem extends SystemFactory<{}>("SnakeGrow", {
  dependencies: ["Collision"], // πŸ‘ˆ Dependency, but not on the type
  execute: ({ poll }) => {
    // ...
  },
}) {}

Alas, I started a possible implementation of a game loop with effect (and more).

My initial goal would be to have a playable website, with type safe and maintainable game code, with effect 🫑

At the moment I am still struggling with the main game loop (requestAnimationFrame), I will keep you posted πŸ”œ


Published a new article on my personal blog: Creative Constraints.

The next (big) event of the year is approaching: localfirstconf. See you in Berlin at the end of May if you plan to join πŸ”œ

See you next πŸ‘‹

Get next Wednesday’s issue

The next focused idea arrives by email. Free, and easy to leave at any time.

Free, no spam, unsubscribe anytime. See the privacy policy.