Files
incremental-game-engine/engine/src/behaviours/base.ts
T
2026-09-04 14:11:25 +03:00

62 lines
2.4 KiB
TypeScript

import Decimal, { type DecimalSource } from "break_eternity.js";
import type { BehaviourDisplayInfo, BehaviourLink, BehaviourSocket, Resource, Resources, SerializedBehaviour } from "../types";
export abstract class Behaviour {
public readonly id: string;
public readonly kind: string;
public readonly inputLinks: BehaviourLink[];
constructor(source: SerializedBehaviour) {
this.id = source.id;
this.kind = source.kind;
this.inputLinks = source.inputLinks.pins;
}
public getDisplayInfo(): BehaviourDisplayInfo {
return {
storages: {},
sockets: [
...this.inputs.map((input, index) => ({
type: 'input',
index,
resource: input,
} satisfies BehaviourSocket)),
...this.outputs.map((output, index) => ({
type: 'output',
index,
resource: output,
} satisfies BehaviourSocket)),
],
};
}
public abstract get inputs(): Resource[];
public abstract get outputs(): Resource[];
/** Withdraws up to `amount` of `resource` from this behaviour's storage, returning how much was actually taken. */
public abstract take(resource: Resource, amount: DecimalSource): Decimal;
protected abstract give(resource: Resource, amount: DecimalSource): void;
/** Snapshot of everything currently held, keyed by resource. */
public abstract getStorage(): Partial<Resources>;
abstract reset(): void;
/**
* Advances this behaviour by `deltaTime`. Must pull whatever inputs it needs (via `resolve`)
* before advancing its own cycle, so that a cycle only completes once enough input was actually
* available — otherwise it stalls and tries again on a later tick.
*
* `fairShare(sourceId, resource)` caps how much of `resource` may be pulled from `sourceId` this
* tick: when several behaviours are linked to the same source for the same resource, each is
* capped to an equal share of what that source held right after its own tick, regardless of
* pull order, instead of whoever asks first draining it.
*/
abstract tick(
deltaTime: number,
resolve: (id: string) => Behaviour | undefined,
fairShare: (sourceId: string, resource: Resource) => Decimal,
): void;
}