# Aztecs v0.14.0 released - A modular game engine and ECS

**URL:** https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672
**Category:** Announcements
**Created:** [August 10, 2025, 4:06pm UTC](https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672 "2025-08-10T16:06:15Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![matthunz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/matthunz/32/4980_2.png) [@matthunz](https://discourse.haskell.org/u/matthunz)
#### Post date: [August 10, 2025, 4:06pm UTC](https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672/1 "2025-08-10T16:06:15Z")

</div>

Hey endofriends! I’m really excited to share the latest version of Aztecs, a modular game engine and Entity Component System (ECS) built with Haskell 😃

> **[Release aztecs-v0.14.0 · aztecs-hs/aztecs](https://github.com/aztecs-hs/aztecs/releases/tag/aztecs-v0.14.0)**
>
> What's Changed
> 
> refactor: remove f wrapper from HSet by @matthunz in #44
> ci: fix caching by @matthunz in #45
> feat: make W generic over storages by @matthunz in #47
> fix: HasDuplicateWrites and refac...

> **[aztecs](https://hackage-content.haskell.org/package/aztecs-0.14.0)**
>
> A modular game engine and Entity-Component-System (ECS) for Haskell.

The latest version now relies heavily on in-place mutation through a type-level [`Query`](https://hackage-content.haskell.org/package/aztecs-0.14.0/docs/Aztecs-ECS-Query-Class.html) API, that provides compile-time guarantees for read and write access. A `System` can then be implemented by taking some ECS access as input:

```haskell
-- Components

newtype Position = Position Int
  deriving (Show, Eq)

instance (Monad m) => Component m Position where
  type ComponentStorage m Position = SparseStorage m

newtype Velocity = Velocity Int
  deriving (Show, Eq)

instance (Monad m) => Component m Velocity where
  type ComponentStorage m Velocity = SparseStorage m

-- System

data MoveSystem = MoveSystem

instance (PrimMonad m, MonadIO m) => System m MoveSystem where
  type SystemIn m MoveSystem = Query (W m Position, R Velocity)

  runSystem \_ = mapM\_ go
    where
      go (posRef, R (Velocity v)) = do
        modifyW posRef $ \\(Position p) -> Position (p + v)

        p <- readW posRef
        liftIO $ putStrLn $ "Moved to: " ++ show p

```

[`System`](https://hackage-content.haskell.org/package/aztecs-0.14.0/docs/Aztecs-ECS-System.html)s can then be automatically scheduled with `Before` and `After` constraints, and in-parallel (if possible), at the type-level (also with compile-time errors):

```haskell
app ::
  HSet
    '[Run '[] MoveSystem,
       Run '[After MoveSystem] PhysicsSystem,
       Run '[After PhysicsSystem] CombatSystem,
       Run '[After CombatSystem] RenderSystem
     ]

```

I’m also really curious about how this generic [`ECS`](https://hackage-content.haskell.org/package/aztecs-0.14.0/docs/Aztecs-ECS-Class.html) class might be used, I’ve been trying to get it as minimal as possible to potentially support a wide-range of ECS backends (like Apecs or maybe bindings to something like Bevy or Flecs):

```haskell
-- | Entity Component System (ECS) implementation.

class ECS m where
  -- | Entity identifier.

  type Entity m :: Type

  -- | Task monad for running systems.

  type Task m :: Type -> Type

  -- | Spawn a new entity with a `Bundle` of components.

  spawn :: Bundle (Entity m) m -> m (Entity m)

  -- | Insert a `Bundle` of components into an existing entity

  -- (otherwise this will do nothing).

  insert :: Entity m -> Bundle (Entity m) m -> m ()

  -- | Remove an entity and its components.

  remove :: Entity m -> m ()

  -- | Run a `Task`.

  task :: (Task m) a -> m a

```

---

<div class="post-metadata">

### Author: ![GunpowderGuy](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/gunpowderguy/32/4164_2.png) [@GunpowderGuy](https://discourse.haskell.org/u/GunpowderGuy)
#### Post date: [August 10, 2025, 6:35pm UTC](https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672/2 "2025-08-10T18:35:48Z")

</div>

Cool. Does your engine support 3d rendering in some way?

---

<div class="post-metadata">

### Author: ![matthunz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/matthunz/32/4980_2.png) [@matthunz](https://discourse.haskell.org/u/matthunz)
#### Post date: [August 10, 2025, 8:14pm UTC](https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672/3 "2025-08-10T20:14:46Z")

</div>

Thanks! Not yet but I’m just about to start adding more rendering support now that the core ECS is a little more nailed down.

The engine itself is split up into multiple repos (with a WIP 2D SDL2 renderer in [`aztecs-sdl`](https://github.com/aztecs-hs/aztecs-sdl)) to be more modular, so some packages like [`aztecs-transform`](https://github.com/aztecs-hs/aztecs-transform) should be compatible with many different render backends.

I’d really like to get either GL or Vulkan going as a first implementation soon, and I’m really excited about using the `Scheduler` in Aztecs for render passes, where shaders can potentially be scheduled to run in-parallel on the GPU.

---

<div class="post-metadata">

### Author: ![GunpowderGuy](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/gunpowderguy/32/4164_2.png) [@GunpowderGuy](https://discourse.haskell.org/u/GunpowderGuy)
#### Post date: [August 10, 2025, 8:37pm UTC](https://discourse.haskell.org/t/aztecs-v0-14-0-released-a-modular-game-engine-and-ecs/12672/4 "2025-08-10T20:37:56Z")

</div>

May i suggest you consider web-gpu instead of Open GL. Both are easier to use than vulkan but web-gpu is still active , often more performant and runs on the web ( in addition to desktop )
