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.value.score += 10;
});

ResMut wraps the resource value. Access the data with .value, or use .modify():

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)

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.value.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,
LocalTransform
} 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(LocalTransform, Player), Query(LocalTransform, 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.value.value += 1;
}
}
}
}
));

Next Steps

  • Systems — how systems use resources and queries
  • Components — data attached to entities