Talos docs

Author

Since 0.6

The one capability an authoring script has.

Plain text

Signature

export interface Author {
  /** The script's file name, the prefix of every id it makes. */
  readonly owner: string;
  /** The seed {@link Author.random} and `Math.random` draw from: the same on every run. */
  readonly seed: number;
  /** The target scene as it is written now, read-only. */
  readonly scene: { readonly entities: ReadonlyArray<{ readonly id: string; readonly [field: string]: unknown }>; readonly [field: string]: unknown };
  /** A project file's text, by its project-relative path (`data/level.json`). Nothing outside the project. */
  read(path: string): string;
  /** A project file parsed as JSON. */
  json<T = unknown>(path: string): T;
  /**
   * A CSV file as one object per row, keyed by the header. A field that is a number becomes one
   * unless `raw` is true or it was quoted.
   */
  csv<T = Record<string, string | number>>(path: string, options?: { raw?: boolean }): T[];
  /** A number in [0, 1) from the script's own seeded stream (as `Math.random` is here). */
  random(): number;
  /** Makes the entity `"<owner>:<key>"`. A key is 1 to 128 characters with no "/", unique in the run. */
  entity(key: string | number, spec?: AuthorEntitySpec): AuthorHandle;
  /** Places the prefab (`prefabs/goblin.prefab.json`) as the entity `"<owner>:<key>"`. */
  instance(key: string | number, prefab: string, spec?: AuthorInstanceSpec): AuthorHandle;
  /** Declares an asset entry of the scene, as its `assets` map writes it: `{ kind: "glb", path: "models/x.glb" }`. */
  asset(id: string, ref: { kind: string; path: string; [field: string]: unknown }): string;
  /**
   * Imports a model, sound or font of the project (a project-relative path; never one outside it,
   * links resolved) as the asset `id`, through the importer `asset.import` uses, in the same change.
   * A file already in the scene's folder (where `asset.import` puts what it brings in from outside)
   * is named where it is; any other is copied in. A later run with the same file and settings
   * copies nothing.
   */
  importAsset(id: string, path: string, settings?: AuthorImportSettings): string;
  /** A line for the run's answer: counts, what was skipped, anything worth saying. */
  report(line: string): void;
}

Import: import type { Author } from "@argus/api"

Members

MemberSignatureDescription
ownerreadonly owner: stringThe script's file name, the prefix of every id it makes.
seedreadonly seed: numberThe seed {@link Author.random} and Math.random draw from: the same on every run.
scenereadonly scene: { readonly entities: ReadonlyArray<{ readonly id: string; readonly [field: string]: unknown }>; readonly [field: string]: unknown }The target scene as it is written now, read-only.
readread(path: string): stringA project file's text, by its project-relative path (data/level.json). Nothing outside the project.
jsonjson<T = unknown>(path: string): TA project file parsed as JSON.
csvcsv<T = Record<string, string | number>>(path: string, options?: { raw?: boolean }): T[]A CSV file as one object per row, keyed by the header. A field that is a number becomes one unless raw is true or it was quoted.
randomrandom(): numberA number in [0, 1) from the script's own seeded stream (as Math.random is here).
entityentity(key: string | number, spec?: AuthorEntitySpec): AuthorHandleMakes the entity "<owner>:<key>". A key is 1 to 128 characters with no "/", unique in the run.
instanceinstance(key: string | number, prefab: string, spec?: AuthorInstanceSpec): AuthorHandlePlaces the prefab (prefabs/goblin.prefab.json) as the entity "<owner>:<key>".
assetasset(id: string, ref: { kind: string; path: string; [field: string]: unknown }): stringDeclares an asset entry of the scene, as its assets map writes it: { kind: "glb", path: "models/x.glb" }.
importAssetimportAsset(id: string, path: string, settings?: AuthorImportSettings): stringImports a model, sound or font of the project (a project-relative path; never one outside it, links resolved) as the asset id, through the importer asset.import uses, in the same change. A file already in the scene's folder (where asset.import puts what it brings in from outside) is named where it is; any other is copied in. A later run with the same file and settings copies nothing.
reportreport(line: string): voidA line for the run's answer: counts, what was skipped, anything worth saying.

Example

The tested fixture fixtures/app/agent.ts.

import type { Behavior } from "@argus/api"

// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
  init(ctx) {
    ctx.state.arrived = false
    ctx.nav?.goTo(ctx.props.target as [number, number, number])
  },
  update(ctx) {
    if (ctx.nav?.arrived) ctx.state.arrived = true
  },
} satisfies Behavior