// Serializes a level data object (as produced by levelBuilder.js) into the // literal `export default {...}` JS module source text the game expects to // find in src/data/levels/levelNN.js. Numbers are emitted as plain scaled // literals rather than `N * WORLD_SCALE` expressions - levelBuilder.js has // already fully resolved them, and level03.js already sets precedent for a // level file built from computed literal points rather than hand-picked // base-unit expressions. function pointsLiteral(points, indent) { const lines = points.map((p) => `${indent} { x: ${p.x}, y: ${p.y} },`); return `[\n${lines.join('\n')}\n${indent}]`; } function terrainLiteral(terrain) { const segments = terrain.map((segment) => ` { points: ${pointsLiteral(segment.points, ' ')} },`); return `[\n${segments.join('\n')}\n ]`; } function rectLiteral(rect) { return `{ x: ${rect.x}, y: ${rect.y}, width: ${rect.width}, height: ${rect.height} }`; } // Smashable item placements (editor "Smashables" section) - one literal // object per item, same field order as levelBuilder.js emits them. function itemsLiteral(items) { if (!items || items.length === 0) return '[]'; const lines = items.map( (it) => ` { type: ${JSON.stringify(it.type)}, mode: ${JSON.stringify(it.mode)}, x: ${it.x}, y: ${it.y} },` ); return `[\n${lines.join('\n')}\n ]`; } export function exportLevelToSource(levelData) { const lines = [ '// Generated by editor.html - review before dropping into src/data/levels/.', 'export default {', ` id: ${JSON.stringify(levelData.id)},`, ` name: ${JSON.stringify(levelData.name)},`, ` description: ${JSON.stringify(levelData.description)},`, ` kidsAboard: ${levelData.kidsAboard},`, ` timeLimit: ${levelData.timeLimit},`, ` startPosition: { x: ${levelData.startPosition.x}, y: ${levelData.startPosition.y} },`, ` startAngle: ${levelData.startAngle},`, ` terrain: ${terrainLiteral(levelData.terrain)},`, ' obstacles: [],', // Only emitted when the level actually has items - keeps hand-authored // levels' exports byte-identical to before this feature existed. ...(levelData.items && levelData.items.length > 0 ? [` items: ${itemsLiteral(levelData.items)},`] : []), ` goal: ${rectLiteral(levelData.goal)},`, ` cameraBounds: ${rectLiteral(levelData.cameraBounds)},`, '};', '', ]; return lines.join('\n'); }