Documentation
¶
Overview ¶
Package filoio reads and writes Linefire's documents in the Filo language.
Filo is used as an S-expression DSL, not as JSON with parentheses: registered builtins build a tagged value tree, hand-written decoders turn that tree into the plain model structs, and Save emits Filo text by hand. That keeps `asset` and `level` free of any serialization concern — they stay pure models — and it leaves room for the reason this format was chosen in the first place: because a document is a PROGRAM, an author can compute a value inline (arithmetic, a generator such as a rectangle of wall) without a new struct field or a new case in the engine.
Filo's own vocabulary is off limits: the core already defines 31 builtins (list, map, range, string, head, length, not, ...) and 15 special forms (def, set, do, if, ...). RegisterBuiltin refuses a duplicate, so a clash fails loudly at Load rather than silently shadowing. That is why the map document is (level ...) and not (map ...).
Index ¶
- Constants
- func AssetPath(dir, ref string) string
- func ConfigPath() (string, error)
- func EmitAsset(a *asset.Asset) string
- func EmitChunk(cx, cy int, walls []asset.Layer, spawns []level.Spawn) string
- func EmitConfig(c config.Config) string
- func EmitLevel(l *level.Level) string
- func LevelPath(dir, name string) string
- func LoadAsset(path string) (*asset.Asset, error)
- func LoadAssetFS(fsys fs.FS, dir, ref string) (*asset.Asset, error)
- func LoadConfig(path string) config.Config
- func LoadLevel(path string) (*level.Level, error)
- func LoadLevelFS(fsys fs.FS, dir, name string) (*level.Level, error)
- func OSFS() fs.FS
- func ParseAsset(src string) (*asset.Asset, error)
- func ParseChunk(src string) (cx, cy int, walls []asset.Layer, spawns []level.Spawn, err error)
- func ParseConfig(src string) (config.Config, error)
- func ParseLevel(src string) (*level.Level, error)
- func RecordBestTime(path, mapName string, ticks int) (best int, record bool, err error)
- func RecordHighScore(path string, score int) (best int, record bool, err error)
- func SaveAsset(path string, a *asset.Asset) error
- func SaveAudio(path string, volume float64, muted bool) error
- func SaveConfig(path string, c config.Config) error
- func SaveLevel(path string, l *level.Level) error
Constants ¶
const ( ExtAsset = ".lfa" // one drawable object: a ship, a weapon, a power-up ExtLevel = ".lfm" // one stage )
File extensions. The syntax is Filo, but the extension is app-specific (a plain .filo is any Filo program) so the OS can associate them and the editor's open dialog can filter by document type.
const ExtChunk = ".lfc"
ExtChunk is the file extension for a persisted procedural chunk.
const ExtConfig = ".filo"
ExtConfig is the config file extension (a denshi-style user script).
Variables ¶
This section is empty.
Functions ¶
func AssetPath ¶
AssetPath resolves an asset REFERENCE — a bare name such as "turret", the way a level and the procedural generator write it — to a file inside dir. Documents name things; only the loader knows where they live and what they are called on disk. Three separate conventions for this had grown (relative to the cwd, relative to the map directory, hardcoded to "gameassets/"), which is why running the game from another working directory used to break spawns but not the horde.
func ConfigPath ¶
ConfigPath is the per-user settings file (~/.config/linefire/config.filo or the OS equivalent). An error means the platform has no user config dir; the caller skips persistence and plays with defaults.
func EmitAsset ¶
EmitAsset renders an asset as Filo text that ParseAsset reads back identically. The round trip is the contract the editor rests on: a lossy save destroys the author's work, so filoio_test walks every real asset in gameassets and proves it.
func EmitConfig ¶
EmitConfig renders a config as Filo text that ParseConfig reads back identically. The best times are written in sorted key order so a rewrite produces a stable diff.
func LoadAssetFS ¶
LoadAssetFS reads and validates the asset named ref (a bare name such as "turret") from dir within fsys. It is the fs.FS twin of LoadAsset, sharing ParseAsset.
func LoadConfig ¶
LoadConfig reads the settings, falling back to defaults when the file is missing, unreadable, unparseable or out of range — settings must never stop the game from starting. This is the one place the degradation policy lives.
func LoadLevelFS ¶
LoadLevelFS reads and validates the map named name (a file stem) from dir within fsys. It is the fs.FS twin of LoadLevel, sharing ParseLevel.
func OSFS ¶
OSFS returns an fs.FS backed directly by the operating system filesystem, the default the game uses when no embedded bundle is supplied.
func ParseAsset ¶
ParseAsset evaluates Filo source into a validated asset. Exported so the editor can parse an in-memory buffer, and so tests need no file.
func ParseChunk ¶
ParseChunk evaluates Filo source into one generated tile.
func ParseConfig ¶
ParseConfig evaluates Filo source into a config. It does not apply defaults or clamp ranges — that is config.Load's job, so the degradation policy lives in one place.
func ParseLevel ¶
ParseLevel evaluates Filo source into a validated level.
func RecordBestTime ¶
RecordBestTime stores ticks as mapName's best clear time when it beats the stored one (or there is none). Times below config.MinBestTicks are rejected as implausible. Returns the best time now and whether this run set a record. Read-modify-write.
func RecordHighScore ¶
RecordHighScore stores score as the new HI score when it beats the stored one. Returns the high score now and whether this run set a record. Read-modify-write, so a score change never wipes the audio settings or best times.
func SaveAudio ¶
SaveAudio persists only the audio settings, preserving every other field (so a volume change never wipes the best times). Read-modify-write.
func SaveConfig ¶
SaveConfig writes the settings, creating the directory on first use.
Types ¶
This section is empty.