Dev console finds materials by display name from the real material table (t82)
This commit is contained in:
@@ -6,6 +6,18 @@ open or not verified. Keep each entry short; the git history has the details.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2026-10-29: t82 dev console material table lookup (Codex)
|
||||||
|
|
||||||
|
- Display-name discovery scans MD ids 1..NMAT-1 through devGiveable; DEV_MATERIALS
|
||||||
|
supplies internal aliases. Listing, suggestions and Tab share the real-table list.
|
||||||
|
- Added regression removing CUORE temporarily (restored in finally): lookup/give,
|
||||||
|
prefixes, filtering, suggestions and completion failed before the fix and pass after.
|
||||||
|
Corrected the new prefix expectation because Copper ore vein also matches.
|
||||||
|
- Files: src/sim/devconsole.js, test/t_dev_console.js, tasks/t82_dev_console_finds.md
|
||||||
|
and this log. Node console suite and python3 test/run_all.py passed (log:
|
||||||
|
/tmp/t82-headless.log). Browser/screenshots skipped at the owner's request; game
|
||||||
|
playtesting remains open. No simulation/worldgen changes; no commit.
|
||||||
|
|
||||||
## 2026-10-28: t94 dev console discovery and keyboard ease of use (Codex)
|
## 2026-10-28: t94 dev console discovery and keyboard ease of use (Codex)
|
||||||
|
|
||||||
- Added case/space-insensitive material lookup, three close giveable suggestions and
|
- Added case/space-insensitive material lookup, three close giveable suggestions and
|
||||||
|
|||||||
+11
-5
@@ -26,7 +26,13 @@ function devError(text) { return Object.assign([text], { error: true }); }
|
|||||||
function devName(text) { return text.toLowerCase().replace(/\s+/g, ''); }
|
function devName(text) { return text.toLowerCase().replace(/\s+/g, ''); }
|
||||||
function devGiveable(id) { return id !== EMPTY && PH[id] !== PH_GAS && (PH[id] !== PH_SOLID || !!YLD[id]); }
|
function devGiveable(id) { return id !== EMPTY && PH[id] !== PH_GAS && (PH[id] !== PH_SOLID || !!YLD[id]); }
|
||||||
function devMaterialList(text = '') {
|
function devMaterialList(text = '') {
|
||||||
return Object.entries(DEV_MATERIALS).filter(([key, id]) => devGiveable(id) && (devName(key).includes(devName(text)) || devName(MD[id].name).includes(devName(text))));
|
const keys = new Map(Object.entries(DEV_MATERIALS).map(([key, id]) => [id, key]));
|
||||||
|
const list = [], name = devName(text);
|
||||||
|
for (let id = 1; id < NMAT; id++) {
|
||||||
|
const key = keys.get(id) || '';
|
||||||
|
if (devGiveable(id) && (devName(key).includes(name) || devName(MD[id].name).includes(name))) list.push([key, id]);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
// Edit distance is only used on a console error, never in the simulation tick.
|
// Edit distance is only used on a console error, never in the simulation tick.
|
||||||
function devDistance(a, b) {
|
function devDistance(a, b) {
|
||||||
@@ -83,12 +89,12 @@ function devComplete(text, previous) {
|
|||||||
const DEV_MATERIALS = { EMPTY, GRASS, DIRT, LDIRT, SAND, GRAVEL, CLAY, STONE, GRANITE, BASALT, WOOD, LEAVES, COALV, COAL, CUV, CUORE, FEV, FEORE, ASH, SLAG, BRICK, GLASS, COPPER, IRON, STEEL, WATER, MAGMA, MCU, MFE, MST, MGL, STEAM, SMOKE, FIRE, BELTL, BELTR, SHAFT, GATE, HULL, SPRING, RSTONE, RGRAN, RBAS, LCLAY, LWOOD, RBRICK, CULLET, SCRCU, SCRFE, SCRST, BARCU, BARFE, BARST, ACORN, CHARCOAL, SNOW, ICE, SNV, SNORE, TIN, MSN, SCRSN, BARSN, ZNV, ZNORE, ZINC, MZN, SCRZN, BARZN, AGV, AGORE, SILVER, MAG, SCRAG, BARAG, AUV, AUORE, GOLD, MAU, SCRAU, BARAU, BRONZE, MBZ, SCRBZ, BARBZ, BRASS, MBS, SCRBS, BARBS, DOCKW, MSLAG, PIPE, BARGL, CUTST, BARSB, GRINDER, SAWB, PLANK, PRESSB, GREENB, BARBR, RACKB };
|
const DEV_MATERIALS = { EMPTY, GRASS, DIRT, LDIRT, SAND, GRAVEL, CLAY, STONE, GRANITE, BASALT, WOOD, LEAVES, COALV, COAL, CUV, CUORE, FEV, FEORE, ASH, SLAG, BRICK, GLASS, COPPER, IRON, STEEL, WATER, MAGMA, MCU, MFE, MST, MGL, STEAM, SMOKE, FIRE, BELTL, BELTR, SHAFT, GATE, HULL, SPRING, RSTONE, RGRAN, RBAS, LCLAY, LWOOD, RBRICK, CULLET, SCRCU, SCRFE, SCRST, BARCU, BARFE, BARST, ACORN, CHARCOAL, SNOW, ICE, SNV, SNORE, TIN, MSN, SCRSN, BARSN, ZNV, ZNORE, ZINC, MZN, SCRZN, BARZN, AGV, AGORE, SILVER, MAG, SCRAG, BARAG, AUV, AUORE, GOLD, MAU, SCRAU, BARAU, BRONZE, MBZ, SCRBZ, BARBZ, BRASS, MBS, SCRBS, BARBS, DOCKW, MSLAG, PIPE, BARGL, CUTST, BARSB, GRINDER, SAWB, PLANK, PRESSB, GREENB, BARBR, RACKB };
|
||||||
function devMaterial(name) {
|
function devMaterial(name) {
|
||||||
name = devName(name);
|
name = devName(name);
|
||||||
const ids = Object.entries(DEV_MATERIALS);
|
const internal = Object.entries(DEV_MATERIALS).find(([key]) => devName(key) === name);
|
||||||
const internal = ids.find(([key]) => devName(key) === name);
|
|
||||||
if (internal) return internal[1];
|
if (internal) return internal[1];
|
||||||
|
const ids = devMaterialList();
|
||||||
const exact = ids.filter(([, id]) => devName(MD[id].name) === name);
|
const exact = ids.filter(([, id]) => devName(MD[id].name) === name);
|
||||||
const matches = [...new Set((exact.length ? exact : ids.filter(([key, id]) => devName(key).startsWith(name) || devName(MD[id].name).startsWith(name))).map(([, id]) => id))];
|
const matches = [...new Set((exact.length ? exact : ids.filter(([key, id]) => devName(key).startsWith(name) || devName(MD[id].name).startsWith(name))).map(([, id]) => id))];
|
||||||
return matches.length === 1 ? matches[0] : matches.length ? `Ambiguous material: ${matches.map(id => MD[id].name + ' (' + ids.find(([, m]) => m === id)[0] + ')').join(', ')}.` : 'Unknown material. Did you mean: ' + devSuggestions(name) + '? Use materials to list names.';
|
return matches.length === 1 ? matches[0] : matches.length ? `Ambiguous material: ${matches.map(id => { const key = ids.find(([, m]) => m === id)[0]; return MD[id].name + (key ? ' (' + key + ')' : ''); }).join(', ')}.` : 'Unknown material. Did you mean: ' + devSuggestions(name) + '? Use materials to list names.';
|
||||||
}
|
}
|
||||||
function devCommand(text, cursor) {
|
function devCommand(text, cursor) {
|
||||||
if (typeof text !== 'string' || !text.trim()) return ['Type help to list commands.'];
|
if (typeof text !== 'string' || !text.trim()) return ['Type help to list commands.'];
|
||||||
@@ -105,7 +111,7 @@ function devCommand(text, cursor) {
|
|||||||
return ['Usage: ' + def[0], 'Example: ' + def[1]];
|
return ['Usage: ' + def[0], 'Example: ' + def[1]];
|
||||||
}
|
}
|
||||||
if (cmd === 'materials') {
|
if (cmd === 'materials') {
|
||||||
const lines = devMaterialList(args.join(' ')).map(([key, id]) => MD[id].name + ' (' + key + ')');
|
const lines = devMaterialList(args.join(' ')).map(([key, id]) => MD[id].name + (key ? ' (' + key + ')' : ''));
|
||||||
return lines.length ? lines : ['No matching materials.'];
|
return lines.length ? lines : ['No matching materials.'];
|
||||||
}
|
}
|
||||||
if (cmd === 'clear') return args.length ? usage() : Object.assign([], { clear: true });
|
if (cmd === 'clear') return args.length ? usage() : Object.assign([], { clear: true });
|
||||||
|
|||||||
@@ -74,6 +74,24 @@ check('give turns rock into its rubble and says so', run(`(() => { enableDevCons
|
|||||||
check('give refuses things that cannot be in a bag', run(`(() => { enableDevConsole(); const out = devCommand('give steam 5').join(' '); return /cannot go in the bag/.test(out) && bag[STEAM] === 0; })()`));
|
check('give refuses things that cannot be in a bag', run(`(() => { enableDevConsole(); const out = devCommand('give steam 5').join(' '); return /cannot go in the bag/.test(out) && bag[STEAM] === 0; })()`));
|
||||||
|
|
||||||
check('material matching ignores spaces and case', run("devMaterial('CoPpErOrE') === CUORE && devMaterial('copper bar') === BARCU"));
|
check('material matching ignores spaces and case', run("devMaterial('CoPpErOrE') === CUORE && devMaterial('copper bar') === BARCU"));
|
||||||
|
const withoutAlias = run(`(() => {
|
||||||
|
const saved = DEV_MATERIALS.CUORE;
|
||||||
|
delete DEV_MATERIALS.CUORE;
|
||||||
|
try {
|
||||||
|
const before = bag[CUORE];
|
||||||
|
devCommand('give CoPpEr OrE 7');
|
||||||
|
return {
|
||||||
|
lookup: devMaterial('CoPpEr OrE') === CUORE && bag[CUORE] === before + 7,
|
||||||
|
prefix: devMaterial('copperor').startsWith('Ambiguous material:') && devMaterial('copperor').includes(', Copper ore.'),
|
||||||
|
list: devMaterialList('CoPpErOrE').some(([, id]) => id === CUORE),
|
||||||
|
suggestions: devSuggestions('coperore').includes(MD[CUORE].name),
|
||||||
|
completion: devComplete('give copperore 25').matches.includes('give Copper ore 25')
|
||||||
|
};
|
||||||
|
} finally { DEV_MATERIALS.CUORE = saved; }
|
||||||
|
})()`);
|
||||||
|
for (const [feature, works] of Object.entries(withoutAlias)) {
|
||||||
|
check('display-name ' + feature + ' works without an internal alias', works);
|
||||||
|
}
|
||||||
check('unknown material suggests close giveable names', /Did you mean:.*Copper ore/i.test(command('give coperore')[0]));
|
check('unknown material suggests close giveable names', /Did you mean:.*Copper ore/i.test(command('give coperore')[0]));
|
||||||
check('materials lists giveable names with internal names', command('materials').some(s => /Copper ore.*CUORE/.test(s)) && !command('materials').some(s => /STEAM/.test(s)));
|
check('materials lists giveable names with internal names', command('materials').some(s => /Copper ore.*CUORE/.test(s)) && !command('materials').some(s => /STEAM/.test(s)));
|
||||||
check('materials filtering ignores spaces and case', command('materials CoPpErOrE').every(s => /Copper ore/i.test(s)) && command('materials copperore').some(s => /CUORE/.test(s)));
|
check('materials filtering ignores spaces and case', command('materials CoPpErOrE').every(s => /Copper ore/i.test(s)) && command('materials copperore').some(s => /CUORE/.test(s)));
|
||||||
|
|||||||
Reference in New Issue
Block a user