Download src/main.ts from Snapkitty/gitworld: direct link, hf CLI and curl.
- Browser
- Download file 5.5 kB
-
https://huggingface.co/Snapkitty/gitworld/resolve/main/src/main.ts
- Command line
-
hf download hf://Snapkitty/gitworld/src/main.ts
-
curl -L -o main.ts https://huggingface.co/Snapkitty/gitworld/resolve/main/src/main.ts
5.5 kB
| import { EVENT_TYPES, TOOLBELT, commandTranscript } from './shared.js'; | |
| import { | |
| advanceWorldState, | |
| createWorldState, | |
| getNearbyDistrict, | |
| renderMinimap, | |
| renderWorld, | |
| worldReducer | |
| } from './world-architect.js'; | |
| import { bindUi, renderHud } from './ui-reality.js'; | |
| const app = document; | |
| const worldViewport = app.getElementById('world-viewport'); | |
| const minimap = app.getElementById('minimap-viewport'); | |
| let state = createWorldState(); | |
| function assetPath(relativePath) { | |
| const root = './phase2-unreal/ReferenceSource/'; | |
| const UrlConstructor = window.URL; | |
| return new UrlConstructor(root + relativePath, window.location.href).href; | |
| } | |
| function setupBrowserScene() { | |
| const opening = app.getElementById('opening-scene'); | |
| const video = app.getElementById('opening-video'); | |
| const enter = app.querySelector('[data-action="enter-game"]'); | |
| const sound = app.querySelector('[data-action="toggle-opening-sound"]'); | |
| const status = app.getElementById('opening-status'); | |
| if (!opening || !video || !enter) return; | |
| const enterWorld = () => { | |
| opening.classList.add('is-dismissed'); | |
| opening.setAttribute('aria-hidden', 'true'); | |
| video.pause(); | |
| worldViewport?.focus(); | |
| }; | |
| try { | |
| video.src = assetPath('Opening/3099.mp4'); | |
| video.poster = assetPath('NeonReflections/3090.webp'); | |
| video.load(); | |
| const openingFallback = window.setTimeout(() => { | |
| if (video.readyState < 2) enterWorld(); | |
| }, 2500); | |
| video.play().catch(() => { | |
| if (status) status.textContent = 'Opening scene ready 路 press ENTER THE WORLD'; | |
| }); | |
| video.addEventListener('playing', () => { | |
| window.clearTimeout(openingFallback); | |
| if (status) status.textContent = 'Playing 3099.mp4 路 opening scene'; | |
| }, { once: true }); | |
| video.addEventListener('error', () => { | |
| if (status) status.textContent = 'Opening media unavailable 路 entering browser scene'; | |
| window.setTimeout(enterWorld, 700); | |
| }, { once: true }); | |
| } catch { | |
| if (status) status.textContent = 'Opening media unavailable 路 entering browser scene'; | |
| enterWorld(); | |
| } | |
| enter.addEventListener('click', enterWorld); | |
| sound?.addEventListener('click', () => { | |
| video.muted = !video.muted; | |
| sound.textContent = video.muted ? 'SOUND OFF' : 'SOUND ON'; | |
| }); | |
| try { | |
| app.querySelectorAll('[data-reference-image]').forEach((plate) => { | |
| plate.setAttribute('poster', assetPath(plate.dataset.referenceImage || '')); | |
| }); | |
| } catch { | |
| // Reference plates are optional presentation assets; never block gameplay. | |
| } | |
| } | |
| function dispatch(event) { | |
| state = worldReducer(state, event); | |
| window.gitWorldState = state; | |
| render(); | |
| } | |
| function render() { | |
| const nearby = getNearbyDistrict(state); | |
| if (worldViewport) renderWorld(worldViewport, state, (districtId) => dispatch({ type: EVENT_TYPES.SELECT_DISTRICT, districtId })); | |
| if (minimap) renderMinimap(minimap, state); | |
| renderHud(app, state, nearby); | |
| } | |
| function move(dx, dy) { | |
| dispatch({ type: EVENT_TYPES.PLAYER_MOVE, dx, dy }); | |
| } | |
| function useToolByKey(key) { | |
| const tool = TOOLBELT.find((candidate) => candidate.key === key); | |
| if (!tool) return; | |
| dispatch({ type: EVENT_TYPES.USE_TOOL, toolId: tool.id, message: `${tool.name}: ${tool.verb}.` }); | |
| } | |
| function inspectNearest() { | |
| const nearby = getNearbyDistrict(state); | |
| if (nearby.inRange) { | |
| dispatch({ type: EVENT_TYPES.ENTER_DISTRICT, districtId: nearby.district.id }); | |
| } else { | |
| dispatch({ type: EVENT_TYPES.SELECT_DISTRICT, districtId: nearby.district.id }); | |
| } | |
| } | |
| function onKeyDown(event) { | |
| const target = event.target; | |
| const typing = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement; | |
| if (typing && event.key !== 'Escape') return; | |
| const key = event.key.toLowerCase(); | |
| const movement = { | |
| w: [0, -1], arrowup: [0, -1], | |
| s: [0, 1], arrowdown: [0, 1], | |
| a: [-1, 0], arrowleft: [-1, 0], | |
| d: [1, 0], arrowright: [1, 0] | |
| }[key]; | |
| if (movement) { | |
| event.preventDefault(); | |
| move(movement[0], movement[1]); | |
| return; | |
| } | |
| if (key === 'e' || event.key === 'Enter') { | |
| event.preventDefault(); | |
| inspectNearest(); | |
| return; | |
| } | |
| if (key === 't') { | |
| event.preventDefault(); | |
| dispatch({ type: EVENT_TYPES.OPEN_TERMINAL }); | |
| return; | |
| } | |
| if (key === 'i') { | |
| event.preventDefault(); | |
| dispatch({ type: EVENT_TYPES.OPEN_INSPECTOR }); | |
| return; | |
| } | |
| if (/^[1-8]$/.test(event.key)) { | |
| event.preventDefault(); | |
| useToolByKey(event.key); | |
| return; | |
| } | |
| if (event.key === 'Escape') { | |
| dispatch(state.terminal.open ? { type: EVENT_TYPES.CLOSE_TERMINAL } : { type: EVENT_TYPES.CLOSE_INSPECTOR }); | |
| } | |
| } | |
| bindUi(app, dispatch); | |
| app.addEventListener('keydown', onKeyDown); | |
| window.addEventListener('resize', render); | |
| window.gitWorldState = state; | |
| render(); | |
| setupBrowserScene(); | |
| // Fixed-step browser-local simulation: the world advances on a deterministic clock, | |
| // while the render layer simply reflects the latest serializable state. | |
| window.setInterval(() => { | |
| const advanced = advanceWorldState(state); | |
| state = advanced.state; | |
| window.gitWorldState = state; | |
| render(); | |
| }, 1600); | |
| // Keep the transcript helper reachable for the UI's delegated terminal buttons in | |
| // environments where the app is embedded without a module bundler. | |
| window.gitWorldCommandTranscript = commandTranscript; | |