跳转到内容
查看源码

文件与输入输出

场景从 Host 世界读取的一切,要么是输入,要么是节点(docs/DECISIONS.md)。文件在会话已有的 sync 中被监视,改变时重新读取。

input name: Type; 是调用者提供的 Field;加上 = 来源,Host 相对于文档读取它,并在它改变时重新读取。

写法 读成
input atlas: Image = "atlas.png"; .png/.ppm 为像素(Grid<Float> 时为亮度),.pgm 为 Grid<Float>
input sound: Rows<Vec2> = "hit.wav"; .wav 为一或两个 float 的行(采样率只报告不保存;用 at_linear 重采样)
input notes: Rows<Note> = "song.mid"; .mid 为 {start, duration, pitch, velocity, channel} 的行,节拍与速度换算为秒
input lamp: Rows<Float> = "lamp.ies"; .ies 灯光光度(C 型)为 181 行坎德拉值
input state: Grid<Cell> = "world.field"; .field:任何 Field,Host 自己的格式
input skills: Rows<Skill> = "data/skills.csv"; .csv/.json 数据表,按读取它的 Kernel 的元素布局读成行
input title: Rows<Int> = text "ENTELECHY"; 字符的码点(支持 \n、\t、\"、\\)
input level: Rows<Int> = bytes "level.bin"; 文件的字节,每个元素一个 0–255(见 examples/level)
input clip: Image = frames "clip/" at 30; 目录中按名字排序的文件,第 floor(time * rate) 帧,循环
input problems: Rows<Int> = checks "src/"; 语言在这些文档中发现的问题,文本,一行一个:file:line:column: message
input defined: Rows<Int> = outline "src/"; 这些文档定义的东西,文本,一行一个:file:line:column: kind name: signature
input disk: Rows<Int> = files "project/"; 目录下每个文件(跳过隐藏文件)的路径和字节
input pasted: Rows<Int> = clipboard; 剪贴板文本(Player 中需要 --allow clipboard.read)
input work: Rows<Int> = progress; 正在准备的 Kernel 及进度(可用来画加载界面)
input saved: Rows<Tally> = "saves/tally.field" else fresh.result; 文件存在之前读 fresh.result(存档模式,见 examples/data/parts/save)

包内路径("world.entpkg/data/rules.csv")读取那个包里的文件;写入永远不会写进包里。

  • CSV 第一行是列名;JSON 是对象数组。每个数字按 show 的命名方式命名:字段名、嵌套用点(look.race)、向量分量 x–w 或 0–3、数组下标(items.0)。
  • 以 # 开头的列/键是注释。#name 列给行命名,其他表中写 table:name(如 beasts:goblin)引用该行的序号。
  • 文本放进 [Int; N]:goblin,哥布林,30(表头 #name,name,hp)中的中文按码点逐个存入,其后补 0。
  • 读不了的表会指出行号,输入保持原样。
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/";

需要 --allow file.write=<dir>(to files 删除/重命名还需要 file.delete),并且只在改变它们的求值提交之后才写。事件 wrote、removed、renamed、write_refused 报告结果。

run --save <node.port>=<file> 把任意节点的输出写成文件——这就是制作资源的方式;行写成 .csv 或 .json,场景可以读回。

终端窗口
entelechy run scene.esn --save steps/8.spread/6.result=rock.field
entelechy run scene.esn --out output.ppm
写法 作用
node g: font "x.ttf" { codes <- wanted.result; } 读取字体:g.glyphs、g.outlines、g.metrics
node d: files "dir/" { paths <- wanted.result; } 像 git 一样列出目录(d.listing),只读取被打开的文件(d.opened)
node near: Rows<Spot> fields "chunks/" { paths <- want.result; } 按需载入 .field 文件,适合比内存大的世界

PNG、PPM、PGM、WAV、MIDI 实时读取;其他字节以 Rows<Int>(bytes)交给 Kernel。glTF、字体、SVG 和有损音频在运行时之外由 entelechy import 转换——这样格式 crate 不会收集所有格式。

终端窗口
entelechy import examples/mesh/parts/model/source/crate.glb --out examples/mesh/parts/model/assets
entelechy import song.ogg --out assets # 写出 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 输入 输出
glTF / GLB 顶点 {position, normal, uv}、三角形、基础色 PNG;带蒙皮时加权重、骨架和动画片段(见仓库 docs/RIGS.md);<stem>.parts.field/json 记录每个三角形来自哪个部件
MP3、OGG Vorbis、FLAC、AAC、Matroska 音频 WAV
MIDI 每个音符一行(start、length、key、velocity、channel)
SVG vector 包绘制所需的线段、形状、渐变点和视图
TrueType / OpenType --chars 指定字符(或全部)的字形、轮廓和度量

export 反向写出:GLB(顶点、三角形、PNG 贴图、骨骼)、WAV、PNG、MIDI,以及 TrueType/OpenType(CFF)/WOFF 字体。import 读入的内容可以逐位写回(字体除外:线段写回为曲线,误差在一个字体单位内)。