Collaborator User Manual - Strange4/RenaEngine GitHub Wiki

User manual for collaborators of Rena Engine (Open Source)

PixiJS

Setup

Enter the following commands in the terminal => To create a JSON file (if there is none):

npm init -y 
npm install pixi.js

The project will have the following structure:

The renderable.ts file will contain interfaces that are like contracts between the game server and the viewer. The renderable.ts file should contain the following:

export enum RenderableType {
  MAP = "MAP",
  OBJECT = "OBJECT",
  DECORATION = "DECORATION",
}

export interface Renderable {
  id: string;
  position: [number, number];
  assetPath: string;
  size: [number, number];
  type: RenderableType;
  layer: number;
}

export interface RenderableChange {
  index: number;
  changes: Renderable[];
}


export interface ViewerSetup {
 // TBD
}

The PixiCanvas.tsx file serves as a mount fro PixiJS. We want to have a Canvas element that will be the game rendering screen.

The following are important imports:

import { useEffect, useRef } from "react";
import * as PIXI from "pixi.js"; 

And it must export the PixiCanvas function:

export default function PixiCanvas({ width, height }: PixiCanvasProps) { 
…
}

Then, the LiveViewer.tsx page imports the Canvas in order to render the game in the latter. PixiJS works well alongside React, meaning that anything outside the Canvas element is React’s(or Next.js) domain of control. Feel free to personalize the page.

Application and Sprites

Application

Using PixiJS's APPLICATION class, it is possible to set up rendering in PixiJS. It is where visual objects will be added.

The application is created by first constructing an instance, then initializing asynchonously using .init()

import { Application } from 'pixi.js';

const app = new Application();

await app.init({
  width: 800,
  height: 600,
  backgroundColor: 0x1099bb,
});

document.body.appendChild(app.canvas);

Sprites

Using the SPRITE class, it is possible to display all of visual assets provided by hosts using RenaEngine.

Each Sprite represents an image to be displayed and it requires a Texture, a transform and display state to properly function in a scene graph.

import { Assets, Sprite } from 'pixi.js';

const texture = await Assets.load('path/to/image.png');
const sprite = new Sprite(texture);

sprite.anchor.set(0.5);
sprite.position.set(100, 100);
sprite.scale.set(2);
sprite.rotation = Math.PI / 4; // Rotate 45 degrees

The relation between the aforementionned elements is as follows:

Image asset -> Texture -> Sprite -> PxiJS Renderer

PixiJS supports images in the following formats:

  • PNG
  • JPEG/JPG
  • WebP
  • SVG

Assets and Layering

Assets

  • await Assets.load(path) loads a texture. The result is cached.
  • Loading the same path again returns the same object (cheap to call repeatedly).
  • Assets.get(key) reads from the cache without loading.
  • Aliases: Assets.load({ alias, src }), then Assets.get(alias).
  • Assets.unload(path) frees memory.
  • Formats: png, jpg, webp, mp4/webm, sprite sheets, bitmap and web fonts, JSON, basis/ktx2.
  • Manifests and bundles are set up with Assets.init(). Useful for loading all of a game's assets at setup, which matches the Viewer's "receive all assets before rendering" requirement.

Layering

  • A Container groups display objects. Use addChild, addChildAt, removeChild, removeChildAt, removeChildren.
  • zIndex sets draw order among siblings. Set container.sortableChildren = true to apply it, and call sortChildren() after changing it manually.
  • reparentChild moves a child to another container and keeps its hierarchy position.
  • Sorting many children every frame is expensive. Set zIndex ONLY when needed. Try to keep layers in separate containers.

Review Viewer Modes and Controls

Viewer Modes and Controls

Recorded Games

People that are using RenaEngine should be able view their recorded games. Therefore, it is essential to provide features that enhance the user experience.

PixiJS can offer rendering and update mechanisms that can fufil or help in the development of some of the Game Viewer's requirements using the Ticker class.

Feature Notes
Play ticker.start() calls listeneners every frame
Pause ticker.stop() pauses the ticker
Playback Speed ticker.speed scales time for slow motion or fast forward effects

Other required features requires more fine tuning, and is not directly supported by PixiJS. They will require their own engineered application logic. These features include:

  • Viewing of the previous change
  • Viewing of the next change

Live Viewing

It is important to know in which state the Game Viewer is in to know what to display to the users. Possible states include:

  • Connecting - The viewer is establishing a connection to a specific game.
  • Waiting - The viewer is receiving game data.
  • Running - The viewer is receiving updates and is rendering the game
  • Ended - All moves have been rendered and the game has ended

Questions

  • Should the user be able to pause a game during a live game? (Testing games included)
  • What happens when a game/recording ends? (rendered elements and application features)
  • What is displayed when a viewer is connecting, waiting, or fails to load a game?
  • Should a game be automatically recorded at the end of a live game?

Record Cross-Team Dependencies

  • Cross-Team Dependency with the Server Team In renderables.ts it will be important to specify what the payload will be exactly for the game setup
interface ViewerSetup {
//to be determined by the server team
}

Sources: