Restructure project as Worldshaper

This commit is contained in:
Andraxion 2026-06-26 20:30:30 -04:00
parent ab891a315c
commit b4dbd4ee8e
583 changed files with 279 additions and 189269 deletions

View file

@ -38,15 +38,12 @@ const dataRoot = path.resolve(__dirname, "data");
const catalogMetaPath = path.join(dataRoot, "catalog_meta.json");
const dialogueNodeMetaPath = path.join(dataRoot, "dialogue_node_meta.json");
const editorSettingsPath = path.join(dataRoot, "editor_settings.json");
const docsRoot = path.resolve(__dirname, "docs");
const wikiPath = path.join(docsRoot, "index.html");
const dialogueBuilderPath = path.join(docsRoot, "dialogue-builder.html");
const imagesCatalogPath = path.join(contentRoot, "images.json");
const legacyTilesCatalogPath = path.join(contentRoot, "tiles.json");
const legacySpritesCatalogPath = path.join(contentRoot, "sprites.json");
const recentSaveEvents = [];
const DEFAULT_MAP_EDITOR_THEME_PRESET = "azure";
const MAP_EDITOR_THEME_PRESET_IDS = new Set(["azure", "verdant", "ember", "amethyst"]);
const DEFAULT_WORLDSHAPER_THEME_PRESET = "azure";
const WORLDSHAPER_THEME_PRESET_IDS = new Set(["azure", "verdant", "ember", "amethyst"]);
const contentMap = {
npcs: { file: "npcs.json", root: "npcs" },
@ -147,16 +144,16 @@ function normalizeHeightBlurStep(value, fallback = 0.1) {
return Math.max(0, Math.min(1, normalized));
}
function normalizeMapEditorThemePreset(value) {
function normalizeWorldshaperThemePreset(value) {
const normalized = String(value || "").trim().toLowerCase();
return MAP_EDITOR_THEME_PRESET_IDS.has(normalized) ? normalized : DEFAULT_MAP_EDITOR_THEME_PRESET;
return WORLDSHAPER_THEME_PRESET_IDS.has(normalized) ? normalized : DEFAULT_WORLDSHAPER_THEME_PRESET;
}
function createDefaultEditorSettings() {
return {
schemaVersion: 1,
mapEditor: {
themePreset: DEFAULT_MAP_EDITOR_THEME_PRESET,
worldshaperStudio: {
themePreset: DEFAULT_WORLDSHAPER_THEME_PRESET,
engineOverrides: [],
},
};
@ -205,14 +202,14 @@ function normalizeEditorSettings(payload) {
const source = payload && typeof payload === "object" && !Array.isArray(payload)
? payload
: fallback;
const mapEditor = source.mapEditor && typeof source.mapEditor === "object" && !Array.isArray(source.mapEditor)
? source.mapEditor
: fallback.mapEditor;
const worldshaperStudio = source.worldshaperStudio && typeof source.worldshaperStudio === "object" && !Array.isArray(source.worldshaperStudio)
? source.worldshaperStudio
: fallback.worldshaperStudio;
return {
schemaVersion: typeof source.schemaVersion === "number" ? source.schemaVersion : fallback.schemaVersion,
mapEditor: {
themePreset: normalizeMapEditorThemePreset(mapEditor.themePreset),
engineOverrides: normalizeEditorEngineOverrides(mapEditor.engineOverrides),
worldshaperStudio: {
themePreset: normalizeWorldshaperThemePreset(worldshaperStudio.themePreset),
engineOverrides: normalizeEditorEngineOverrides(worldshaperStudio.engineOverrides),
},
};
}
@ -261,23 +258,6 @@ function createDefaultColorCatalogEntries() {
app.use(express.json({ limit: "10mb" }));
app.use(express.static(path.join(__dirname, "dist")));
app.use("/wiki-assets", express.static(docsRoot));
app.get("/wiki", (_req, res) => {
try {
res.sendFile(wikiPath);
} catch (err) {
res.status(500).send(`Failed to load wiki: ${String(err)}`);
}
});
app.get("/dialogue-builder", (_req, res) => {
try {
res.sendFile(dialogueBuilderPath);
} catch (err) {
res.status(500).send(`Failed to load dialogue builder prototype: ${String(err)}`);
}
});
function resolveContent(type) {
const entry = contentMap[type];
@ -2684,10 +2664,11 @@ app.post("/api/catalog-meta", (req, res) => {
});
app.listen(port, host, () => {
console.log(`Content editor V2 API running at http://${host}:${port}`);
console.log(`Worldshaper API running at http://${host}:${port}`);
console.log(`[paths] contentRoot=${contentRoot}`);
console.log(`[paths] imagesRoot=${imagesRoot}`);
if (!fs.existsSync(contentRoot)) {
console.warn(`[paths] content root does not exist yet. Create: ${contentRoot}`);
}
});