Math and Values#

These look like conveniences and are really a compatibility boundary. Reading this page once will save you a confusing afternoon later.

Why they exist#

In onejs-react, Vector2 and Color are type aliases for the C# types, and Transform2D.point() returns a real CS.UnityEngine.Vector2. That is correct in a Unity project and unusable in code that must also run where there is no C# to reach.

So oj exports its own Vector2, Color and Transform2D: plain JavaScript classes, same names, no interop. They are not wrappers around the C# types and they do not convert to them implicitly.

The gotcha follows directly. If you import Vector2 from oj and something else from onejs-react that expects the C# Vector2, you have two different types wearing one name, and the failure arrives at a call site that looks fine. Pick one source per project. If you are writing against oj, take all of these from oj.

Vector2#

import { Vector2 } from "oj"

const v = new Vector2(3, 4)
v.add(other)      // returns a new Vector2
v.sub(other)
v.mul(2)
v.div(2)
v.negate()
v.clone()
v.equals(other)

Arithmetic returns new instances rather than mutating. set(x, y) and copyFrom(v) mutate in place and return this, for the hot paths where allocating per frame is the thing you are trying to avoid. Statics cover the usual constants: Vector2.zero, one, up, down, left, right.

Color#

import { Color } from "oj"

const c = new Color(1, 0.5, 0, 1)   // r, g, b, a in 0..1
c.withAlpha(0.5)
c.mul(0.8)                          // scales rgb, leaves alpha
c.toHex()

Statics match Unity's names: white, black, clear, red, green, blue, yellow, cyan, magenta, gray and grey.

Mathf#

Unity's Mathf, in JavaScript, with the same names and semantics: Sign, Min, Max, Lerp, LerpUnclamped, LerpAngle, InverseLerp, PingPong, SmoothStep, MoveTowardsAngle, Approximately and the rest. It exists so that code and habits move between C# and JavaScript without translation, not because Math is missing anything.

random#

import { random } from "oj"

const rng = random("level-1")       // seeded, reproducible
rng.next()                          // 0..1
rng.int(1, 6)
rng.range(0.5, 2)
rng.bool(0.3)
rng.sign()
rng.direction()                     // a unit vector, as { x, y }

random(seed?) returns an Rng. Seed it with a string or a number and the sequence is reproducible, which is what you want for anything you intend to test, replay or generate identically for two players.

rng.fork(label) derives an independent stream from the same seed. Use it to keep unrelated systems from perturbing each other: if terrain and loot draw from one stream, adding a single terrain call reshuffles every drop.

Transform2D#

The JavaScript-only counterpart of onejs-react's transform stack, for use with the batched painter. It provides the translate, rotate and scale stack that the raw Painter2D has no state for, and its companion TransformedPath applies it to a path sink.

Take it from oj rather than onejs-react in oj code, for the reason at the top of this page: the onejs-react one returns C# vectors.