import streamlit as st import numpy as np import pandas as pd import json import asyncio import websockets import base64 from io import BytesIO from PIL import Image import pythreejs as three from streamlit.components.v1 import html # --- Shared World State --- @st.cache_resource def init_world_state(): return { "players": {}, # {player_id: {x, y, z}} "elements": [], # List of placed comic elements {id, type, x, y, content} "bounds": 100, # Radius of the spherical world } world_state = init_world_state() # --- Multiplayer WebSocket Server --- async def websocket_handler(websocket, path): player_id = str(id(websocket)) world_state["players"][player_id] = {"x": 0, "y": 0, "z": 0} try: async for message in websocket: data = json.loads(message) if "position" in data: world_state["players"][player_id] = data["position"] elif "element" in data: world_state["elements"].append(data["element"]) await websocket.send(json.dumps(world_state)) finally: del world_state["players"][player_id] # Start WebSocket server in a separate thread async def start_websocket_server(): server = await websockets.serve(websocket_handler, "localhost", 8765) await asyncio.Future() # Run forever if "websocket_server" not in st.session_state: st.session_state.websocket_server = True asyncio.run_coroutine_threadsafe(start_websocket_server(), asyncio.get_event_loop()) # --- Streamlit App --- st.title("Neon Emissary’s Promise: A Sci-Fi Horror Comic Adventure") # --- Comic Cover Display with Improved Font Styles --- st.header("Comic Cover: Neon Emissary’s Promise") st.markdown(""" A stained glass mosaic artwork of a futuristic envoy, composed of jewel-toned, colored glass fragments arranged into intricate patterns, with refracted light and vibrant, luminous reflections, standing beneath a vault of radiant pink chrome. """) # Custom CSS for improved font styles inspired by horror comic aesthetics st.markdown(""" """, unsafe_allow_html=True) st.markdown('
Neon Emissary’s Promise
', unsafe_allow_html=True) st.markdown('
A Tale of Love and Rebirth in Know It All
', unsafe_allow_html=True) # --- Game Interface --- st.header("Interactive Comic Adventure") # Player ID for multiplayer if "player_id" not in st.session_state: st.session_state.player_id = str(np.random.randint(1000000)) # --- Drag-and-Drop Canvas with JavaScript --- st.subheader("Comic Canvas (Drag and Drop Elements)") canvas_html = """
""" html(canvas_html, height=500) # --- 3D Particle System for Multiplayer --- st.subheader("Multiplayer World (3D Particle System)") threejs_html = """
""" html(threejs_html, height=450) # --- Story Dialogue --- st.header("Story: Neon Emissary’s Promise") st.write(""" **Scene:** A futuristic envoy, rendered as a stained glass mosaic, stands beneath a vault of radiant pink chrome in the city of Know It All, where giant brain skyscrapers pulse with LED lights. **Dialogue:** *“In these kaleidoscopic shards, every broken piece whispers the promise of rebirth,”* she confesses, eyes sparkling amid refracted light. *“Our love etches its vow into every fragment of this luminous city,”* he replies, as vibrant reflections underscore their fateful meeting. """) # --- World Building Tests --- st.header("World Building Tests") if st.button("Generate Random Event"): event = np.random.choice([ "A neon storm erupts, casting fractured light across the city.", "A brain skyscraper pulses, revealing a hidden memory in the shards.", "A rival envoy appears, challenging the promise of rebirth." ]) st.write(event) world_state["elements"].append({ "id": str(np.random.randint(1000000)), "type": "speech", "x": np.random.randint(50, 750), "y": np.random.randint(50, 350), "content": event })