Spaces:
Sleeping
Sleeping
| title: 🧜♀️Streamlit🧠CV📚Scroller | |
| emoji: 🧜♀️📚🧜♂️ | |
| colorFrom: gray | |
| colorTo: pink | |
| sdk: streamlit | |
| sdk_version: 1.45.0 | |
| app_file: app.py | |
| pinned: false | |
| license: mit | |
| short_description: 🧠CV Scroller🧜♀️🧜♂️🧜3D Graphs | |
| ## 📂 File Cast & Roles | |
| - **`app.py`** — 🧑✈️ **The Conductor** | |
| Orchestrates Streamlit: | |
| - Loads per‑plot CSVs (your saved “tiles”) | |
| - Fetches the **GameState vault** | |
| - Injects everything into the browser | |
| - Listens for your “💾 Save” click and hands new objects off to both the plot‑file writer **and** the GameState vault | |
| - **`gamestate.py`** — 💼 **The Vault** | |
| A thread‑safe singleton that: | |
| - On startup, reads `world_state.csv` → `world_state[]` | |
| - On update, merges in new objects by `obj_id` and writes back to `world_state.csv` | |
| - Serves as the **shared truth** for everyone who joins | |
| - **`index.html`** — 🎭 **The Stage** | |
| Three.js world where: | |
| - Injected arrays (`ALL_INITIAL_OBJECTS`, `PLOTS_METADATA`, `GAME_STATE`) arrive as `window…` variables | |
| - Ground tiles and objects are rendered from those arrays | |
| - Local clicks spawn new objects into a **sessionStorage** “back‑pocket” until you hit Save | |
| - A tiny 5 s timer peeks at `window.GAME_STATE` so you can see others’ updates in near‑real time | |
| - **`requirements.txt`** — 🛠️ **The Toolbox** | |
| Lists exactly the small helper you need (`streamlit_js_eval`) to bridge JS ↔️ Python | |
| --- | |
| ## 🔄 How State Sticks | |
| 1. **Persistent CSVs** | |
| - **Per‑plot files** (`plot_X3_Z2.csv`) hold each tile’s snapshot | |
| - **Global file** (`world_state.csv`) holds the universal list of all objects | |
| 2. **In‑Memory Caching** | |
| - `@st.cache_data` for plot metadata (avoids re‑reading disk for 1 h) | |
| - `@st.cache_resource` for the GameState singleton (one vault, never re‑instantiated) | |
| 3. **Browser Session Storage** | |
| - Unsaved objects live in `sessionStorage` so you don’t lose placements on refresh | |
| - Cleared only when you “Reset” or after a successful Save | |
| 4. **JS ↔️ Python Bridge** | |
| - JS `getSaveDataAndPosition()` → returns your new objects + player coords as JSON | |
| - Streamlit parses that, writes CSV, merges vault, clears caches, and **reruns** to inject the fresh state back into the Stage | |
| --- | |
| ## 🌊 Flow of Play (Intuition) | |
| 1. **Boot Up** | |
| - Conductor (`app.py`) reads all the saved chunks → tells the Stage (`index.html`) “Here’s what’s out there!” | |
| 2. **Explore & Build** | |
| - You walk around (WASD) and click to place “House🌳Rock🏠Tree” | |
| - New pieces go into your **back pocket** (`sessionStorage`)—invisible until saved | |
| 3. **Save the Day** | |
| - Hit “💾 Save” → Conductor grabs your pocket’s contents | |
| - Vault (`GameState`) merges them into the master record | |
| - Plot files get updated so new visitors see your work | |
| 4. **Collaborate in Near‑Real Time** | |
| - Every 5 s the Stage peeks at `window.GAME_STATE` | |
| - You see newcomers’ additions pop in without a full reload | |
| ✨ a tiny toolbox keep a **persistent**, **shared**, **interactive** 3D world humming! 🎉``` | |
| - 🐍 **Python Startup** | |
| - 📂 `load_plot_metadata()` → scan `saved_worlds/` for `plot_X…_Z…csv` (cached) | |
| - 📑 `load_plot_objects()` → read CSV → build `ALL_INITIAL_OBJECTS` | |
| - 🔒 `get_game_state()` → singleton `GameState` → load/hold `world_state.csv` | |
| - 🚀 Inject → `ALL_INITIAL_OBJECTS`, `PLOTS_METADATA`, `GAME_STATE` into `index.html` | |
| - 💾 **Save Flow** | |
| - 🖱️ User clicks “💾 Save” → JS `getSaveDataAndPosition()` → returns JSON payload | |
| - 🔄 Py parses → computes `plot_X…_Z….csv` → `save_plot_data()` writes per‑plot file | |
| - ➕ `game_state.update_state()` merges into `world_state.csv` | |
| - 🔁 `load_plot_metadata.clear()` + `st.rerun()` → refreshed state | |
| - 🌐 **Three.js Init** | |
| - 🌟 `init()` → scene, camera, lights | |
| - 🛤️ `setupInitialGround()` → one plane per saved plot (or at 0,0) | |
| - 👤 `setupPlayer()` → capsule mesh at center | |
| - 📦 `loadInitialObjects()` → instantiate all persisted objects | |
| - 🎮 **Interaction & Local State** | |
| - 🖱️ `onDocumentClick()` → raycast → spawn `House/Tree/Rock…` → add to `newlyPlacedObjects` | |
| - 💾 `saveUnsavedState()` → persist `newlyPlacedObjects` to `sessionStorage` | |
| - 🔄 `restoreUnsavedState()` on reload → rehydrate unsaved objects | |
| - 🗑️ `resetNewlyPlacedObjects()` → clear sessionStorage | |
| - ⏩ **Game Loop** | |
| - 🔑 `onKeyDown`/`onKeyUp` → track WASD/Arrows | |
| - 🚶 `updatePlayerMovement()` → camera‑relative walk + `checkAndExpandGround()` | |
| - 🌱 `checkAndExpandGround()` → add placeholder planes around player | |
| - 📽️ `animate()` → movement, camera lerp, `renderer.render()` | |
| - 🔄 **Collab Sync** | |
| - ⏲️ `setInterval(pollGameState, 5000)` → logs or applies updated `window.GAME_STATE` | |
| ✨ **All set!** end‑to‑end state protocol. |