CoolFace
Apppublic

VIDraft/WorldForge

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes
index.html187 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="utf-8">5<title>WorldForge — prompt to explorable terrain</title>6<meta name="viewport" content="width=device-width, initial-scale=1">7<style>8  :root {9    --ink: #e8eef3;10    --dim: #93a3b1;11    --panel: #141a20;12    --line: #26313b;13    --accent: #6fd08c;14  }15  * { box-sizing: border-box; }16  html, body { height: 100%; margin: 0; }17  body {18    font: 14px/1.5 ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;19    color: var(--ink); background: #0c1014; overflow: hidden;20    display: grid; grid-template-columns: 320px 1fr;21  }22  body.busy { cursor: progress; }23 24  aside {25    background: var(--panel); border-right: 1px solid var(--line);26    padding: 18px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px;27  }28  h1 { font-size: 17px; margin: 0; letter-spacing: -0.01em; }29  h1 span { color: var(--accent); }30  .sub { color: var(--dim); font-size: 12px; margin-top: 4px; }31 32  label { display: block; font-size: 11px; text-transform: uppercase;33          letter-spacing: 0.08em; color: var(--dim); margin-bottom: 6px; }34  input[type=text], input[type=number] {35    width: 100%; padding: 9px 10px; border-radius: 7px;36    border: 1px solid var(--line); background: #0e1418; color: var(--ink); font: inherit;37  }38  input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }39 40  .row { display: flex; gap: 8px; }41  .row > * { flex: 1; }42  button {43    padding: 9px 12px; border-radius: 7px; border: 1px solid var(--line);44    background: #1b242c; color: var(--ink); font: inherit; cursor: pointer;45  }46  button:hover { background: #23303a; }47  button:disabled { opacity: 0.5; cursor: default; }48  button.primary { background: var(--accent); color: #06110a; border-color: var(--accent); font-weight: 600; }49  button.primary:hover { background: #82dc9d; }50  button.on { background: var(--accent); color: #06110a; border-color: var(--accent); }51 52  #presets { display: flex; flex-wrap: wrap; gap: 6px; }53  #presets button { flex: 0 0 auto; padding: 5px 9px; font-size: 12px; border-radius: 20px; }54 55  #layout { width: 100%; aspect-ratio: 1; border-radius: 8px;56            border: 1px solid var(--line); image-rendering: pixelated; display: block; }57 58  ul#legend, ul#census { list-style: none; margin: 0; padding: 0;59                         display: flex; flex-direction: column; gap: 5px; }60  #legend li, #census li { display: flex; align-items: center; gap: 8px; font-size: 13px; }61  #legend i, #census i { width: 13px; height: 13px; border-radius: 3px; flex: 0 0 auto;62                         border: 1px solid rgba(255,255,255,.18); }63  #legend b, #census b { margin-left: auto; color: var(--dim); font-weight: 500;64                         font-variant-numeric: tabular-nums; }65 66  input[type=range] { width: 100%; accent-color: var(--accent); }67  #clockLabel { color: var(--accent); font-variant-numeric: tabular-nums; letter-spacing: 0; }68 69  #probe { display: flex; flex-direction: column; gap: 4px; font-size: 13px;70           background: #0e1418; border: 1px solid var(--line); border-radius: 7px; padding: 9px 10px; }71  #probe span { display: flex; gap: 8px; color: var(--dim); }72  #probe span b { margin-left: auto; color: var(--ink); font-weight: 500;73                  font-variant-numeric: tabular-nums; }74  #probe > b { color: var(--accent); }75  .dimmed { color: var(--dim); }76 77  #stats { color: var(--dim); font-size: 12px; font-variant-numeric: tabular-nums; }78  footer { margin-top: auto; color: var(--dim); font-size: 11px; line-height: 1.6; }79  footer a { color: #9ec7dd; }80 81  main { position: relative; }82  #view { width: 100%; height: 100%; display: block; }83  #hint {84    display: none; position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%);85    background: rgba(10,14,18,.82); border: 1px solid var(--line); border-radius: 8px;86    padding: 8px 14px; font-size: 12px; color: var(--dim);87  }88  @media (max-width: 820px) {89    body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }90    aside { max-height: 46vh; }91  }92</style>93</head>94<body>95<aside>96  <div>97    <h1>World<span>Forge</span></h1>98    <div class="sub">A prompt becomes a region plan, a semantic layout map, and an explorable height field.</div>99  </div>100 101  <div>102    <label for="prompt">Prompt</label>103    <input id="prompt" type="text" value="a snowy alpine range above a pine forest and a lake"104           placeholder="describe a world…" autocomplete="off">105  </div>106 107  <div id="presets">108    <button data-p="a desert of red canyons and mesas">Canyons</button>109    <button data-p="volcanic island ringed by ocean and jungle">Volcanic island</button>110    <button data-p="snowy alpine peaks over a pine forest">Alps</button>111    <button data-p="savanna plains with scattered acacia">Savanna</button>112    <button data-p="frozen tundra and glaciers">Tundra</button>113    <button data-p="swamp and dense rainforest">Swamp</button>114  </div>115 116  <div class="row">117    <div style="flex:1.1">118      <label for="seed">Seed</label>119      <input id="seed" type="number" min="1" step="1" value="1">120    </div>121    <div style="display:flex; align-items:flex-end">122      <button id="reseed" title="New seed, same prompt">Reroll</button>123    </div>124  </div>125 126  <div class="row">127    <button id="go" class="primary">Generate</button>128    <button id="fly" title="WASD + mouse look, Esc to exit">Fly</button>129  </div>130 131  <div>132    <label>Semantic layout map</label>133    <canvas id="layout"></canvas>134  </div>135 136  <div>137    <label for="clock">Time of day <span id="clockLabel">12:00</span></label>138    <input id="clock" type="range" min="0" max="1000" value="420">139    <div class="row" style="margin-top:8px">140      <button id="play">Run day</button>141    </div>142  </div>143 144  <div>145    <label>Regions</label>146    <ul id="legend"></ul>147  </div>148 149  <div>150    <label>Inhabitants</label>151    <ul id="census"></ul>152  </div>153 154  <div>155    <label>Inspect</label>156    <div id="probe"><span class="dimmed">click the ground to inspect</span></div>157  </div>158 159  <div id="stats"></div>160 161  <div class="row">162    <button id="glb">Export GLB</button>163    <button id="json">World spec</button>164    <button id="png">Map</button>165  </div>166 167  <footer>168    An independent implementation of the terrain foundation described in169    <a href="https://arxiv.org/abs/2608.05248" target="_blank" rel="noopener">WorldClaw</a>170    (arXiv&nbsp;2608.05248). That project publishes no code or weights; nothing from it is171    used here. Everything runs in your browser.<br>172    Built by <a href="https://huggingface.co/VIDraft" target="_blank" rel="noopener">VIDraft</a>.173  </footer>174</aside>175 176<main>177  <canvas id="view"></canvas>178  <div id="hint">WASD move · mouse look · Q/E down/up · Shift boost · Esc exit</div>179</main>180 181<script type="importmap">182{ "imports": { "three": "./vendor/three.module.js" } }183</script>184<script type="module" src="./app.js"></script>185</body>186</html>187