apecs is an Entity Component System (ECS) library inspired by specs and Entitas. ECS presents a data-driven approach to game development, that elegantly tackles many of the unique issues of game programming.
apecs aims to be
- Fast - Performance is competitive with Rust ECS libraries (see benchmark results below).
- Concise - Game logic is expressed using a small number of powerful combinators.
- Safe - The
cmap
/cfold
-DSL completely hides the dangers of the low-level API. - Extensible - At its heart apecs is just a data manipulation DSL that can be implemented with any number of backends. As a monad transformer it easily integrates into larger applications.
- Cool
- documentation on hackage
- tutorial and other examples
- paper (prepublication) (see #19)
- apecs-physics - 2D physics using the Chipmunk2D engine
- apecs-gloss - Simple frontend for gloss-based rendering
- apecs-stm - STM-based stores for easy concurrency
- An Introduction to Developing Games in Haskell with Apecs by Ashley Smith
Package | Hackage | Stack LTS | Stack Nightly |
---|---|---|---|
apecs | |||
apecs-physics | |||
apecs-gloss | |||
apecs-stm | - | - | |
examples | - | - | - |
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Apecs
import Linear (V2 (..))
newtype Position = Position (V2 Double) deriving Show
newtype Velocity = Velocity (V2 Double) deriving Show
data Flying = Flying
makeWorldAndComponents "World" [''Position, ''Velocity, ''Flying]
game :: System World ()
game = do
newEntity (Position 0, Velocity 1)
newEntity (Position 2, Velocity 1)
newEntity (Position 1, Velocity 2, Flying)
-- 1. Add velocity to position
-- 2. Apply gravity to non-flying entities
-- 3. Print a list of entities and their positions
cmap $ \(Position p, Velocity v) -> Position (v+p)
cmap $ \(Velocity v, _ :: Not Flying) -> Velocity (v - V2 0 1)
cmapM_ $ \(Position p, Entity e) -> liftIO . print $ (e, p)
main :: IO ()
main = initWorld >>= runSystem game