{ "demo": true, "settings": { "merge": { "companyName": "Neon Forge", "tagline": "We build games and the tools that ship them." } }, "data_tables": [ { "key": "contact_submissions", "name": "Contact Enquiries", "description": "Seeded contact-form submissions for the Neon Forge demo. A submission becomes a row here and emails the site admins.", "columns": [ { "key": "name", "label": "Name", "type": "text", "required": true }, { "key": "email", "label": "Email", "type": "email", "required": true }, { "key": "studio", "label": "Studio", "type": "text", "required": false }, { "key": "message", "label": "Message", "type": "text", "required": true } ] } ], "pages": [ { "slug": "/", "title": "Neon Forge", "template_key": "landing", "blocks": [ { "block_key": "hero", "title": "Hero", "slot": "main", "sort_order": 1, "content": { "template": "centered", "minHeight": "screen", "eyebrow": "Build 2.049", "headline": "Ship the impossible", "subheadline": "A game studio and the tools that ship it.", "description": "We build a rendering engine, live ops, and a build farm that never sleeps. Then we make games on top of it.", "ctaPrimary": { "text": "Get the SDK", "url": "/contact" }, "ctaSecondary": { "text": "Read the devlog", "url": "/blog" } } }, { "block_key": "feature-grid", "title": "What we ship", "slot": "main", "sort_order": 2, "content": { "eyebrow": "The stack", "heading": "One pipeline, end to end", "intro": "Engine, tooling, and live service. Built in house, shipped together.", "layout": "card", "columns": 3, "items": [ { "icon": "lucide:cpu", "title": "Render engine", "text": "Neon lighting, volumetric fog, and a deferred path tuned for night maps." }, { "icon": "lucide:terminal", "title": "Build farm", "text": "Shader caching across branches. Green builds in minutes, not hours." }, { "icon": "lucide:radio", "title": "Live ops", "text": "Ship events, patch balance, and roll back without a redeploy." } ] } }, { "block_key": "cyberpunk:roster_grid", "title": "The crew", "slot": "main", "sort_order": 3, "content": { "eyebrow": "The crew", "heading": "Who ships this", "intro": "A small team that builds the engine, the game, and the pipeline in between.", "members": [ { "name": "Nova Reyes", "handle": "@nova", "role": "Engine lead", "status": true }, { "name": "Kai Okafor", "handle": "@kaisdf", "role": "Graphics", "status": true }, { "name": "Sable Lin", "handle": "@sable", "role": "Live ops", "status": false }, { "name": "Juno Vale", "handle": "@juno", "role": "Gameplay", "status": true }, { "name": "Rin Castellano", "handle": "@rin", "role": "Tools", "status": true }, { "name": "Ash Mori", "handle": "@ash", "role": "Netcode", "status": false } ] } }, { "block_key": "cyberpunk:patch_notes", "title": "Patch notes", "slot": "main", "sort_order": 4, "content": { "heading": "Patch notes", "intro": "What changed, build by build.", "entries": [ { "version": "v2.049.0", "date": "2049.04.01", "tag": "FEATURE", "items": [ { "text": "Volumetric neon fog on all night maps." }, { "text": "Build farm caches shaders across branches." } ] }, { "version": "v2.048.3", "date": "2049.03.18", "tag": "FIX", "items": [ { "text": "Fixed a stall when hot-reloading materials." }, { "text": "Reduced desync on high-latency links." } ] }, { "version": "v2.048.0", "date": "2049.03.02", "tag": "BALANCE", "items": [ { "text": "Tuned dash cooldown from 4s to 3.2s." } ] } ] } }, { "block_key": "cta", "title": "CTA", "slot": "main", "sort_order": 5, "content": { "background": "band", "heading": "Start building tonight", "text": "Grab the SDK and ship your first build before the coffee runs out.", "primaryLabel": "Get the SDK", "primaryUrl": "/contact" } } ] }, { "slug": "/about", "title": "The studio", "template_key": "default", "blocks": [ { "block_key": "heading", "title": "Heading", "slot": "main", "sort_order": 1, "content": { "text": "The studio", "level": 1 } }, { "block_key": "rich-text", "title": "Story", "slot": "main", "sort_order": 2, "content": { "html": "

Neon Forge started as a build tool for a game that shipped late. The tool outlived the game. We kept building it, then built more games to prove it out.

Now we run both. The engine and live service on one side, the games that stress test them on the other. Everything we make, we run in production first.

" } }, { "block_key": "cyberpunk:code_neon", "title": "Quickstart", "slot": "main", "sort_order": 3, "content": { "language": "bash", "code": "npm install @neon-forge/sdk\nnpx neon-forge init my-game\nnpx neon-forge ship --stage prod", "copy": "on" } }, { "block_key": "divider", "title": "Divider", "slot": "main", "sort_order": 4, "content": { "variant": "line", "weight": "medium" } }, { "block_key": "quote", "title": "Quote", "slot": "main", "sort_order": 5, "content": { "style": "pull", "quote": "Build the tool. Ship the game. Repeat.", "attribution": "The studio" } } ] }, { "slug": "/blog", "title": "Devlog", "template_key": "blog-index", "blocks": [ { "block_key": "card", "title": "Post: Rain", "slot": "main", "sort_order": 1, "content": { "layout": "vertical", "title": "Making it rain", "text": "

How we built a dependency-free digital-rain effect that stays smooth at 60 fps.

", "link": "/blog/making-it-rain", "linkLabel": "Read on" } }, { "block_key": "card", "title": "Post: Shaders", "slot": "main", "sort_order": 2, "content": { "layout": "vertical", "title": "Caching shaders across branches", "text": "

Green builds in minutes. What we changed in the build farm and why.

", "link": "/blog/caching-shaders", "linkLabel": "Read on" } }, { "block_key": "card", "title": "Post: Netcode", "slot": "main", "sort_order": 3, "content": { "layout": "vertical", "title": "Netcode on bad links", "text": "

Cutting desync on 200ms connections without rewriting the sim.

", "link": "/blog/netcode-bad-links", "linkLabel": "Read on" } } ] }, { "slug": "/blog/making-it-rain", "title": "Making it rain", "template_key": "article", "parent_slug": "/blog", "blocks": [ { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Making it rain", "level": 1 } }, { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

The hero on our home page runs a digital-rain canvas. No libraries, no images, just a small script that draws falling glyphs.

The trick is to fade the last frame instead of clearing it. That leaves a trail. Cap the frame rate and it stays cheap, even on a laptop.

" } } ] }, { "slug": "/blog/caching-shaders", "title": "Caching shaders across branches", "template_key": "article", "parent_slug": "/blog", "blocks": [ { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Caching shaders across branches", "level": 1 } }, { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

Every branch used to recompile the whole shader set. That is minutes per build, times every push.

We keyed the cache on the shader source, not the branch. Two branches that share a shader now share the compile. Builds got short again.

" } } ] }, { "slug": "/blog/netcode-bad-links", "title": "Netcode on bad links", "template_key": "article", "parent_slug": "/blog", "blocks": [ { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Netcode on bad links", "level": 1 } }, { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

Players on slow connections kept desyncing. Rewriting the simulation was off the table.

We added client prediction with a short rollback window. The client guesses, the server corrects, and the gap closes before anyone notices.

" } } ] }, { "slug": "/contact", "title": "Contact", "template_key": "contact", "blocks": [ { "block_key": "contact-form", "title": "Contact form", "slot": "main", "sort_order": 1, "content": { "heading": "Request access", "description": "Tell us what you are building. We reply within one business day.", "submitLabel": "Request access", "successMessage": "Message received. We will reply within one business day.", "fields": [ { "name": "name", "label": "Your name", "type": "text", "required": true, "width": "half" }, { "name": "email", "label": "Email", "type": "email", "required": true, "width": "half" }, { "name": "studio", "label": "Studio", "type": "text", "required": false, "width": "full" }, { "name": "message", "label": "What are you building", "type": "textarea", "required": true, "width": "full" } ], "formConfig": { "enabled": true, "captchaEnabled": false, "targetTable": "contact_submissions" } } }, { "block_key": "contact-card", "title": "Reach us", "slot": "main", "sort_order": 2, "content": { "heading": "Other ways in", "columns": 3, "channels": [ { "icon": "lucide:mail", "label": "Email", "value": "crew@neonforge.dev", "link": "mailto:crew@neonforge.dev" }, { "icon": "simple-icons:github", "label": "Source", "value": "github.com/neon-forge", "link": "https://github.com/neon-forge" }, { "icon": "lucide:message-square", "label": "Discord", "value": "Join the build channel", "link": "#" } ] } } ] }, { "slug": "/login", "title": "Sign in", "template_key": "auth", "blocks": [ { "block_key": "auth-form", "title": "Sign in", "slot": "main", "sort_order": 1, "content": { "default_tab": "login", "show_social": false } } ] } ], "menu_items": [ { "menu": "main", "label": "Home", "page_slug": "/", "sort_order": 1 }, { "menu": "main", "label": "Studio", "page_slug": "/about", "sort_order": 2 }, { "menu": "main", "label": "Devlog", "page_slug": "/blog", "sort_order": 3 }, { "menu": "main", "label": "Contact", "page_slug": "/contact", "sort_order": 4 } ] }