Skip to content
View source

Files & I/O

What a scene reads of the Host’s world is an input or a node (docs/DECISIONS.md). Files are watched on the sync the session already makes and read again when they change.

input name: Type; is a Field the caller supplies; with = source, the Host reads it relative to the document, and again whenever it changes.

Form Read as
input atlas: Image = "atlas.png"; .png/.ppm as pixels (luminance for Grid<Float>), .pgm as Grid<Float>
input sound: Rows<Vec2> = "hit.wav"; .wav as rows of one or two floats (the rate is reported, not stored; resample with at_linear)
input notes: Rows<Note> = "song.mid"; .mid as rows of {start, duration, pitch, velocity, channel}, ticks and tempo read as seconds
input lamp: Rows<Float> = "lamp.ies"; .ies light photometry (type C) as 181 rows of candela
input state: Grid<Cell> = "world.field"; .field: any Field, the Host’s format
input skills: Rows<Skill> = "data/skills.csv"; a .csv/.json table, read as rows of the element the reading Kernel lays out
input title: Rows<Int> = text "ENTELECHY"; the characters’ codes (\n, \t, \", \\)
input level: Rows<Int> = bytes "level.bin"; a file’s bytes, one per element, 0 to 255 (examples/level)
input clip: Image = frames "clip/" at 30; a directory’s files in name order, frame floor(time * rate), wrapping
input problems: Rows<Int> = checks "src/"; what the language finds wrong in those documents, as text, a line a problem: file:line:column: message
input defined: Rows<Int> = outline "src/"; what those documents define, a line each: file:line:column: kind name: signature
input disk: Rows<Int> = files "project/"; every file under a directory (hidden ones left out), paths and bytes
input pasted: Rows<Int> = clipboard; the clipboard’s text (the Player needs --allow clipboard.read)
input work: Rows<Int> = progress; the Kernels being prepared and how far (for a loading screen)
input saved: Rows<Tally> = "saves/tally.field" else fresh.result; fresh.result until the file exists (saving, see examples/data/parts/save)

A path through a package ("world.entpkg/data/rules.csv") reads the file inside that package; nothing is ever written into a package.

  • A CSV’s first line names its columns; a JSON file is an array of objects. Each number is named as show names it: a field by name, nested with a dot (look.race), a vector’s lane x–w or 0–3, an array element by index (items.0).
  • A column or key beginning with # is a note. A #name column names rows; another table’s cell table:name (beasts:goblin) is that row’s place.
  • Text goes in an [Int; N]: goblin,哥布林,30 under #name,name,hp stores the characters’ codes, zeros after.
  • A table that cannot be read says the line or row and leaves the input as it was.
output kept <- state.result to "saves/state.field";
output table <- scores.result to "scores.csv";
output raw <- packed.result to bytes "out.bin";
output tree <- edits.result to files "project/";

These need --allow file.write=<dir> (and file.delete for removal and rename by to files), and are written only once the evaluation that changed them commits. The events wrote, removed, renamed and write_refused report the outcome.

run --save <node.port>=<file> writes any node’s output — how an asset is made; rows go out as .csv or .json a scene reads back.

终端窗口
entelechy run scene.esn --save steps/8.spread/6.result=rock.field
entelechy run scene.esn --out output.ppm
Form Effect
node g: font "x.ttf" { codes <- wanted.result; } reads a font: g.glyphs, g.outlines, g.metrics
node d: files "dir/" { paths <- wanted.result; } lists a folder as git would (d.listing), reading only the opened files (d.opened)
node near: Rows<Spot> fields "chunks/" { paths <- want.result; } brings .field files in on demand, for a world larger than memory

PNG, PPM, PGM, WAV and MIDI are read live; other bytes go to a Kernel as Rows<Int> (bytes). glTF, fonts, SVG and lossy sound are converted outside the runtime by entelechy import — so the formats crate never collects every format.

终端窗口
entelechy import examples/mesh/parts/model/source/crate.glb --out examples/mesh/parts/model/assets
entelechy import song.ogg --out assets # writes assets/song.wav
entelechy import examples/vector/source/garden.svg --out examples/vector/assets
entelechy import font.ttf --out assets --chars "Hello, world."
entelechy export crate.vertices.field crate.triangles.field crate.albedo.png --out crate.glb
entelechy export kick.field --out kick.wav --rate 48000
entelechy export song.notes.field --out song.mid --beats 100
import takes writes
glTF / GLB vertices {position, normal, uv}, triangles, the base color as PNG; a skin adds weights, skeleton and clips (see docs/RIGS.md); <stem>.parts.field/json says which part each triangle came from
MP3, OGG Vorbis, FLAC, AAC, Matroska audio WAV
MIDI a row a note (start, length, key, velocity, channel)
SVG the segments, shapes, stops and view the vector package draws
TrueType / OpenType glyphs, outlines and metrics for --chars, or every character

export goes the other way: GLB (vertices, triangles, PNG maps, a rig as a skin), WAV, PNG, MIDI, and TrueType/OpenType (CFF)/WOFF fonts. What the importer read is written back bit for bit, but a font: its segments come back as curves within a font unit.