Add The Frontier, a second setting, and a picker to choose between them
Cold Fork is a freight yard: 29 events across two stages, a four-day cycle, and its own relationship and skill vocabulary. src/engine/ was not touched. Adding it needed three changes outside the engine: one save slot per pack, app.js holding the current pack, and turn.js no longer naming the mailroom (DECISIONS #34). build.js now handles imports wrapped across lines. A conformance suite runs over every registered pack. DECISIONS #35 records three calls on open questions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RxdJFbLq1rBKsUeticGV1g
This commit is contained in:
co-authored by
Claude Opus 5
parent
4957c24e31
commit
7f20be83e8
+30
-11
@@ -210,19 +210,38 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
const runs = byRun(entries);
|
||||
console.log(`${entries.length} turns logged across ${runs.size} run${runs.size === 1 ? '' : 's'} ` +
|
||||
`(pack ${entries[0].pack_id} ${entries[0].pack_version ?? ''})`.trimEnd());
|
||||
for (const [seed, run] of runs) {
|
||||
const stages = [...new Set(run.map((e) => e.stage))];
|
||||
console.log(` seed ${seed}: ${run.length} turns, ${stages.join(' → ')}`);
|
||||
// One log can hold turns from more than one setting, and pooling them would
|
||||
// put a mailroom and a freight yard in the same repetition table. The same
|
||||
// rule as the run boundary in DECISIONS #30, a level up: every statistic
|
||||
// here is per pack, and a log is not one sequence.
|
||||
const byPack = new Map();
|
||||
for (const entry of entries) {
|
||||
const id = entry.pack_id ?? 'unknown';
|
||||
if (!byPack.has(id)) byPack.set(id, []);
|
||||
byPack.get(id).push(entry);
|
||||
}
|
||||
|
||||
reportRepetition(runs);
|
||||
reportChoices(entries);
|
||||
reportGates(entries);
|
||||
reportFeedback(entries);
|
||||
console.log('');
|
||||
if (byPack.size > 1) {
|
||||
console.log(`${entries.length} turns logged across ${byPack.size} settings.`);
|
||||
}
|
||||
|
||||
for (const [packId, packEntries] of byPack) {
|
||||
const runs = byRun(packEntries);
|
||||
console.log(
|
||||
`${packEntries.length} turns logged across ${runs.size} run${runs.size === 1 ? '' : 's'} ` +
|
||||
`(pack ${packId} ${packEntries[0].pack_version ?? ''})`.trimEnd(),
|
||||
);
|
||||
for (const [seed, run] of runs) {
|
||||
const stages = [...new Set(run.map((e) => e.stage))];
|
||||
console.log(` seed ${seed}: ${run.length} turns, ${stages.join(' → ')}`);
|
||||
}
|
||||
|
||||
reportRepetition(runs);
|
||||
reportChoices(packEntries);
|
||||
reportGates(packEntries);
|
||||
reportFeedback(packEntries);
|
||||
console.log('');
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
|
||||
+5
-1
@@ -79,7 +79,11 @@ async function collect(entryPath, seen = new Map()) {
|
||||
const source = await readFile(entryPath, 'utf8');
|
||||
seen.set(entryPath, null); // reserve the slot before recursing
|
||||
|
||||
const specifiers = [...source.matchAll(/^[ \t]*import\s.*?from\s*['"]([^'"]+)['"];?[ \t]*$/gm)]
|
||||
// `[\s\S]*?` rather than `.*?`: a destructured import may be wrapped across
|
||||
// several lines, and `transform` below already rewrites those — a scan that
|
||||
// missed them produced a bundle with a __require for a module that was never
|
||||
// collected, which only failed when the bundled game was run.
|
||||
const specifiers = [...source.matchAll(/^[ \t]*import\s[\s\S]*?from\s*['"]([^'"]+)['"];?[ \t]*$/gm)]
|
||||
.map((match) => match[1])
|
||||
.filter((specifier) => specifier.startsWith('.'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user