FiredancerVM.js
A JavaScript wrapper for Firedancer VM.
Caveats
- Unstable!!
- Currently the thread pool capacity (the max number of threads per actor) is fixed at
8
, and the memory capacity (the memory size in bytes per actor) is fixed at 256
. Maybe these should be possible to change in future versions.
Usage
(See also the full Example below)
Load the Library
FiredancerVM.js is an IIFE library.
Load it in your HTML before loading your own script so that it defines a variable FiredancerVM
in the global scope that can be referred from your code.
For example:
<head>
<script src="https://unpkg.com/@fal-works/firedancer-vm@0.1.2/lib/firedancer-vm.min.js" defer></script>
<script src="path/to/your-script.js" defer></script>
</head>
Prepare a FiredancerVM.ProgramPackage
instance
Prepare any Firedancer program package serialized into a JSON string representation.
Then parse it by FiredancerVM.ProgramPackage.fromString()
so that you get a FiredancerVM.ProgramPackage
instance, which can be executed on the VM.
Define the Habitable Zone
Any actor that is out of the habitable zone is automatically killed.
Define the zone by either:
FiredancerVM.RectangleBounds.fromCorners(
x1: number,
y1: number,
x2: number,
y2: number
)
or
FiredancerVM.RectangleBounds.fromSize(
width: number,
height: number,
margin: number,
centerX: boolean = false,
centerY: boolean = false
)
Create Firedancer Context
Create a context object:
{
programPackage: FiredancerVM.ProgramPackage,
habitableZone: FiredancerVM.RectangleBounds,
getGroupOnFire: (fireCode: number) => FiredancerVM.ActorGroup,
onFire: (actor: FiredancerVM.Actor, fireCode: number) => void,
defaultTargetPositionRef: { x: number, y: number },
onEnd: (actor: FiredancerVM.Actor, endCode: number) => void,
onGlobalEvent: (glotalEventCode: number) => void,
onLocalEvent: (localEventCode: number, x: number, y: number, thread: Thread, originPositionRef: { x: number, y: number } | null, targetpositionRef: { x: number, y: number }) => void,
defaultDraw: (actor: FiredancerVM.Actor) => void
}
At this moment all properties are optional, however:
- At least you'll have to eventually set
programPackage
and getGroupOnFire
before running the VM, otherwise you'll have runtime errors. See also below about getGroupOnFire
.
- If you don't set
defaultDraw
, you have to manually set the field draw: (actor) => void
for each Actor
instance in the onFire()
function, otherwise you won't see anything on the screen.
Create an Actor Group
Now you can create an actor group passing the context you have prepared.
new FiredancerVM.ActorGroup(context);
Set context.getGroupOnFire
The context field getGroupOnFire
is a function that returns the actor group which should be used when any actor is fired (The argument fireCode
receives any integer value that is specified in the original Firedancer program).
Set this function after creating your actual actor group(s).
Activate your first Actor
Activate an actor with any program.
- You can get a Firedancer Program from your
FiredancerVM.ProgramPackage
instance by calling its method getProgramByName(name)
.
- Call
use()
on your FiredancerVM.ActorGroup
instance, which reserves a new actor and returns it. Then call reset()
on the returned actor.
For example:
const program = programPackage.getProgramByName("main");
const x = 0, y = 0, vx = 0, vy = 0;
actors.use().reset(x, y, vx, vy, program);
Run
Call update()
and draw()
on your FiredancerVM.ActorGroup
instance(s) in each frame.
Basically the frame rate should be fixed to 60 FPS.
Example
Here is a full (but simple) example using FiredancerVM.js and p5.js.
Be sure to load each library before your own script.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/@fal-works/firedancer-vm@0.1.2/lib/firedancer-vm.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js" defer></script>
<script src="path/to/your-script.js" defer></script>
</head>
<body>
</body>
</html>
const worldWidth = 600;
const worldHeight = 600;
const programPackage = FiredancerVM.ProgramPackage.fromString(`{
"nameIdMap": {
"main": 0
},
"programTable": [
"s44:4AAAAAAAAAAAAAAAAAAAFEAj%Nbre:Ppzso:AAIRAAAA"
],
"vmVersion": "0.1.0"
}`);
const margin = 60;
const centerX = true;
const centerY = true;
const habitableZone = FiredancerVM.RectangleBounds.fromSize(
worldWidth,
worldHeight,
margin,
centerX,
centerY
);
const context = {
programPackage,
habitableZone,
};
const actors = new FiredancerVM.ActorGroup(context);
context.getGroupOnFire = () => actors;
function setup() {
createCanvas(worldWidth, worldHeight);
stroke("#4d089a");
fill("#4d089a20");
context.defaultDraw = (actor) => circle(actor.x, actor.y, 30);
const x = 0, y = 0, vx = 0, vy = 0;
actors.use().reset(x, y, vx, vy, programPackage.getProgramByName("main"));
}
function draw() {
actors.update();
background(252);
translate(width / 2, height / 2);
actors.draw();
}
Third Party Licenses
The following software may be included in this product:
The Haxe Standard Library
© 2005-2016 Haxe Foundation
Used under MIT License.