read method
Reads the config, or hands back defaults.
Never throws. A missing document is the first run; an unreadable one is a disk that filled up mid-write or a hand edit that lost a brace, and in every one of those cases starting the game with default settings beats refusing to start. What is lost is a player's bindings, which is a bad day; what is avoided is a game that cannot be launched, which is a bug report nobody can act on.
Implementation
GameConfig read() {
final text = storage.read(_name);
if (text == null) return GameConfig();
try {
final json = jsonDecode(text);
if (json is! Map<String, Object?>) {
// **This one said nothing at all**, which is worse than the `catch`
// below: a document that parses as JSON and is not an object — a
// stored `null`, a `[]`, a truncated write on a platform where the
// atomic rename did not apply — went back as defaults with no word
// anywhere, so a player whose bindings had just been silently reset
// had nothing to report. `SaveFile.read` got this right next door and
// says so in its own comment; the lesson did not cross the file.
onIssue(
Issue('settings: the document is not an object, using defaults'),
);
return GameConfig();
}
return GameConfig.fromJson(json);
} catch (error) {
onIssue(Issue('settings: could not be read, using defaults ($error)'));
return GameConfig();
}
}