From a7d541a1cf0860ba1df4ac16055412ea771bdff8 Mon Sep 17 00:00:00 2001
From: Daniel Legt
Date: Tue, 30 Jun 2026 22:28:37 +0300
Subject: [PATCH] Initial Commit
---
.gitignore | 1 +
dev_server.py | 115 +++++++++++++++++++++++++++++++++
index.html | 40 ++++++++++++
run.sh | 9 +++
src/lib/camera.js | 15 +++++
src/lib/config.js | 14 ++++
src/lib/math.js | 11 ++++
src/lib/platforms.js | 48 ++++++++++++++
src/lib/player.js | 111 ++++++++++++++++++++++++++++++++
src/lib/readout.js | 24 +++++++
src/lib/sketches.js | 80 +++++++++++++++++++++++
src/lib/state.js | 22 +++++++
src/lib/viewportRenderer.js | 125 ++++++++++++++++++++++++++++++++++++
src/lib/worldRenderer.js | 91 ++++++++++++++++++++++++++
src/main.js | 7 ++
src/styles.css | 120 ++++++++++++++++++++++++++++++++++
16 files changed, 833 insertions(+)
create mode 100644 .gitignore
create mode 100644 dev_server.py
create mode 100644 index.html
create mode 100755 run.sh
create mode 100644 src/lib/camera.js
create mode 100644 src/lib/config.js
create mode 100644 src/lib/math.js
create mode 100644 src/lib/platforms.js
create mode 100644 src/lib/player.js
create mode 100644 src/lib/readout.js
create mode 100644 src/lib/sketches.js
create mode 100644 src/lib/state.js
create mode 100644 src/lib/viewportRenderer.js
create mode 100644 src/lib/worldRenderer.js
create mode 100644 src/main.js
create mode 100644 src/styles.css
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c18dd8d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+__pycache__/
diff --git a/dev_server.py b/dev_server.py
new file mode 100644
index 0000000..e7c66c2
--- /dev/null
+++ b/dev_server.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
+from io import BytesIO
+from pathlib import Path
+import argparse
+import errno
+import os
+import time
+
+
+ROOT = Path(__file__).resolve().parent
+WATCH_EXTENSIONS = {".html", ".css", ".js"}
+RELOAD_SNIPPET = """
+
+"""
+
+
+class HotReloadHandler(SimpleHTTPRequestHandler):
+ def end_headers(self):
+ self.send_header("Cache-Control", "no-store")
+ super().end_headers()
+
+ def do_GET(self):
+ if self.path == "/__hotreload":
+ self.handle_hotreload()
+ return
+
+ super().do_GET()
+
+ def translate_path(self, path):
+ clean_path = path.split("?", 1)[0].split("#", 1)[0].lstrip("/")
+ return str(ROOT / clean_path)
+
+ def send_head(self):
+ path = Path(self.translate_path(self.path))
+ if path.is_dir():
+ path = path / "index.html"
+
+ if path.suffix == ".html" and path.exists():
+ html = path.read_text(encoding="utf-8")
+ html = html.replace("
+
+
+
+ ", f"{RELOAD_SNIPPET}")
+ body = html.encode("utf-8")
+
+ self.send_response(200)
+ self.send_header("Content-Type", "text/html; charset=utf-8")
+ self.send_header("Content-Length", str(len(body)))
+ self.end_headers()
+ return BytesIO(body)
+
+ return super().send_head()
+
+ def handle_hotreload(self):
+ self.send_response(200)
+ self.send_header("Content-Type", "text/event-stream")
+ self.send_header("Cache-Control", "no-store")
+ self.send_header("Connection", "keep-alive")
+ self.end_headers()
+
+ last_seen = latest_mtime()
+ while True:
+ time.sleep(0.5)
+ current = latest_mtime()
+ if current > last_seen:
+ last_seen = current
+ try:
+ self.wfile.write(b"event: reload\ndata: changed\n\n")
+ self.wfile.flush()
+ except (BrokenPipeError, ConnectionResetError):
+ break
+
+
+def latest_mtime():
+ latest = 0.0
+ for directory, names, files in os.walk(ROOT):
+ if ".git" in names:
+ names.remove(".git")
+
+ for filename in files:
+ path = Path(directory) / filename
+ if path.suffix in WATCH_EXTENSIONS:
+ latest = max(latest, path.stat().st_mtime)
+
+ return latest
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Run a tiny p5 dev server with hot reload.")
+ parser.add_argument("--host", default="0.0.0.0")
+ parser.add_argument("--port", type=int, default=8000)
+ args = parser.parse_args()
+
+ server, port = create_server(args.host, args.port)
+ print(f"Serving http://{args.host}:{port}", flush=True)
+ print("Watching .html, .css, and .js files for changes", flush=True)
+ server.serve_forever()
+
+
+def create_server(host, preferred_port):
+ for port in range(preferred_port, preferred_port + 20):
+ try:
+ return ThreadingHTTPServer((host, port), HotReloadHandler), port
+ except OSError as error:
+ if error.errno != errno.EADDRINUSE:
+ raise
+
+ raise OSError(f"No available port found from {preferred_port} to {preferred_port + 19}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..562a55a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
p5 World Y
+
+
+
+
+
+
+
+