A standalone Three.js application for developing the garden hall's architecture. The interface contains camera controls and a screenshot button; proportions are defined in the source code. This is an editable structural model with schematic materials, not a finished palace asset. Offices are enclosed, unfurnished rooms. The conservatory has beds, shaped soil and paths; ground-floor planting, further decoration, gallery stairs and office furnishings are future layers.
Requires Node.js 20.19+ or 22.12+. From this folder:
npm install
npm start
Open the local URL printed by Vite. Use npm run build for a production build, npm run preview to view that build, and npm test for the geometric invariants.
Edit src/layout/garden-map.png in an image editor and save it as PNG. The current map is 960 × 1200 pixels, covering 48 × 60 metres at 20 pixels per metre. Top is the throne end; bottom is the entrance. Keep its 4:5 aspect ratio and the same framing.
| Colour | Meaning |
|---|---|
Brown, #65513d | A planting bed with a stone edge and shaped soil. |
Sand, #c9c0aa | Garden paving. Paint this through a bed to split it, or inside one to create an enclosed paved opening. |
Light grey, #e0e2d9 | Existing plain floor. |
Teal, #5b9b9e | Reference for the existing water. This colour does not remodel the basin. |
Use solid colours and broad strokes. The importer tolerates modest edge antialiasing, simplifies pixel stair-steps and ignores regions smaller than 0.35 m². Give beds enough width for their 18 cm stone edging. Transparency is treated as unpainted floor. This is a plan mask, not a photograph or shaded paintover.
While npm start is running, saving the PNG or its configuration recompiles the layout and reloads the scene. No additional buttons are needed. npm run layout compiles it manually; tests and production builds compile it automatically. Invalid images report an error and leave the previous generated layout intact.
The pool, island foundation and bridge structures remain reusable geometry components. The importer clips bed shapes to their dry surfaces and preserves full-width bridge routes and gallery circulation. Teal is a painting guide for these fixed structures; repainting it alone does not move water or bridges. Soil crests are separately editable in src/layout/garden-map.json, so changing a bed outline does not pull its high point toward the centre.
The compiler is scripts/compile-garden-map.mjs; bitmap contour tracing is in scripts/map-contours.mjs. The generated src/layout/garden-layout.json is a reproducible mesh input, not the editing source. The application uses polygon-clipping for intersections and pngjs to read the PNG during development and builds.
Edit DEFAULTS and HALL in src/model.js to change the building. There are no building controls in the interface.
The central floor is 48 × 60 m, doubled from the original 24 m width. Both lower galleries move outward; the 5.5 m upper balconies retain their depth and the glass roof spans 59 m. There are still two occupied storeys at 5 m intervals. These are working dimensions, not setting canon or a certified structural design.
src/components/office-room.js: the single office-room definition. Its OFFICE dimensions and mesh assembly supply all 32 rooms, eight along each side of each floor. Windows are 4.125 m wide, 50% wider than the original 2.75 m. Each room has actual side/back walls, a floor, ceiling, a fitted door and transparent glazing. Both levels use the same geometry; the upper level uses a different trim material.src/components/branched-pillar.js: one tapered shaft and two curved branches, repeated ten times. Branches adapt to the roof profile while the feet stay at the lower office boundaries. Both sides share the same component geometry, mirrored through placement.src/components/flower-box.js: a hollow stone trough, soil, stems, leaves and flowers, repeated 32 times along the upper balconies. Leaves and blooms use instanced meshes; editing this component updates every box.src/components/conservatory-garden.js: turns the compiled map polygons into shared planting-bed components and solid paving. Polygon intersections keep soil on dry land and out of the gallery and bridge routes. Paving is cut around the actual rounded bed outlines, including enclosed paths.src/components/bridge-approach.js: four gallery approaches with the same width and direction as their crossing. The central crossing is one logical route containing two physical bridge spans and a level island path.src/components/planting-bed.js: the common bed component, with a consistent corner treatment that preserves straight edges, stone retaining edges and unplanted soil. Changing the component updates every ground-floor bed.src/components/soil-mound.js: smooth soil surfaces from explicit crest profiles, also used by the island. Each bed exposes soilHeightAt(x, z) for positioning future plants on its contours.src/components/garden-island.js: the solid island foundation and level landing. Beds on it are generated from the same map as the surrounding banks.src/components/water-channel.js: the channel outline, enclosed stone basin and coping. Inner faces point into the water; the solid bed extends under the full wall thickness. The same outline cuts the ground slab and clips its paving joints. This ground-floor layer stays fixed when the upper galleries change.src/components/water-surface.js: animated water shader with overlapping travelling ripples, view-dependent reflections of the actual hall, refraction of the submerged stonework, a shallow jade tint and sunlight glints. One pair of 1024-pixel render targets serves the whole channel; the island remains a real hole in the surface. Three.js Reflector/Refractor provide the capture cameras, and their targets are disposed with the component.src/components/footbridge.js: the reusable unrailed stone bridge, with a variable span. The two island spans share their deck geometry; the entrance span uses the same component at its original 6.2 m length.src/components/throne-setting.js: the throne surround, dais, simple medallion and chair as one component, with separate named groups for later editing. THRONE holds its working dimensions.src/components/throne-dais.js: concentric semicircular stone steps and curved silver inlays, sharing one radius and tread profile.src/components/horizontal-solid.js: common extrusion and inward-facing hole geometry for the floor, basin and dais.src/components/throne-emblem.js: loads the imagegen colour texture and grayscale bump map onto the medallion and manages their lifetime. Shallow relief responds to scene lighting; the emblem's branches and coloured lights are in the images, not individual meshes.src/assets/morlenciri-throne-emblem-v1.png: generated silver emblem texture based on the author's logo concept; the adjacent .prompt.md records the source and exact prompt.src/assets/morlenciri-throne-emblem-bump-v1.png: generated height map based on the colour texture, sampled as linear data with a 0.055 m bump scale. The adjacent .prompt.md records its source and exact prompt.src/components/skybox.js: the panoramic sky and reflection environment. The Thessia-inspired city faces the throne end (-Z); the rest of the horizon is wooded landscape. Change SKYBOX.rotation to turn the backdrop and its sunlight together. The sky stays at infinity as the camera moves.src/assets/sylir-city-sky-v3.webp: the current 3200 × 1600 backdrop, stitched from four newly generated overlapping strips. Native strips are about 972 × 1619; the panorama adds native detail rather than enlarging the old image. The city and landscape are a visual study, not a canonical map of Sylir. The source strips, exact prompts, PNG master and stitch record are preserved in ../output/imagegen/sylir-skybox-strips-v1/.scripts/stitch-skybox-strips.mjs: joins the four 108-degree strips with 18-degree overlaps. FFmpeg prepares two frequency bands; narrow minimum-error seams preserve fine detail while broader blending smooths color differences. The polar caps converge to shared colors. The lossless WebP is bundled with the app; FFmpeg is only needed to regenerate it.scripts/prepare-skybox.mjs: offline FFmpeg preparation of the original panorama. It blends the wrap edges and resamples to 4096 × 2048 with light sharpening. Resampling does not add native detail to the 1774 × 887 source. FFmpeg is needed only to regenerate the asset, not to run the app.src/model.js: geometry, fixed dimensions, adjustable parameters. The ground-floor group is constructed once and never rebuilt by parameter changes.src/main.js: rendering, lighting, navigation and controls.src/camera-controls.js: independent camera translation and yaw/pitch navigation.src/screenshot.js: captures the rendered canvas and downloads a PNG without the interface.src/style.css: application interface.tests/model.test.js: fixed-ground invariants, upper-wall offsets, roof alignment, frame spacing and input validation.tests/office-room.test.js: room tiling, shared component resources, window width and clear lines of sight through the glazing into the enclosed interior.tests/branched-pillar.test.js: alternate-boundary placement, truss contact, balcony headroom, and shared component geometry.tests/water-channel.test.js: rays verify the real floor opening, submerged bed, inward-facing sides, closed ends, solid underside, dry banks and island; bridge checks verify shared decks, both-bank support, water clearance and flush floor connections.tests/throne-setting.test.js: verifies that the dais clears the water, supports the chair, leaves side passages and keeps the surround beneath the roof.tests/conservatory-garden.test.js: checks waterside soil, gallery and bridge clearances, gentle rises and retaining edges, and keeps paving out of the basin. tests/garden-map.test.js checks contour topology, painted cut-throughs and enclosed paths, protected crossings, and the flat island landing.Repeated architecture should come from components in src/components/, not separately edited copies. Edit the component source, and the dev server rebuilds all instances. Office copies share their geometry and materials; their row placement is handled by the hall model. The 7.5 m office module divides the unchanged 60 m hall into eight rooms per row. Pilasters and roof-support posts meet module boundaries so they do not cut through the wider windows.
Keep the interface simple and limited to camera positioning. Add buttons only when they have a concrete testing benefit. Do not restore the lower/upper gallery legend.
This folder has its own package and lockfile, and is excluded from the parent Eleventy site. It does not modify the main site's JavaScript dependencies.
Visual references and image studies are in ../output/imagegen/palace-visual-language-2026-09-18/; the design record is ../docs/manual/The Palace on Sylir - Visual Language.md. Rejected stepped ground-floor versions are not geometry references.
Technical references: Three.js documentation and Vite.