# Engine API Two layers. A new frontend should call the **app-facing API** (`engineApi.ts`); reach into the **pure engine** (`engine.ts`) only for custom flows (search, permalinks, validators). --- ## App-facing API — `src/engine/engineApi.ts` ```ts pullAt(formId, pos: [x,y,z], lushiOnly: boolean): PulledPoem ``` Pull a poem out of the void at a clicked world point. Deterministic: same point + form + mode → same poem. `lushiOnly=false` samples the full Babel catalog (almost always gibberish); `lushiOnly=true` samples the nested 格律 sub-catalog (always tone/rhyme-valid under the active lexicon). Returns: ```ts interface PulledPoem { form: FormId; // "wujue" | "qijue" | "wulu" | "qilu" lines: string[]; // poem text, one string per line babelIndex: string; // decimal — the catalog address (82–229 digits) babelDigits: number; // its length (UI flavour) lushiIndex: string | null; // 格律 sub-catalog index, if the poem is regulated valid: boolean; // is it 格律-valid? pos: [number, number, number]; // where to place the star (the clicked point) } ``` ```ts pointForBabelIndex(formId, b: bigint, R?=1000): Vec3 ``` Canonical 3D position of a known catalog index `b` (for search / permalink fly-to). Uses a reversible Feistel scatter so neighbouring indices land far apart. ```ts babelCardinality(form): bigint // N^L for the form regulatedCardinality(form): bigint // |格律 sub-catalog| textBabelIndex(form, hanText): {index, digits} | null // a REAL poem's catalog index; null unless char count == form length & all chars ∈ 字库. ``` ```ts type PullForm = FormId | "ziyou"; // the 5th "form" — 自由格式 / 词 — is a separate catalog pullAt(form: PullForm, pos, {lushiOnly?, commonK?}) // form="ziyou" → describeFree: a variable-length 词 from the radix-(realN+W) 自由 catalog; // lines come from splitFree (id ≥ realN = a line break), index is the 自由目录 address, no 格律. halfIndex(form: FormId, han): HalfIndex | null // 半编号 of a typed OPENING (han.length ≤ L) halfIndexAuto(han): HalfIndex | null // ↑ but auto-picks the form by line length pullByIndex(form: PullForm, indexStr): IndexPoem | null // 反查: 编号 → 诗 (the bijection's // other direction). babelUnrank/freeUnrank the decimal index back into the poem at that catalog // position. {lines, inRange, ...}. The displayed 全集编号 is babelRank itself (a true 正序 rank, // first char = MSB), so pullByIndex(form, poemIndex) reproduces the exact poem — 诗 ⇄ 编号. pulledFromIndex(form: PullForm, indexStr): PulledPoem | null // ↑ but returns a full PulledPoem // placed at the canonical scattered point — used to REBUILD a shared #p=