mischief-ecs
Safe HaskellNone
LanguageGHC2024

Mischief.ECS.Tutorial.App

Description

This module contains a more in-depth look into the Mischief App and Plugins.

It isn't as technically interesting as the other chapters of the tutorial, focusing more on organization and high-level logic.

Previous Chapter: Coding a Dungeon Game

Next Chapter: Components

Main Page

Synopsis

    Learn You an ECS for Great Mischief! - 3. App and Plugins

    The App is a thin wrapper around the World that works as an interface for plugging in various behavior and features in modular fashion, via Plugins.

    A Mischief game / app usually starts by creating an app and adding one or more plugins to it.

    main :: IO ()
    main = do
      app <- newApp
      addPlugin @MainPlugin app
      runApp app
    
    data MainPlugin
    
    instance Plugin MainPlugin where
      init = info "Hello!"
    

    A Plugin instance has two optional functions:

    1. An initialization system that will be ran at the very beginning of the app.

    This system is usually used to schedule other systems, or to initialize data, such as resources and observers.

    init :: System ()
    init = do
      insertRes (Health 0)
      void $ spawn (Observer onDamage)
    
      systems movePlayer
        & schedule Update
    
    1. A list of plugins this plugin depends on.

    Any plugin can be made into a dependency using the dep function:

    deps = [dep @PlayerPlugin, dep @EnemyPlugin, dep @PhysicsPlugin]
    

    It is guaranteed that the init systems of a plugin's dependencies will run before its own init.

    Modular Features

    Mischief is intended to let you cleanly separate and organize your logic.

    For instance, you may have a PhysicsPlugin that adds physics to your game, a RenderPlugin which renders objects, a LevelPlugin that spawns your levels.

    instance Plugin MainPlugin where
      deps _ = [dep @PhysicsPlugin, dep @RenderPlugin, dep @LevelPlugin]
    

    Ideally, each of these plugins would add their own independent features. So, if you were to remove physicsPlugin, your entities simply wouldn't move and collide anymore, but the rest of the app would work just fine.

    Note that, internally, PhsyicsPlugin could also be subdivided into its own plugins with separate roles:

    data PhysicsPlugin
    
    instance Plugin PhysicsPlugin where
      deps = [dep @CollisionPlugin, dep @MovePlugin]
    

    This also lets the various packages of Mischief be modular, and makes it easy for third party library developers to create plugins that you just plug into your app with ease!

    Next chapter: Components