---
title: Systems
slug: /systems
section: Entity Component System
---

```twoslash include ex
/// <reference path="../src/engine/excalibur.d.ts" />
declare const game: ex.Engine;
```

Core behavior in Excalibur is implemented by Systems. Systems process all entities that have matching component types and perform some action.

Examples of systems are the [[GraphicsSystem]], [[MotionSystem]], [[CollisionSystem]], and [[DebugSystem]]

## System

Each Excalibur [[System]] loops through all entities in `System.priority` order. There are a list of built in system priorities [[SystemPriority]] that can be used to assign priority. Lower number means higher priority which runs first.

```typescript
/**
 * Higher priorities run earlier than others in the system update
 */
export const SystemPriority = {
  Highest: -Infinity,
  Higher: -5,
  Average: 0,
  Lower: 5,
  Lowest: Infinity
} as const;
```

## System Types

There are two system types [[SystemType.Update|update]] and [[SystemType.Draw|draw]].

[[SystemType.Update]] type systems all run before [[SystemType.Draw]] type systems.

## Lifecycle

Systems execute in this order

1. one-time `constructor(world: World)`
   * Initialize your query here
2. one-time `initialize(world: World, scene: Scene)`
   * Initialize anything that relies on the scene/engine here
3. every frame `preupdate(scene: Scene, elapsedMs: number)`
   * Run setup code for the update
4. every frame `update(delta: number)`
   * Update all your entities here
5. every frame `postupdate(scene: Scene, elapsedMs: number)`
   * Run cleanup code for the update

## Built in Systems

Excalibur has a few built in systems that are used to enable the default behavior. These `Systems` are defined at Scene constructor time.

### [[MotionSystem]]

The motion system implements motion on entities, like Actors moving with velocity and acceleration.

This system makes use of the [[TransformComponent]] and [[MotionComponent]] to implement motion.

If a [[BodyComponent]] is present that will be used to apply sleep or global acceleration [[Physics.acc]] to all [[CollisionType.Active]] bodies.

### [[CollisionSystem]]

The collision system uses the [[TransformComponent]], [[MotionComponent]], and [[ColliderComponent]] to implement collision detection and resolution behavior.

### [[GraphicsSystem]]

The Excalibur GraphicsSystem takes any entity with a [[TransformComponent]] and a [[GraphicsComponent]] and draws it to the screen using the [[ExcaliburGraphicsContext]].

### [[DebugSystem]]

The debug system is slightly odd, it operates on all entities with a [[TransformComponent]] to display debug information to the screen when [[Engine.showDebug]] is enabled.

Read more about the debug options here [[Debug]]

## Implementing your own Components & Systems

To build your own component, extend the Excalibur [[Component]] abstract class and pick a unique type name (duplicate type names will cause problems).

For custom component types it is recommended you prefix your types, like `type = 'myCustomPrefixTransform'`

In this example, we create a "search" type component, that searches for a target position. Notice how this component implementation is mostly data.

```typescript
class SearchComponent extends ex.Component {
    constructor(public target: ex.Vector) {
        super();
    }
}

class SearchSystem extends ex.System {

  query: Query<typeof SearchComponent>;
  constructor(world: World) {
    this.query = world.query([TransformComponent, SearchComponent]);
  }

  // Lower numbers mean higher priority
  // 99 is low priority
  public priority = 99;

  // Run this system in the "update" phase
  public systemType = ex.SystemType.Update

  private _searchSpeed = 100 // pixels/sec

  public update(delta: number) {
    for (let entity of this.query.entities) {
        const target = entity.get(SearchComponent).target;
        const transform = entity.get(ex.TransformComponent);

        const direction = target.sub(transform.pos);
        const motion = direction.normalize().scale(this._searchSpeed);

        // Moves these entities towards the target at 10 pixels per second
        transform.pos = transform.pos.add(motion.scale(delta / 1000))
    }
  }
}

const scene = new ex.Scene();
scene.world.add(new SearchSystem());

// Actors come with batteries included built in features
const actor = new ex.Actor({
    pos: ex.vec(100, 100),
    width: 30,
    height: 30,
    color: ex.Color.Red
});
actor.addComponent(new SearchComponent(ex.vec(600, 400)));
```

<IFrameEmbed src="https://excaliburjs.com/excalibur-snippets/ecs/" />

Any entity that has the new component attached will be processed by the new system once added to the world!
