Skip to content

Resources

Resources are global singletons — they exist once in the entire app, not attached to any entity. Use them for shared state like time, input, and game configuration.

Accessing Resources

Res (read-only)

import { defineSystem, Res, Time } from 'esengine';
defineSystem([Res(Time)], (time) => {
console.log(`Delta: ${time.delta}s, Elapsed: ${time.elapsed}s`);
});

ResMut (mutable)

import { defineSystem, ResMut } from 'esengine';
defineSystem([ResMut(GameState)], (state) => {
state.get().score += 10;
});

ResMut wraps the resource value. Access the data with .get(), replace it entirely with .set(), or use .modify() for partial updates:

defineSystem([ResMut(GameState)], (state) => {
state.modify((s) => {
s.score += 10;
s.level = Math.floor(s.score / 100) + 1;
});
});

Builtin Resources

Time

Frame timing information. Available automatically.

import { Res, Time } from 'esengine';
defineSystem([Res(Time)], (time) => {
time.delta; // Seconds since last frame
time.elapsed; // Total elapsed seconds
time.frameCount; // Total frames rendered
});
PropertyTypeDescription
deltanumberSeconds since last frame
elapsednumberTotal elapsed seconds
frameCountnumberTotal frames rendered

Input

Keyboard and mouse state. Available automatically.

import { Res, Input } from 'esengine';
defineSystem([Res(Input)], (input) => {
if (input.isKeyDown('Space')) {
// Space is held
}
if (input.isKeyPressed('KeyE')) {
// E was just pressed this frame
}
});
MethodDescription
isKeyDown(code)Key is currently held
isKeyPressed(code)Key was pressed this frame
isKeyReleased(code)Key was released this frame
getMousePosition()Returns { x, y }
isMouseButtonDown(button)Mouse button held (0=left, 2=right)
isMouseButtonPressed(button)Mouse button was pressed this frame
isMouseButtonReleased(button)Mouse button was released this frame
getScrollDelta()Returns { x, y } scroll delta

UIEvents

UI interaction events collected each frame. Available when UI plugins are active (default).

import { Res } from 'esengine';
import { UIEvents } from 'esengine';
defineSystem([Res(UIEvents)], (events) => {
for (const e of events.query('click')) {
console.log('Clicked:', e.entity);
}
});

You can also subscribe to events with callbacks using .on():

defineSystem([Res(UIEvents)], (events) => {
// Subscribe to a specific entity's events
const unsub = events.on(buttonEntity, 'click', (e) => {
console.log('Button clicked!');
});
// Subscribe to all events of a type
events.on('change', (e) => {
console.log('Value changed on:', e.entity);
});
});

See UI Interaction for the full list of event types and the callback API.

Custom Resources

defineResource

import { defineResource } from 'esengine';
const GameState = defineResource({
score: 0,
level: 1,
paused: false
});

Inserting Resources

Insert a resource via Commands in a startup system:

import { addStartupSystem, defineSystem, Commands } from 'esengine';
addStartupSystem(defineSystem([Commands()], (cmds) => {
cmds.insertResource(GameState, { score: 0, level: 1, paused: false });
}));

Reading and Writing

// Read-only
defineSystem([Res(GameState)], (state) => {
console.log(`Score: ${state.score}`);
});
// Mutable
defineSystem([ResMut(GameState)], (state) => {
state.get().score += 10;
});

Example: Score Tracking

Define a Coin tag, attach it to coin entities in the scene, and track score with a resource:

import {
defineSystem, defineResource, defineTag,
addStartupSystem, addSystem, Commands, Query, ResMut,
Transform
} from 'esengine';
const Score = defineResource({ value: 0 });
const Coin = defineTag('Coin');
const Player = defineTag('Player');
addStartupSystem(defineSystem([Commands()], (cmds) => {
cmds.insertResource(Score, { value: 0 });
}));
addSystem(defineSystem(
[Commands(), ResMut(Score), Query(Transform, Player), Query(Transform, Coin)],
(cmds, score, players, coins) => {
for (const [_, pPos] of players) {
for (const [coinEntity, cPos] of coins) {
const dx = pPos.position.x - cPos.position.x;
const dy = pPos.position.y - cPos.position.y;
if (Math.sqrt(dx * dx + dy * dy) < 30) {
cmds.despawn(coinEntity);
score.get().value += 1;
}
}
}
}
));

Next Steps

  • Systems — how systems use resources and queries
  • Components — data attached to entities
  • Events — decoupled inter-system communication