ArturoNereu's picture
Improved lighting, removed debug text
7aa89e4
"""
In-memory storage for game scenes
"""
from typing import Dict, Optional, Any
from datetime import datetime
class Storage:
"""Simple in-memory storage for game scenes using plain dictionaries"""
def __init__(self):
self._scenes: Dict[str, Dict[str, Any]] = {}
def save(self, scene: Dict[str, Any]) -> Dict[str, Any]:
"""Save or update a scene"""
if not isinstance(scene, dict):
raise ValueError("Scene must be a dictionary")
if "scene_id" not in scene:
raise ValueError("Scene must have a 'scene_id' key")
# Update timestamp
scene["updated_at"] = datetime.utcnow().isoformat()
self._scenes[scene["scene_id"]] = scene
return scene
def get(self, scene_id: str) -> Optional[Dict[str, Any]]:
"""Retrieve a scene by ID"""
return self._scenes.get(scene_id)
def delete(self, scene_id: str) -> bool:
"""Delete a scene"""
if scene_id in self._scenes:
del self._scenes[scene_id]
return True
return False
def list_all(self) -> list[Dict[str, Any]]:
"""List all scenes"""
return list(self._scenes.values())
def exists(self, scene_id: str) -> bool:
"""Check if scene exists"""
return scene_id in self._scenes
# Global storage instance
storage = Storage()
# Initialize with an impressive default Welcome Scene for HuggingFace Spaces
def initialize_default_scene():
"""Create a visually impressive Welcome Scene on startup"""
from backend.game_models import (
create_scene, create_light, create_environment, create_vector3,
create_game_object, create_material
)
# Create lights using Three.js best practices:
# - Ambient: Low intensity (~0.1-0.2) to fake light bounce without washing out scene
# - Directional: Main sun light with warm color for outdoor feel
# - Secondary directional: Fill light from opposite side to soften shadows
# - Point lights: Distributed around arena for even coverage
lights = [
# Main directional light (sun) - warm sunset color, positioned for dramatic shadows
create_light(
name="Sun",
light_type="directional",
color="#ffd4a3", # Warm sunlight (less saturated orange)
intensity=1.5,
position=create_vector3(10, 20, 10),
cast_shadow=True,
),
# Fill light - cooler blue from opposite side to balance shadows
create_light(
name="FillLight",
light_type="directional",
color="#a3c4ff", # Cool blue fill
intensity=0.4,
position=create_vector3(-10, 15, -5),
),
# Ambient light - very low intensity to simulate indirect light bounce
create_light(
name="Ambient",
light_type="ambient",
color="#404060", # Slightly blue-ish for natural feel
intensity=0.2,
),
# === Arena Point Lights (distributed for even coverage) ===
# Center light - main arena illumination
create_light(
name="ArenaCenter",
light_type="point",
color="#ffffff", # Neutral white
intensity=1.0,
position=create_vector3(0, 10, 0),
distance=30,
),
# Corner lights - warm tones for cozy feel
create_light(
name="ArenaCornerNE",
light_type="point",
color="#ffcc88", # Warm
intensity=0.6,
position=create_vector3(8, 6, 8),
distance=20,
),
create_light(
name="ArenaCornerNW",
light_type="point",
color="#ffcc88", # Warm
intensity=0.6,
position=create_vector3(-8, 6, 8),
distance=20,
),
create_light(
name="ArenaCornerSE",
light_type="point",
color="#88ccff", # Cool blue
intensity=0.5,
position=create_vector3(8, 6, -8),
distance=20,
),
create_light(
name="ArenaCornerSW",
light_type="point",
color="#88ccff", # Cool blue
intensity=0.5,
position=create_vector3(-8, 6, -8),
distance=20,
),
]
# Create environment with sunset preset
env = create_environment(
lighting_preset="sunset",
background_color="#1a0a20", # Dark purple (will be overridden by skybox)
)
# Hugging Face emoji model at center (animated + unlit for true colors)
objects = [
create_game_object(
object_type="model",
name="HuggingFace",
position=create_vector3(0, 1.5, 0),
scale=create_vector3(3, 3, 3),
model_path="Norod78/huggingface_emoji.glb",
metadata={"animate": True, "baseY": 1.5, "unlit": True},
),
]
# Create scene with starter objects
scene = create_scene(
name="Welcome to GCP",
description="AI-powered 3D scene builder - Try 'add a red sphere' or 'set lighting to night'",
world_width=25,
world_height=10,
world_depth=25,
objects=objects,
lights=lights,
environment=env,
)
# Use a predictable scene ID for easy linking
scene["scene_id"] = "welcome"
# Add skybox configuration (sunset preset)
scene["skybox"] = {
"preset": "sunset",
"turbidity": 8,
"rayleigh": 2,
"elevation": 5,
"azimuth": 180
}
# Save to storage
storage.save(scene)
print(f"✓ Initialized Welcome Scene (ID: welcome)")
print(f" - 25x25 world with sunset skybox")
print(f" - Hugging Face emoji model at center (unlit)")
print(f" - 8-light setup: Sun + Fill + Ambient + 5 arena point lights")
print(f" - FPS physics controller ready")
# Initialize on module load
initialize_default_scene()