Spaces:
Running
Running
feat: add description to the app
Browse files- src/app_description.py +36 -0
- src/game_constructor.py +13 -7
- src/main.py +14 -13
src/app_description.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
|
| 3 |
+
def app_description():
|
| 4 |
+
gr.Markdown("""
|
| 5 |
+
# ๐ฎ LLMGameHub - Your Personal Visual Novel
|
| 6 |
+
|
| 7 |
+
**Craft your own adventures with an AI-powered game master!**
|
| 8 |
+
|
| 9 |
+
๐ฅ [Video Demo](https://youtu.be/pQfP9lA1QUM)
|
| 10 |
+
|
| 11 |
+
This application is an interactive storytelling experience where you are the author. Create a unique world, design your character, and let our AI agent weave a narrative tailored to your choices. It's a blend of a game constructor and a visual novel, powered by generative AI.
|
| 12 |
+
|
| 13 |
+
## ๐ฏ Key Features
|
| 14 |
+
- **๐ค AI Game Master**: An intelligent agent that generates a dynamic story with branching narratives based on your inputs.
|
| 15 |
+
- **๐จ World Building**: Define your own game setting, from fantasy realms to sci-fi dystopias.
|
| 16 |
+
- **๐ค Character Creation**: Customize your protagonist's name, age, background, and personality.
|
| 17 |
+
- **๐ญ Genre Selection**: Choose from a variety of genres to set the tone of your story (e.g., Fantasy, Sci-Fi, Mystery).
|
| 18 |
+
- **๐ผ๏ธ Visual & Audio Experience**: The AI generates images and background music to accompany the scenes, immersing you in the story.
|
| 19 |
+
- **โ๏ธ Interactive Choices**: Guide the narrative by selecting from AI-generated options or writing your own custom actions.
|
| 20 |
+
|
| 21 |
+
## ๐ ๏ธ How It Works
|
| 22 |
+
|
| 23 |
+
1. **Construct Your World**: Use the forms to describe the setting and your character.
|
| 24 |
+
2. **Choose a Genre**: Select the style of your adventure.
|
| 25 |
+
3. **Start the Game**: The AI will generate the opening scene based on your setup.
|
| 26 |
+
4. **Make Your Choices**: Interact with the story by choosing from a list of actions or writing your own.
|
| 27 |
+
5. **Experience Your Story**: Watch as the AI dynamically creates a unique story with text and images just for you.
|
| 28 |
+
|
| 29 |
+
## ๐ Agent Demo
|
| 30 |
+
This Space showcases **intelligent agent capabilities for creative writing**:
|
| 31 |
+
- Dynamic story and scene generation.
|
| 32 |
+
- Contextual understanding of player choices.
|
| 33 |
+
- AI-powered generation of text, images, and music.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
""")
|
src/game_constructor.py
CHANGED
|
@@ -1,16 +1,14 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import json
|
| 3 |
import uuid
|
| 4 |
-
from game_setting import Character, GameSetting, get_user_story
|
| 5 |
-
from game_state import story, state, get_current_scene
|
| 6 |
-
from agent.llm_agent import process_user_input
|
| 7 |
-
from images.image_generator import generate_image
|
| 8 |
from game_setting import Character, GameSetting
|
| 9 |
from agent.runner import process_step
|
| 10 |
from audio.audio_generator import start_music_generation, change_music_tone
|
| 11 |
from agent.music_agent import generate_music_prompt
|
| 12 |
import asyncio
|
| 13 |
-
from
|
|
|
|
|
|
|
| 14 |
|
| 15 |
|
| 16 |
# Predefined suggestions for demo
|
|
@@ -87,7 +85,15 @@ def save_game_config(
|
|
| 87 |
):
|
| 88 |
"""Save the game configuration to a JSON file"""
|
| 89 |
if not all(
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
):
|
| 92 |
return "โ Please fill in all fields before saving."
|
| 93 |
|
|
@@ -127,8 +133,8 @@ async def start_game_with_settings(
|
|
| 127 |
[setting_desc, char_name, char_age, char_background, char_personality, genre]
|
| 128 |
):
|
| 129 |
return (
|
| 130 |
-
gr.update(visible=True), # constructor_interface
|
| 131 |
gr.update(visible=False), # loading indicator
|
|
|
|
| 132 |
gr.update(visible=False), # game_interface
|
| 133 |
gr.update(
|
| 134 |
value="โ Please fill in all fields before starting the game.",
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import json
|
| 3 |
import uuid
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
from game_setting import Character, GameSetting
|
| 5 |
from agent.runner import process_step
|
| 6 |
from audio.audio_generator import start_music_generation, change_music_tone
|
| 7 |
from agent.music_agent import generate_music_prompt
|
| 8 |
import asyncio
|
| 9 |
+
from logging import getLogger
|
| 10 |
+
|
| 11 |
+
logger = getLogger(__name__)
|
| 12 |
|
| 13 |
|
| 14 |
# Predefined suggestions for demo
|
|
|
|
| 85 |
):
|
| 86 |
"""Save the game configuration to a JSON file"""
|
| 87 |
if not all(
|
| 88 |
+
s.strip()
|
| 89 |
+
for s in [
|
| 90 |
+
setting_desc,
|
| 91 |
+
char_name,
|
| 92 |
+
char_age,
|
| 93 |
+
char_background,
|
| 94 |
+
char_personality,
|
| 95 |
+
genre,
|
| 96 |
+
]
|
| 97 |
):
|
| 98 |
return "โ Please fill in all fields before saving."
|
| 99 |
|
|
|
|
| 133 |
[setting_desc, char_name, char_age, char_background, char_personality, genre]
|
| 134 |
):
|
| 135 |
return (
|
|
|
|
| 136 |
gr.update(visible=False), # loading indicator
|
| 137 |
+
gr.update(visible=True), # constructor_interface
|
| 138 |
gr.update(visible=False), # game_interface
|
| 139 |
gr.update(
|
| 140 |
value="โ Please fill in all fields before starting the game.",
|
src/main.py
CHANGED
|
@@ -15,6 +15,7 @@ from game_constructor import (
|
|
| 15 |
load_character_suggestion,
|
| 16 |
start_game_with_settings,
|
| 17 |
)
|
|
|
|
| 18 |
|
| 19 |
CONCURRENCY_LIMIT = 100
|
| 20 |
|
|
@@ -34,12 +35,14 @@ async def return_to_constructor(user_hash: str):
|
|
| 34 |
gr.update(visible=False), # game_interface
|
| 35 |
gr.update(visible=False), # error_message
|
| 36 |
)
|
| 37 |
-
|
|
|
|
| 38 |
async def generate_user_hash():
|
| 39 |
hash = str(uuid.uuid4())
|
| 40 |
logger.info(f"Generated user hash: {hash}")
|
| 41 |
return gr.update(value=hash)
|
| 42 |
|
|
|
|
| 43 |
async def update_scene(user_hash: str, choice):
|
| 44 |
logger.info(f"Updating scene with choice: {choice}")
|
| 45 |
if not isinstance(choice, str):
|
|
@@ -142,18 +145,16 @@ with gr.Blocks(
|
|
| 142 |
with gr.Column(
|
| 143 |
visible=True, elem_id="constructor-interface", elem_classes=["constructor-page"]
|
| 144 |
) as constructor_interface:
|
| 145 |
-
gr.
|
| 146 |
-
|
| 147 |
-
"Create your own interactive story game by defining the setting, character, and genre!"
|
| 148 |
-
)
|
| 149 |
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
|
| 158 |
with gr.Row():
|
| 159 |
with gr.Column(scale=2):
|
|
@@ -339,7 +340,7 @@ with gr.Blocks(
|
|
| 339 |
error_message,
|
| 340 |
],
|
| 341 |
)
|
| 342 |
-
|
| 343 |
game_choices.change(
|
| 344 |
fn=update_scene,
|
| 345 |
inputs=[ls_user_hash, game_choices],
|
|
|
|
| 15 |
load_character_suggestion,
|
| 16 |
start_game_with_settings,
|
| 17 |
)
|
| 18 |
+
from app_description import app_description
|
| 19 |
|
| 20 |
CONCURRENCY_LIMIT = 100
|
| 21 |
|
|
|
|
| 35 |
gr.update(visible=False), # game_interface
|
| 36 |
gr.update(visible=False), # error_message
|
| 37 |
)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
async def generate_user_hash():
|
| 41 |
hash = str(uuid.uuid4())
|
| 42 |
logger.info(f"Generated user hash: {hash}")
|
| 43 |
return gr.update(value=hash)
|
| 44 |
|
| 45 |
+
|
| 46 |
async def update_scene(user_hash: str, choice):
|
| 47 |
logger.info(f"Updating scene with choice: {choice}")
|
| 48 |
if not isinstance(choice, str):
|
|
|
|
| 145 |
with gr.Column(
|
| 146 |
visible=True, elem_id="constructor-interface", elem_classes=["constructor-page"]
|
| 147 |
) as constructor_interface:
|
| 148 |
+
with gr.Row():
|
| 149 |
+
app_description()
|
|
|
|
|
|
|
| 150 |
|
| 151 |
+
with gr.Row():
|
| 152 |
+
error_message = gr.Textbox(
|
| 153 |
+
label="โ ๏ธ Error",
|
| 154 |
+
visible=False,
|
| 155 |
+
interactive=False,
|
| 156 |
+
elem_classes=["error-message"],
|
| 157 |
+
)
|
| 158 |
|
| 159 |
with gr.Row():
|
| 160 |
with gr.Column(scale=2):
|
|
|
|
| 340 |
error_message,
|
| 341 |
],
|
| 342 |
)
|
| 343 |
+
|
| 344 |
game_choices.change(
|
| 345 |
fn=update_scene,
|
| 346 |
inputs=[ls_user_hash, game_choices],
|