Spaces:
Running
Running
metadata
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 toworld_state.csv
- Serves as the shared truth for everyone who joins
- On startup, reads
index.html
— 🎭 The Stage
Three.js world where:- Injected arrays (
ALL_INITIAL_OBJECTS
,PLOTS_METADATA
,GAME_STATE
) arrive aswindow…
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
- Injected arrays (
requirements.txt
— 🛠️ The Toolbox
Lists exactly the small helper you need (streamlit_js_eval
) to bridge JS ↔️ Python
🔄 How State Sticks
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
- Per‑plot files (
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)
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
- Unsaved objects live in
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
- JS
🌊 Flow of Play (Intuition)
Boot Up
- Conductor (
app.py
) reads all the saved chunks → tells the Stage (index.html
) “Here’s what’s out there!”
- Conductor (
Explore & Build
- You walk around (WASD) and click to place “House🌳Rock🏠Tree”
- New pieces go into your back pocket (
sessionStorage
)—invisible until saved
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
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
- Every 5 s the Stage peeks at
✨ a tiny toolbox keep a persistent, shared, interactive 3D world humming! 🎉```
🐍 Python Startup
- 📂
load_plot_metadata()
→ scansaved_worlds/
forplot_X…_Z…csv
(cached) - 📑
load_plot_objects()
→ read CSV → buildALL_INITIAL_OBJECTS
- 🔒
get_game_state()
→ singletonGameState
→ load/holdworld_state.csv
- 🚀 Inject →
ALL_INITIAL_OBJECTS
,PLOTS_METADATA
,GAME_STATE
intoindex.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 intoworld_state.csv
- 🔁
load_plot_metadata.clear()
+st.rerun()
→ refreshed state
- 🖱️ User clicks “💾 Save” → JS
🌐 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 → spawnHouse/Tree/Rock…
→ add tonewlyPlacedObjects
- 💾
saveUnsavedState()
→ persistnewlyPlacedObjects
tosessionStorage
- 🔄
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 updatedwindow.GAME_STATE
- ⏲️
✨ All set! end‑to‑end state protocol.