# Pearl

Pearl is a small framework for creating video games in the browser using [TypeScript](https://www.typescriptlang.org/). It's made to have a simple API that's easy to extend.

Unlike lots of fancier frameworks, games in Pearl are created mainly in *code*, rather than in a special editor. Rather than trying to be the level editor/sprite editor/visual scripting flowchart of your dreams, Pearl leaves the tooling used to create assets entirely up to you.

Pearl is made up of a small API for creating and rendering entities using *components*. If you're familiar with the [Component pattern](http://gameprogrammingpatterns.com/component.html), or have used an engine like Unity or Unreal Engine, you've seen this before. If not, never fear, as it's easy to pick up.

In addition to allowing you to define your own components, Pearl includes built-in components for handling positioning, collision detection, sprite rendering, and other basic utilities.

To get started with Pearl, begin with the [Tutorial](/tutorial), which provides a small boilerplate to get started with, and a simple game to make.

## Credits & Inspiration

Pearl started life as a fork of Mary Rose Cook's [Coquette](https://github.com/maryrosecook/coquette), a wonderful microframework for simple JS games. In addition to using code from Coquette, Pearl uses ideas from frameworks including Unity, Godot, and Superpowers.

Pearl relies on the [SAT.js](https://github.com/jriecken/sat-js) library for collisions, in addition to several other supporting Node modules.


# Tutorial

In this tutorial, we'll make a very simple game, in which the heroic player, as represented by a box, shall pick up a sword to slay the terrifying, massive enemy, as represented by a somewhat larger box.

To get a sense of what we're making, it may make sense to preview the completed game [here](http://pearl-tutorial.surge.sh/). You can use the arrow keys to move.

## Setting up the boilerplate

You can use anything that knows how to build TypeScript to compile games in Pearl, but Pearl recommends the *lingua franca* of build systems, [Webpack](https://webpack.js.org/), to build. Don't worry, for this tutorial you won't need to configure it yourself. To follow along at home, just clone the tutorial repo:

```
git clone git@github.com:thomasboyt/pearl-tutorial.git
cd pearl-tutorial
npm install
```

Once npm finishes installing all dependencies (that is: TypeScript, Webpack, several Webpack loaders, and Pearl itself), you can start the dev server with `npm run dev`, then navigate to `localhost:8080`. If you see a blank white screen with no console errors, you're all set up!

## Creating the game world and player object

First off, let's just create a game world that contains the player. `index.ts` already has the scaffolding for a game, so we'll fill it out further:

```typescript
// index.ts

import {
  Component,
  createPearl,
  Entity,
  Physical,
  BoxCollider,
  BoxRenderer,
} from 'pearl';

class Game extends Component<null> {
  init() {
    this.pearl.entities.add(
      new Entity({
        name: 'player',
        components: [
          new Physical({
            center: {
              x: 140,
              y: 20,
            },
          }),

          new BoxCollider({
            width: 20,
            height: 20,
          }),

          new BoxRenderer({
            fillStyle: 'cyan',
          }),
        ],
      })
    );
  }
}

createPearl({
  rootComponents: [new Game()],
  width: 300,
  height: 300,
  canvas: document.getElementById('canvas') as HTMLCanvasElement,
});
```

Start by looking at the bottom of the file: we're creating a new Pearl instance using `createPearl`. In addition to setting the canvas to use, and its width and height, we define a *root component*. This component is instantiated when the game starts, and is generally used as an "entry point" into the game. It's attached to a root entity, which can be accessed at `this.pearl.root`.

When the game component is initialized, we create a new entity, the player. The player entity is composed of a `Physical` component, giving it a position, a `BoxCollider` component, which creates a rectangular collider, and a `BoxRenderer` component, which renders the box defined by the `BoxCollider`.

{% hint style="info" %}
In addition to `BoxCollider`, Pearl also includes a `PolygonCollider` and `CircleCollider`, and corresponding `Render` components for both.
{% endhint %}

Now, when we start the game, we see a cyan box at the top of the screen. Our valiant player will venture down to face an enemy at the bottom of the screen, which we will add in a moment. However, before we do so, we need to give the player the ability to move.

## Adding player input

To give the player the ability to move, we'll create a new component, `Player`, which will be attached to the entity along with the previously-shown components. In a new file, a new component is created:

```typescript
// components/Player.ts

import { Component } from 'pearl';

export default class Player extends Component<null> {
}
```

Then, back in our root Game component, we import the component and add it to the components:

```typescript
// snip previously shown imports...
import Player from './components/Player';

class Game extends Component<null> {
  init() {
    this.pearl.entities.add(
      new Entity({
        name: 'player',
        components: [
          // snip previously shown components...
          new Player(),
        ]
      })
    );
  }
}
```

Now, we can add our input logic to `Player`.

To move the player, we need to do two things: read the input from the keyboard (that is, which arrow keys are being pressed), and then apply a velocity to the entity's `Physical` component:

```typescript
import { Component, Keys, Physical } from 'pearl';

export default class Player extends Component<null> {
  playerSpeed = 0.1;

  update(dt: number) {
    this.move(dt);
  }

  private move(dt: number) {
    let xVec = 0;
    let yVec = 0;

    if (this.pearl.inputter.isKeyDown(Keys.rightArrow)) {
      xVec = 1;
    } else if (this.pearl.inputter.isKeyDown(Keys.leftArrow)) {
      xVec = -1;
    }

    if (this.pearl.inputter.isKeyDown(Keys.downArrow)) {
      yVec = 1;
    } else if (this.pearl.inputter.isKeyDown(Keys.upArrow)) {
      yVec = -1;
    }

    this.getComponent(Physical).translate({
      x: xVec * this.playerSpeed * dt,
      y: yVec * this.playerSpeed * dt,
    });
  }
}
```

Here, we've defined a method, `move()`, which gets called on every frame through the `update()` hook. `move()` reads the currently-pressed keys via the `pearl.inputter` API, which is available in any component. The x and y velocities are just set to `0`, `1`, `-1` to indicate direction.

When we go to move the entity, we use the `Physical` component's `translate()` method, which moves the entity by a given x and y distance. To give the actual distance to move, the velocities are multiplied by `dt`, or delta-time. This is the amount of time, in ms, that have passed since the last frame. This is what allows objects to move smoothly over a variable framerate - e.g., whether your game runs at 30 frames a second or 60 frames a second, as long as you use delta-time as a factor in movement calculations, players will move the same distance over time. This is then multiplied by a `playerSpeed` factor that can be thought of as "pixels per millisecond." Our entity will move at `0.1` pixels per millisecond in the direction pushed, or `100` pixels a second.

If you reload the game, you'll see that you can move around the game world with the arrow keys. Great! Now we need something to defeat with our newfound mobility.

## Creating the enemy

We'll quickly throw in a big ol' enemy to fight. Underneath the player creation code in our `Game` component, we add another entity:

```typescript
class Game extends Component<null> {
  init() {
    // ... snip player creation code ...

    this.pearl.entities.add(
      new Entity({
        name: 'enemy',
        tags: ['enemy'],

        components: [
          new Physical({
            center: {
              x: 140,
              y: 260,
            },
          }),

          new BoxCollider({
            width: 40,
            height: 40,
          }),

          new BoxRenderer({
            fillStyle: 'red',
          }),
        ],
      })
    );
  }
}
```

This code should look familar, with only a few values changed from the player creation. One notable change is the addition of `tags` - these are strings that can be used to identify *types of entities*. In a traditional OOP game, you might use `instanceof` to determine what kind of object you're looking at - say, `entity instanceof Enemy` - but since here, all entities are merely instances of `Entity`, we use `tags` to distinguish them. You'll see this in use in the next section.

If you refresh, you'll see a big red box at the bottom of the screen, our new enemy. Currently, we can run right up to it - or through it - and laugh at it, since it currently has no way to fight back. Let's make it so that if you run into the enemy without a weapon, the enemy will, as expected, kill you.

## Adding collision detection

While Pearl includes several `Collider` components for various shapes, it doesn't automatically *do* anything with them, unlike some fancier frameworks. This is partially so that you have control over handling and resolving collisions - since the way Pac-Man handles collisions is a heck of a lot different than how Mario would - but is also because I haven't come up with a good, magical collision API yet. It might get there eventually!

For now, we'll add collision detection inside the `Player` component. We need to check to see if the player has collided with the enemy, and if so, set the player to dead. Back in our player component, we add a new field to the player, and a new placeholder function for checking collisions:

```typescript
export default class Player extends Component<null> {
  playerSpeed = 0.1;
  isAlive = true;

  update(dt: number) {
    if (!this.isAlive) {
      return;
    }

    this.move(dt);
    this.checkCollisions();
  }

  private move(dt: number) { /* ... */ }

  private checkCollisions() {
    // TODO
  }
}
```

Now, we have a flag that determines whether the player is alive to dead. If they're dead, we'll early return from `update()` to prevent the player from moving, and to skip unnecessary collision detection.

Now, inside `checkCollisions()`, we just want to see if the player has collided with the enemy, and then set `isAlive` to false if they have:

```typescript
class Player extends Component<null> {
  /* ... */

  private checkCollisions() {
    const enemy = this.pearl.entities.all('enemy')[0];

    if (
      enemy
        .getComponent(BoxCollider)
        .isColliding(this.getComponent(BoxCollider))
    ) {
      this.isAlive = false;
    }
  }
}
```

A couple new APIs show up here. First off, we need to find the enemy entity. There are several ways for components to reference other entities, depending on your needs. For example, a component that is always associated with another entity could just have references set directly on the component. So here, we could have chosen to add `enemy` as a field on `Player`, and then set up the reference when creating our entities:

```typescript
class Game extends Component<null> {
  init() {
    const player = this.pearl.entities.add(new Entity(/* ... */));
    const enemy = this.pearl.entities.add(new Entity(/* ... */));
    player.enemy = enemy;
  }
}
```

However, what if we later wanted to add multiple enemies? Managing an array of enemies would be annoying, especially since we'd have to ensure the enemy is removed from the array when destroyed. In addition, if we later made it so enemies could spawn over time, or from other events in the game world, it might be annoying to look up the player every time.

In general, looking up entities from the game world is Fast Enough(tm) for most games. If you profile your game and find `entities.all()` becoming a bottleneck, you might want to add some level of caching - especially if you need to do some complex filtering beyond just looking at tags, such as "only get entities in a certain area of the world" - but using `entities.all()` is the easiest way to get started.

So, with entity lookup taken care of, we then use the `isColliding()` method of `BoxCollider`, which can check against another `BoxCollider`, to see if the entities are colliding. If they are, we just set the player to dead. Now, if you refresh the game, you should see the player rendered helplessly immobile after touching the enemy, presumedly because the enemy has eaten or stabbed or done something equally horrendous.

So now the player dies when they poke the evil enemy, and can no longer move or win the game. To emphasize this point, we'll add a *game over* display.

## Creating a game over display

A simple UI will serve as a good introduction to canvas rendering in Pearl. Unlike `BoxRenderer`, Pearl currently doesn't have a drop-in component for displaying text content. That's okay, though, as it's very easy to add.

Any component can have a `render()` function on it. Traditionally, you'd probably make a new UI component that would probably live in a UI entity, or maybe be a sibling component of your main `Game` component. For simplicity's sake, we'll just add a `render()` method to our root `Game` component:

```typescript
class Game extends Component<null> {
  init() { /* ... */ }

  render(ctx: CanvasRenderingContext2D) {
  }
}
```

Canvas rendering is outside of the scope of this tutorial, but it's a simple, if maybe overly-naive, API to work with. In Pearl, you can think of rendering as somewhat *stateless* - between every frame, the canvas is completely thrown away, and every component's render function is redrawn.

Now, canvas operations can be kind of expensive to do 60 times a second, but there are methods for caching/memoizing canvas rendering built into Pearl. For now, we'll just do the naive thing of rendering text on every frame.

To determine whether to render our game over text, we need to check to see if the player's still alive. To do so, we'll store the player entity as a reference on the class, and check it every frame.

```typescript
class Game extends Component<null> {
  playerEntity: Entity;

  init() {
    this.playerEntity = this.pearl.entities.add(new Entity(/* ... */));

    /* ... */
  }

  render(ctx: CanvasRenderingContext2D) {
    if (!this.playerEntity.getComponent(Player).isAlive) {
      ctx.textAlign = 'center';
      ctx.font = '16px monospace';
      ctx.fillStyle = 'black';
      ctx.fillText('game over :(', 150, 150);
    }
  }
}
```

Now, if you run the game, you should see a nice game over message appear when you touch the enemy. Now the fun part: let's let the player win!

## Creating a sword

We've seen how to render boxes using `BoxRenderer`, and text using canvas drawing instructions. Now, for our sword, let's add a proper sword sprite, drawn by `SpriteRenderer`. The `SpriteRenderer` component simply renders a single sprite, while the `AnimationManager` can be used to add timed animations and multiple animation states to a component.

To load our image, in `assets/sword.png`, we'll use Webpack's `url-loader` (already pre-configured) and Pearl's built-in assets loader. To start, we add the assets we want to preload to a new `assets` field on `createGame()`:

```typescript
import { /* ... */, ImageAsset } from 'pearl';

createPearl({
  rootComponents: [new Game()],
  width: 300,
  height: 300,
  canvas: document.getElementById('canvas') as HTMLCanvasElement,
  assets: {
    swordImage: new ImageAsset(require('../assets/sword.png')),
  }
});
```

This will allow us to access the sword image (as an `HTMLImageElement`) using the `pearl.assets` API:

```typescript
// returns HTMLImageElement
this.pearl.assets.get(ImageAsset,  'swordImage');
```

{% hint style="info" %}
Note that the first argument is used to typecast the asset as well as to check its type *at runtime*. There is no static type safety on asset lookup!
{% endhint %}

We'll use this image to create a `Sprite`, which can be passed to a `SpriteRenderer` for rendering.

{% hint style="info" %}
We could also use an image to create a `SpriteSheet_` which can handle rendering multiple sprites from the same sheet.
{% endhint %}

Let's finally create the sword entity:

```typescript
class Game extends Component<null> {
  init() {
    /* ... */

    const swordImage = this.pearl.assets.get(ImageAsset,  'swordImage');

    const swordSprite = new Sprite(
      // sprite image
      swordImage,
      // offset x
      0,
      // offset y
      0,
      // sprite width
      swordImage.width,
      // sprite height
      swordImage.height
    );

    this.pearl.entities.add(
      new Entity({
        name: 'sword',
        tags: ['sword'],
        components: [
          new Physical({
            center: {
              x: 150,
              y: 150,
            },
          }),

          new BoxCollider({
            width: swordSprite.width,
            height: swordSprite.height,
          }),

          new SpriteRenderer({
            sprite: swordSprite,
          }),
        ],
      })
    );
  }
}
```

Now, if you refresh the game, you'll see our nice, definitely not stolen from a famous Nintendo game sword sprite, waiting to be picked up. Back in `Player`, we can add logic to check collision with the sword, and set a flag to indicate we picked it up:

```typescript
export default class Player extends Component<null> {
  /* ... */

  hasSword = false;

  private checkCollisions() {
    /* ... */

    if (!this.hasSword) {
      const sword = this.pearl.entities.all('sword')[0];

      if (
        sword
          .getComponent(BoxCollider)
          .isColliding(this.getComponent(BoxCollider))
      ) {
        this.hasSword = true;
      }
    }
  }
}
```

Great, except the sword's still left behind in the ground!

In a real game, the `sword` entity would likely have just represented a sword *pickup*, and once you've collected it, the entity would be removed from the world. However, since this is a tutorial and not a real game, this is a good time to show off one last feature of Pearl. We want to render the player *holding* the sword, that is, the sword sprite moving along with the player. So let's add the sword as a *child entity* of the player, and then set its position relative to the player's position:

```typescript
export default class Player extends Component<null> {
  /* ... */

  private checkCollisions() {
    /* ... */

    if (!this.hasSword) {
      const sword = this.pearl.entities.all('sword')[0];

      if (
        sword
          .getComponent(BoxCollider)
          .isColliding(this.getComponent(BoxCollider))
      ) {
        this.hasSword = true;

        this.entity.appendChild(sword);
        sword.getComponent(Physical).localCenter = {
          x: -5,
          y: 15,
        };
      }
    }
  }
}
```

Now, when we pick up the sword, we'll see it move along with us!

{% hint style="warning" %}
**TODO**: Eventually, I'd like child objects to render with their *angle* relative to their parent's, not just their *position*. Once this is done, this would be a good time show off the sword also *rotating* when the player turns (though I'd also have to add some logic to set the player's angle... maybe this should all be done once player is also rendered by a sprite).
{% endhint %}

## Slaying the enemy

There are only two pieces remaining now. When the player collides with the enemy, the enemy should be killed - that is, removed from the game world:

```typescript
export default class Player extends Component<null> {
  /* ... */

  private checkCollisions() {
    const enemy = this.pearl.entities.all('enemy')[0];

    if (
      // Note that sense the enemy can now be destroyed, we've added a check to
      // make sure it's present before checking collision against it, or else
      // it would error out!
      enemy &&
      enemy
        .getComponent(BoxCollider)
        .isColliding(this.getComponent(BoxCollider))
    ) {
      if (this.hasSword) {
        this.pearl.entities.destroy(enemy);
      } else {
        this.isAlive = false;
      }
    }

    /* ... */
  }
}
```

And the UI should be updated to show a nice "you win!" message:

```typescript
class Game extends Component<null> {
  init() {
    /* ... */

  render(ctx: CanvasRenderingContext2D) {
    ctx.textAlign = 'center';
    ctx.font = '16px monospace';
    ctx.fillStyle = 'black';

    if (!this.playerEntity.getComponent(Player).isAlive) {
      ctx.fillText('game over :(', 150, 150);
    }

    if (this.pearl.entities.all('enemy').length === 0) {
      ctx.fillText('you win!', 150, 150);
    }
  }
}
```

All done!

## Exercises for the reader

* Can you make it so that the *sword*, not the player, has to collide with the enemy to defeat it? This should require creating a new component for either the sword or the enemy.
* Experiment with adding sprites for the player and enemy.
* The repo includes a second asset, `hit.wav`, meant to be played when the player hits the enemy with their sword. Use `AudioAsset` and the `pearl.audio` API to play it at the correct time.


# Guides


# Creating Gameplay with Components

{% hint style="warning" %}
This documentation hasn't been finished yet! Sorry about that.
{% endhint %}

Pearl is a framework built around the [Component pattern](http://gameprogrammingpatterns.com/component.html). Lots of big fancy game frameworks, like Unity and Unreal Engine, use this pattern, so you might find it familiar. If not, don't fret!

If you're familiar with OOP, you might best think of components as *really fancy mixins/traits*. In a component system, you have "entities" (in our case, actual entities in the game world), which are objects that only hold a few things:

* Metadata that makes it possible to identify what *kind* of entity this is. In Pearl, this is a *name* that gets set on an object, plus optional tags to further identify the entity. For example, if you were building a Pac-Man clone, you might create four ghost objects with their own name (e.g. `Inky`, `Blinky`, `Pinky`, and `Clyde`), but all sharing a `ghost` tag.
* A list of components that make up the entity. For a Pac-Man ghost, each ghost might have a `SpriteRenderer` to determine what to render and a `Physical` component determining its place in the game world. Since each ghost has different AI, you would then add different components to each ghost for their AI - e.g. `InkyAI`, `BlinkyAI` - that might all subclass a base `GhostAI` component.

Components can easily reference sibling components on the same component - for example, the `GhostAI` component could look up the `Physical` component to determine where it currently is, and make decisions based on the entity's current location.


# Moving & Colliding

{% hint style="warning" %}
This documentation hasn't been finished yet! Sorry about that.
{% endhint %}

## Collisions Overview

Collisions in Pearl are handled with *Collider* components.

Pearl ships with three core shape colliders - `PolygonCollider`, `CircleCollider`, and `BoxCollider`. These colliders each have `CollisionShape` objects that define their shapes.

* show example of importing and attaching a collider to an entity
* show isColliding/getCollision API

### Collision Details

Under the hood, Pearl currently uses [SAT.js](https://github.com/jriecken/sat-js) for collisions. SAT.js supports collisions between convex polygons (including simple line segments) and circles.

In the future, a different library may be used to allow more types of collision shapes. For now, this should be good enough for most games.

The `SAT.Polygon` and `SAT.Circle` classes are wrapped by `PolygonShape` and `CircleShape` classes, respectively. These wrapper classes abstract over the SAT API (so if the underlying library changes, the Pearl API won't have to change). In addition, when Pearl has support for a RigidBody component and a physics engine, these shape classes will be used to generate physics objects.

### Custom Colliders

* maybe leave this section blank for a long time

## Kinematic movement with KinematicBody

Pearl includes a KinematicBody component patterned after Godot's KinematicBody2D. A *KinematicBody* is a component that handles movement and collision resolution in one step.

This is different from how collisions are handled in most physics engines, or in other frameworks that you may have used in the past. In those, you might be used to the pattern being:

* On update(), move all objects in the world based on input/forces/etc
* After update(), check to see if any objects have collided
* If they have, resolve each collision in turn, and trigger collision handlers

This pattern works well for real physics engines, but usually not so well for simple game movement. This kind of collision often leads to subtle and tricky bugs.

With KinematicBody, things are much simpler:

* In update(), *attempt* to move an object based on input/forces/etc
* Check to see if the object has collided with anything. If it has, move the object back to its previous location, and trigger collision handlers

KinematicBody has two methods, `moveAndCollide(vec2)` and `moveAndSlide(vec2)`. These methods are used to move the entity

* collide vs slide

  \-


# Using Assets

*Assets* represent files that get loaded before the game starts. These can include audio, images, and custom assets such as level data.

Using Pearl's asset system saves you from writing custom code to load assets, and provides a simple UI for accessing your assets within your game's components.

Pearl's asset system does *not* handle the problem of bundling assets with your game, but is very easy to use with a bundler like Webpack, as you'll see below.

{% hint style="info" %}
**TODO**: Explain Webpack `require()` a lil bit
{% endhint %}

## Preloading Assets

Pearl includes a special preloader for loading assets before starting the game.

```typescript
import {createPearl, ImageAsset} from 'pearl';

createPearl({
  assets: {
    swordImage: new ImageAsset(require('../sprites/sword.png')),
  },
  // ....
});
```

Now, within a component, we can access and use `swordImage`. For example, here we create a `Sprite` with it:

```typescript
const swordImage = this.pearl.assets.get(ImageAsset, 'swordImage');

const swordSprite = new Sprite(
  swordImage,
  0,
  0,
  swordImage.width,
  swordImage.height
);
```

## Custom Assets

You can define custom assets to load by extending the `Asset` class. For example, to load level data from an external file as a string, we could define an asset:

```typescript
import {AssetBase} from 'pearl';

class LevelAsset extends AssetBase<string> {
  async load(path: string): Promise<string> {
    const resp = await fetch(path);
    const level = await resp.body();
    return level;
  }
}

createPearl({
  assets: {
    levelOne: new LevelAsset(require('../levels/levelOne.txt')),
  }
})

class LevelOne extends Component<null> {
  init() {
    const levelData = this.pearl.assets.get(LevelAsset, 'levelOne');
  }
}
```


# Sprites & Animations

{% hint style="warning" %}
This documentation hasn't been written yet! Sorry about that. For information about sprites & animations, you may want to take a peek at the included `SpriteRenderer` and `AnimationManager` components, as well as the [Using Assets](/guides/using-assets) guide.
{% endhint %}


# Writing Components


# Coroutines

If you have a stateful process that lasts across multiple frames - for example, a timed animation cycle, or an entity that waits a certain amount of time before performing an action - you may want to try using coroutines.

Coroutines in Pearl are based off ES6 generators. If you've used [async/await](https://ponyfoo.com/articles/understanding-javascript-async-await) syntax, you'll be right at home. A *coroutine* is a generator function that yields a promise.

Here's an example of a component with a simple coroutine that changes a displayed message after 5 seconds:

```typescript
class TimedMessage extends Pearl.Component<null> {
  message: string = 'Waiting...';

  init() {
    this.runCoroutine(this.messageChanger);
  }

  *messageChanger() {
    yield this.pearl.async.waitMs(5000);
    this.message = 'Hello coroutines!';
  }

  render(ctx: CanvasRenderingContext2D) {
    ctx.fillText(this.message, 100, 100);
  }
}
```

Unlike traditional async/await methods or simple promise chaining, coroutine execution is tied into the game's run loop.

Coroutines started using `runCoroutine` inside a component are stopped when that component's Entity is destroyed. Internally, this works by simply discarding the coroutine. However, any asynchronous operations spawned by the coroutine will still finish, as JavaScript promises currently can't be canceled. Take the following example:

```typescript
import {getHttp} from 'some-http-library';

class LoadMessage extends Pearl.Component<null> {
  message: string = 'Loading...';

  init() {
    this.runCoroutine(this.getAsync);
    this.runCoroutine(this.cancelAsync);
  }

  *getAsync() {
    // assume this takes 100 ms to finish:
    const msg = yield getHttp('/message');
    this.message = msg;
  }

  *cancelAsync() {
    yield this.pearl.async.waitMs(50);
    this.pearl.entities.destroy(this.entity);
  }

  render(ctx: CanvasRenderingContext2D) {
    ctx.fillText(this.message, 100, 100);
  }
}
```

Here, the Entity is destroyed before `getHttp` returns its response and sets the message. When this happens, the `getAsync` coroutine is discarded and never resumed. However, `getHttp()` *itself isn't canceled* and will complete execution, with its result simply being discarded.


# Entity & Component Lifecycle

## Component Hooks Recap

To remind, the basic lifecycle hooks on every component are:

```typescript
class MyComponent extends Component<null> {
  create() {
    // called immediately when the entity is added to the game world
  }

  init() {
    // called before the first update() tick, which is the frame _after_
    // the entity is added to the game world
  }

  update(dt: number) {
    // called on each frame
  }

  onDestroy() {
    // called immediately when the entity is removed from the game world
  }
}
```

The distinction between `create` and `init` specifically can be confusing, so it may be helpful to understand how the entity lifecycle works.

## Lifecycle Overview

Creating an entity constructs instances of your components, but does nothing else:

```typescript
const entity = new Entity(components: [new MyComponent()])
```

At this point, no hooks on components are called, and the object hasn't been added to the game world.

When an entity is added:

```typescript
this.pearl.entities.add(entity);
```

The entity is moved to the `created` state, and the `create()` hook on components is called. The create hook *can* access sibling components at this point, but it depends on the order they were added in the components array.

In general, you should defer anything that depends on other components or entities to the `init()` hook.

When an object is added, it is *initialized on the next frame*. This may change, but currently, it's done to make it easier to reason about adding entities. On the next frame, before any component's `update()` hook is called, all added entities are initialized, meaning their `init()` is called and all components are set up.

One nice guarantee from this is that if you add two entities on the same frame, you can safely reference one from the other in the first `update()` tick. Of course, the flip side of this is that it's not necessarily so safe to reference each other in `init()`.

## Impact of Lifecycles on Component Access

In general:

* Inside a component's `create()`, you should not reference sibling components or components on other entities created in the same frame, as they may not have been created yet.
* Inside a component's `init()`, you should not expect sibling components, or components on other entities created in the same frame, to have had their `init()` methods run yet.

Of course, there are potential workarounds for this behavior. For example, you could defer initialization of some dependent property on a component until its first `update()`:

```typescript
class AComponent extends Component<null> {
  importantString: string;

  init() {
    this.importantString = 'important';
  }
}

class BComponent extends Component<null> {
  importantStringCopy: string;
  initialized = false;

  init() {
    // THIS MAY NOT WORK if BComponent is initialized first!
    this.importantStringCopy = this.getComponent(AComponent).importantString;
  }

  update() {
    if (!this.initialized) {
      // at this point, BComponent is guaranteed to have been initialized
      this.importantStringCopy = this.getComponent(AComponent).importantString;
      this.initialized = true;
    }
  }
}
```

This should *only* be done as a last resort - obviously, in this case, there would be several other ways to handle this, such as setting the string in `create()`, or simply not copying the string and instead accessing it through `AComponent` every time.


# Networking


# Introduction

{% hint style="warning" %}
This documentation hasn't been written yet! Sorry about that.
{% endhint %}


# Example Games

## Demos

* [Multiplayer Pong](https://github.com/thomasboyt/pong)
* [Platformer](https://github.com/thomasboyt/pearl-platformer)
* [Mini Dungeon](https://github.com/thomasboyt/mini-dungeon)

## Games

* [Sledgehammer](https://github.com/thomasboyt/sledgehammer)


# Roadmap

## Planned for 0.1.0

* Simplify component creation using one of the strategies detailed below (see below)
* Tiled platformer example! Probably will port over Blorp, probably with shinier new sprites from a free asset pack.

### Beyond that, probably

* More collisions stuff
* First-class events
* DOM rendering thing/React integration?

## Preloader/Preloader Hooks

It'd be fun and cute to ship a default preloader, but most games will probably not have enough assets to ever see it anyways, so might be more important to document how you could make your own, and actually provide the hooks needed.

## Collision System

Now that Pearl has a more fleshed-out set of Colliders and a KinematicBody, more stuff can be added to the collision system.

Some things I'd like:

* how do non-KinematicBody things collide
  * is it time for RigidBody to happen
    * physics are hard and scary :(
* collisionEnter/collisionContinue/collisionExit events
  * on collide: set colliding to true and collisionEnter fired (along with collisionContinue?)
  * continue firing collisionContinue every frame
  * on exit: collisionExit event
    * how is exit triggered??
    * this is actually really tricky w/ current KinematicBody implementation :I
  * if entity destroyed, fire collisionExit
  * unity handles this by literally just not supporting these events for two kinematic bodies colliding
    * instead: <https://docs.unity3d.com/ScriptReference/CharacterController.OnControllerColliderHit.html>
    * also see: <https://docs.unity3d.com/Manual/class-Rigidbody2D.html>
    * I think Godot maybe also does this? hmmm

### Other questions

* Could entities be grouped into a single top-level "scene" component?
  * Scene component would get all children and create collision pair tests between them
* Is it fine for collisions to exist as just another system in a component's update hook, or should it have special component hooks and exist in a special system?
  * Unity does the latter - why?
    * Superpowers *does not*, fwiw, and there may be others that don't.
  * Collisions generally need to be resolved *before* updates happen (see Coquette)
    * Pre-update hook?
* Long-term considerations
  * Collision layers? Would help avoid triggering/calculating unnecessary collisions

## Networking Thoughts

There's \~zero chance networked multiplayer will ever be a core component in Pearl, but it's good to keep in mind, especially as Sledgehammer is theoretically ongoing.

For example: `Physical.vel` is being removed in favor of manually moving entities and, eventually, maybe using physics, or at least some sort of `MovingBody` that you can apply a velocity to. However, `Physical.vel` had the nice property of allowing (sorta) "predictive" movement, rather than purely relying on the incoming position. Adding a real physics engine might help with this, but that's obviously fraught with its own peril, as Manygolf showed.

Any automated collision system should keep this in mind, too. It'd be annoying to have collisions duplicated on server and client, requiring a `if (!isHost) {return}` check, but it might make sense.

## Simpler Entity Creation

Entity creation is currently a kind of awkward process, depending on what you want to do. Specifically:

* The *settings* passed through to `create()` and `init()` create an awkward second set of preconfigured properties
* Overriding settings created by e.g. a factory or "prefab"-like construct requires the original component to have special logic:

```typescript
type Settings = {sprite?: Sprite};

class MyComponent<Settings> {
  sprite?: Sprite;

  init(settings: Settings) {
    // check to see if this has already had a sprite set on it
    if (settings.sprite && !this.sprite) {
      this.sprite = settings.sprite;
    }
  }
}
```

* On the other hand, strategies like the above could leave a component in an invalid state - e.g. what if MyComponent can't function without a set `sprite`?
* It's also hard to subclass components when base class needs settings - have to copy logic to apply settings, or create helper method.

### Magic Components

TypeScript (as of 2.1) now makes it easy to create a type-safe API similar to the original Coquette entity construction API:

```typescript
export class MagicSettingsComponent<T> extends Component<any> {
  constructor(settings: Partial<T> = {}) {
    super();
    for (let key of Object.keys(settings)) {
      this[key] = settings[key];
    }
  }
}

interface ISpriteRendererProperties {
  spritePath: string;
  scaleX: string;
}

class SpriteRenderer extends MagicSettingsComponent<ISpriteRendererProperties>
  implements ISpriteRenderer {
  spritePath?: string;

  create() {
    console.log(this.spritePath);
  }

  renderSprite() {
    // ...
  }
}

new SpriteRenderer({ spritePath: 'foo.png' });
```

This would make reasoning about setting and using properties before and during initialization much easier.

There are some potential downsides:

a) Settings that are only used during initialization, and then discarded, would still have to defined as properties on the component.

b) TypeScript's `keyof` includes methods/getters/setters, requiring an interface to be defined without these. This is annoying bit of boilerplate :(

c) The component wouldn't have type-safe *required* settings:

```typescript
class MyComponent extends Component {
  a: string;

  create() {
    console.log(this.a.toUpperCase());
  }
}

// errors out because a is not passed
this.pearl.entities.add(new Entity({
  components: [new MyComponent()],
});
```

However, this may not be a big deal, as "required" settings are in opposition to being able to update settings after construction anyways. Maybe some kind of helper could be added to throw out automagically if required settings are missing at `create()` (or `init()`) time?

d) Setters that depend on the parent object may error out with this.

An experimental implementation of this exists at the `ideas/magic-components` branch.

### Alternatives To Magic Components

* Add merge-properties helper, which additionally ensures that properties passed in settings don't override properties that have been set
* Validate *required* properties at construction time, with type guarantees - non-optional settings
  * What if the user really wants to defer setting properties on the object for some reason?
    * User should just suck it up and e.g. pass partially-filled out setting through control flow

## Devtools Inspector

This is its infancy at [Pearl Inspect](https://github.com/thomasboyt/pearl-inspect).

The goal of the Pearl Inspector will be to add a simple display of entities in the world (shown in the parent-child hierarchy) and their components. For more information on the roadmap and status of this project, see [its TODO file](https://github.com/thomasboyt/pearl-inspect/blob/master/TODO.md).

## Canvas scaling utilities

It'd be great to offer canvas scaling utilities, like scaling-on-resize while maintaining the original aspect ratio (using `ctx.scale`, that is, not CSS that causes blurry images). It'd also be cool to have a full-screen toggle.

## Design Questions, etc.

This is an unsorted list of things I've been thinking about.

* How are objects created/destroyed?
  * Figure out better API for `entities.add`/`entities.destroy`
  * Maybe `this.createObject({...})` / `this.destroyObject({...})`
* Add better utilities for managing destroyed objects and components
  * Unity's able to automatically null references to destroyed objects. I don't think there's any magic I can do for that in TS/JS, unfortunately.
  * Make `destroyedObject.getComponent()` give an explicit error
* How are "game controller" level components handled?
  * Singleton example in Unity: <https://unity3d.com/learn/tutorials/projects/2d-roguelike-tutorial/writing-game-manager>
  * Useful SA discussion on Unity singletons starts here: <http://forums.somethingawful.com/showthread.php?threadid=2692947&userid=0&perpage=40&pagenumber=444#post462272736>
* Figure out additional hooks for components
  * For example, collision needs to be broken up into "detection" and "resolution" phases, so that e.g. an enemy that turns around when it hits a block can be coded as two separate components
  * `FixedUpdate`-like hook? Does this even make sense in a single-threaded application? Seems suuuper difficult to time and schedule correctly.


