Skip to content

@aosengine/assets-placeholder

Classes

ColliderFormatError

A collider buffer that could not be read.

The message always says what was expected and what was found, because the only realistic way to hit it is to hand the parser the wrong file.

Extends

  • Error

Constructors

Constructor
ts
new ColliderFormatError(message): ColliderFormatError;

Build a collider format error.

Parameters
ParameterTypeDescription
messagestringWhat is wrong with the buffer.
Returns

ColliderFormatError

Overrides
ts
Error.constructor

Interfaces

ArenaBounds

The axis-aligned box the playable arena occupies.

Example

ts
import type { ArenaBounds } from '@aosengine/assets-placeholder';
import { arenaSpawns } from '@aosengine/assets-placeholder';

const bounds: ArenaBounds = arenaSpawns.bounds;
console.log(bounds.max[0] - bounds.min[0]); // 24 — the floor is 24 m across

Properties

max
ts
readonly max: readonly [number, number, number];

Maximum corner [x, y, z] in metres.

min
ts
readonly min: readonly [number, number, number];

Minimum corner [x, y, z] in metres.


ArenaSpawns

The shape of assets/arena.spawns.json.

Example

ts
import type { ArenaSpawns } from '@aosengine/assets-placeholder';
import { arenaSpawns } from '@aosengine/assets-placeholder';

const spawns: ArenaSpawns = arenaSpawns;
console.log(spawns.units, spawns.up); // 'metres' '+Y'

Properties

bounds
ts
readonly bounds: ArenaBounds;

The playable volume: floor, walls and everything between them.

enemies
ts
readonly enemies: readonly SpawnPoint[];

Six enemy spawn points, spread around the perimeter.

generatedBy
ts
readonly generatedBy: string;

Which script produced the file.

pickups
ts
readonly pickups: readonly SpawnPoint[];

Three pickup positions, floating a metre above the floor.

player
ts
readonly player: SpawnPoint;

Where the player starts, facing the centre.

units
ts
readonly units: "metres";

Length unit every coordinate is in.

up
ts
readonly up: "+Y";

Which axis points up.

yawConvention
ts
readonly yawConvention: string;

How to read the yaw fields.


ColliderMesh

A triangle mesh: flat positions plus flat triangle indices.

Properties

indices
ts
readonly indices: Uint32Array;

Triangle indices into positions. Length is a multiple of three.

positions
ts
readonly positions: Float32Array;

Vertex positions in metres, flattened x y z. Length is 3 * vertexCount.


PlaceholderAssetEntry

One entry of placeholderManifest.

Example

ts
import type { PlaceholderAssetEntry } from '@aosengine/assets-placeholder';
import { placeholderManifest } from '@aosengine/assets-placeholder';

const sfx: readonly PlaceholderAssetEntry[] = placeholderManifest.assets.filter((a) =>
  a.tags.includes('sfx'),
);
console.log(sfx.length); // 4

Properties

collider?
ts
readonly optional collider?: PlaceholderCollider;

Static collision proxy, on the entries that have one.

id
ts
readonly id: string;

Stable id game logic asks for.

src
ts
readonly src: string;

Path relative to PLACEHOLDER_ASSETS_BASE.

tags
ts
readonly tags: readonly string[];

Grouping labels; every entry carries placeholder.

type
ts
readonly type: "splat" | "audio";

What the host loads the entry as.


PlaceholderCollider

A static collision proxy, as the manifest declares it.

Example

ts
import type { PlaceholderCollider } from '@aosengine/assets-placeholder';

const collider: PlaceholderCollider = {
  shape: 'mesh',
  src: 'arena.collider.bin',
  layer: 'static',
};
console.log(collider.src); // 'arena.collider.bin'

Properties

layer
ts
readonly layer: "static";

Physics layer the proxy belongs to.

shape
ts
readonly shape: "mesh";

Collider shape. The arena uses a triangle mesh.

src
ts
readonly src: string;

Path to the collision geometry, relative to the manifest.


PlaceholderManifest

The shape of assets/assets.json.

Example

ts
import type { PlaceholderManifest } from '@aosengine/assets-placeholder';
import { placeholderManifest } from '@aosengine/assets-placeholder';

const manifest: PlaceholderManifest = placeholderManifest;
console.log(manifest.version); // 1

Properties

assets
ts
readonly assets: readonly PlaceholderAssetEntry[];

Every placeholder asset, in load order.

version
ts
readonly version: 1;

Manifest schema version.


SpawnPoint

A place to put something, with the direction it should face.

Example

ts
import type { SpawnPoint } from '@aosengine/assets-placeholder';
import { arenaSpawns } from '@aosengine/assets-placeholder';

const spawn: SpawnPoint = arenaSpawns.player;
console.log(spawn.position[1]); // 0 — feet on the floor

Properties

position
ts
readonly position: readonly [number, number, number];

World position [x, y, z] in metres, Y-up, origin at the floor centre.

yaw
ts
readonly yaw: number;

Yaw in radians about +Y; 0 looks down -Z, like three's rotation.y.

Variables

arenaSpawns

ts
const arenaSpawns: ArenaSpawns;

A typed, ready-to-use copy of assets/arena.spawns.json.

Spawn points are not assets — there is no manifest type for "a list of coordinates" and inventing one would be a schema change — so they ship as a plain export. A unit test asserts this object and the JSON never drift apart, and that every point sits inside ArenaSpawns.bounds.

Example

ts
import { arenaSpawns } from '@aosengine/assets-placeholder';

const { position, yaw } = arenaSpawns.player;
console.log(position, yaw); // [0, 0, 9] 0
console.log(arenaSpawns.enemies.length); // 6

PACKAGE

ts
const PACKAGE: "@aosengine/assets-placeholder";

Package identity marker.

Example

ts
import { PACKAGE } from '@aosengine/assets-placeholder';

console.log(PACKAGE); // '@aosengine/assets-placeholder'

PLACEHOLDER_ASSETS_BASE

ts
const PLACEHOLDER_ASSETS_BASE: string;

Absolute URL of the directory holding the packaged assets, with a trailing slash.

Use it as a manifest baseUrl. It resolves against this module, so it is correct from src/ under the development condition, from dist/ in a published install, and from whatever path a bundler emits.

Example

ts
import { PLACEHOLDER_ASSETS_BASE } from '@aosengine/assets-placeholder';

console.log(PLACEHOLDER_ASSETS_BASE.endsWith('/assets/')); // true

placeholderManifest

ts
const placeholderManifest: PlaceholderManifest;

A typed, ready-to-parse copy of assets/assets.json.

It has no baseUrl, so merge PLACEHOLDER_ASSETS_BASE in when you feed it to parseManifest, or point loadManifest at the JSON file itself and let it default the base to the file's own directory. A unit test asserts this object and the JSON never drift apart.

face.idle is deliberately absent: docs/schemas/assets.schema.json fixes type to splat | gltf | character | audio, an ARKit clip is none of those, and extending the schema is out of scope for a placeholder pack. Reach it with placeholderAssetUrl('face_idle.arkit.json') instead.

Example

ts
import { parseManifest } from '@aosengine/assets';
import { placeholderManifest, PLACEHOLDER_ASSETS_BASE } from '@aosengine/assets-placeholder';

const manifest = parseManifest(placeholderManifest, { baseUrl: PLACEHOLDER_ASSETS_BASE });
console.log(manifest.assets.map((a) => a.id)); // ['env.arena', 'sfx.shot', ...]

Functions

encodeCollider()

ts
function encodeCollider(positions, indices): ArrayBuffer;

Write an arena.collider.bin buffer.

The exact inverse of parseCollider: parseCollider(encodeCollider(p, i)) returns p and i unchanged, up to f32 rounding of the positions.

Parameters

ParameterTypeDescription
positionsArrayLike<number>Vertex positions in metres, flattened x y z.
indicesArrayLike<number>Triangle indices into positions.

Returns

ArrayBuffer

The encoded file, ready to write to disk.

Throws

When positions is not a whole number of vertices, indices is not a whole number of triangles, or an index is out of range.

Example

ts
import { encodeCollider, parseCollider } from '@aosengine/assets-placeholder';

// A single 1 m triangle on the floor.
const file = encodeCollider([0, 0, 0, 1, 0, 0, 0, 0, 1], [0, 1, 2]);
console.log(file.byteLength); // 8 + 9 * 4 + 3 * 4 = 56
console.log(parseCollider(file).indices.length); // 3

parseCollider()

ts
function parseCollider(buffer): ColliderMesh;

Read an arena.collider.bin buffer.

The whole file is validated up front — counts, length and index range — so a mesh that parses is a mesh physics can consume without further checks.

Parameters

ParameterTypeDescription
bufferArrayBuffer | ArrayBufferView<ArrayBufferLike>The file contents, as an ArrayBuffer or any view over one.

Returns

ColliderMesh

The vertex positions and triangle indices, as views over buffer.

Throws

When the buffer is truncated, the index count is not a multiple of three, or an index is out of range.

Example

ts
import { parseCollider, placeholderAssetUrl } from '@aosengine/assets-placeholder';

const bytes = await (await fetch(placeholderAssetUrl('arena.collider.bin'))).arrayBuffer();
const { positions, indices } = parseCollider(bytes);
console.log(positions.length / 3, indices.length / 3); // 98 142

placeholderAssetUrl()

ts
function placeholderAssetUrl(file): string;

The absolute URL of one packaged file.

This is the escape hatch for the two files that cannot live in the manifest — arena.spawns.json and face_idle.arkit.json — and for tooling that wants the bytes directly. Game logic must not call it: assets are addressed by id (AGENTS.md rule 3), and the ids are in placeholderManifest.

Parameters

ParameterTypeDescription
filestringA file name inside assets/, for example arena.spz.

Returns

string

The absolute URL of that file.

Example

ts
import { placeholderAssetUrl } from '@aosengine/assets-placeholder';

const url = placeholderAssetUrl('face_idle.arkit.json');
console.log(url.endsWith('/assets/face_idle.arkit.json')); // true