mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-16 00:02:23 +02:00
92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# RFC 0008 — Runtime mod option schema export
|
|
|
|
## Status
|
|
|
|
Proposed. Engine: `src/mods/Loader.lua`. Tests:
|
|
`tests/mod_loader_tests.lua`. This RFC defines an optional filesystem
|
|
contract; it does not require a native launcher or any other consumer.
|
|
|
|
## Motivation
|
|
|
|
A native launcher may want to present settings for installed mods before it
|
|
starts the game. Running every mod's entry chunk in that launcher just to
|
|
discover its settings would duplicate engine behavior and give the launcher
|
|
an unnecessary code-execution surface. The engine already has the authoritative
|
|
runtime schemas after mod loading, so it can publish a data-only snapshot for
|
|
platform shells that want one.
|
|
|
|
## The exact contract
|
|
|
|
After the mod loader has finished running entry chunks, it may write
|
|
`mod_option_schemas.json` beside `options.lua` in the same filesystem. The
|
|
document is a snapshot of the current boot; it is not a second settings store
|
|
and does not change how option values are read or written.
|
|
|
|
Version 1 has this shape:
|
|
|
|
```json
|
|
{
|
|
"schema_version": 1,
|
|
"mods": {
|
|
"example": [
|
|
{"key":"enabled","type":"toggle","label":"Enabled","default":true},
|
|
{"key":"mode","type":"choice","label":"Mode","default":"safe",
|
|
"choices":[["Safe","safe"],["Fast","fast"]]},
|
|
{"key":"rate","type":"number","label":"Rate","default":5,
|
|
"min":0,"max":10,"step":1},
|
|
{"key":"name","type":"text","label":"Name","default":"","maxLen":12}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
`mods` is keyed by mod id. Its rows come from the runtime
|
|
`mod.options:define` schema, or from the legacy manifest `options_schema` file
|
|
when the runtime schema is absent. The supported row types are `toggle`,
|
|
`choice`, `number`, and `text`. Their optional fields retain the meanings
|
|
established by the existing in-game option UI: choices are `[label, value]`
|
|
pairs, numeric rows may provide `min`, `max`, and `step`, and text rows may
|
|
provide `maxLen`.
|
|
|
|
Only mods that are enabled and successfully loaded in the current boot are
|
|
included. A disabled or failed mod must not contribute rows. If an older
|
|
snapshot exists and the current boot has no schema-bearing mods, the producer
|
|
overwrites it with `{"schema_version":1,"mods":{}}`; this prevents stale
|
|
settings rows from surviving a disable or load failure. A fresh mod-free boot
|
|
does not create the file, and a filesystem without write support is tolerated.
|
|
|
|
The producer writes the snapshot after entry chunks and the final load set
|
|
have been established. Consumers must treat the file as untrusted input and
|
|
must not execute anything from it.
|
|
|
|
## Compatibility and versioning
|
|
|
|
The contract is optional on both sides. A native consumer may be absent, and
|
|
the engine continues normally if the file cannot be written. A native
|
|
consumer is not required to render, validate, or persist every supported row;
|
|
it may ignore an unknown row type or optional field.
|
|
|
|
For compatibility with files produced by the original unversioned prototype,
|
|
a missing `schema_version` means version 1. Consumers must ignore documents
|
|
with a newer version rather than guessing at their shape. Producers must bump
|
|
the version whenever they change the document shape or the meaning of an
|
|
existing field. Version 1 is therefore the legacy unversioned format as well
|
|
as the explicitly versioned format shown above.
|
|
|
|
## Migration note
|
|
|
|
Nothing. Existing mods, option values, and the in-game options UI are
|
|
unchanged. Platforms that do not consume `mod_option_schemas.json` have no
|
|
new integration requirement.
|
|
|
|
## Parity tests
|
|
|
|
`tests/mod_loader_tests.lua` verifies the explicit version, runtime and legacy
|
|
row round-tripping, enabled/disabled filtering, failed-mod filtering,
|
|
stale-snapshot clearing, and tolerance of a read-only filesystem.
|
|
|
|
## Deprecation etiquette
|
|
|
|
Nothing is deprecated. The unversioned file form remains readable as legacy
|
|
version 1; new producers write the explicit `schema_version` field.
|