Speedodude commited on
Commit
f63b467
·
verified ·
1 Parent(s): de56997

Upload 3 files

Browse files
Files changed (3) hide show
  1. Speedodude_installer.py +388 -0
  2. app.py +284 -0
  3. requirements.txt +3 -0
Speedodude_installer.py ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ # --- CONFIGURATION ---
4
+ # New Folder Name matching the new branding
5
+ FOLDER_NAME = "SpeedoDude_CyberDeckDroid"
6
+ os.makedirs(FOLDER_NAME, exist_ok=True)
7
+
8
+ def write_file(filename, content):
9
+ path = os.path.join(FOLDER_NAME, filename)
10
+ with open(path, "w", encoding="utf-8") as f:
11
+ f.write(content.strip())
12
+ print(f"✅ Created: {path}")
13
+
14
+ # ==============================================================================
15
+ # 1. APP.PY (The Main Logic)
16
+ # ==============================================================================
17
+ app_code = r'''
18
+ import gradio as gr
19
+ import os
20
+ import json
21
+ import random
22
+ from huggingface_hub import InferenceClient
23
+
24
+ # --- CONFIGURATION ---
25
+ # Connects to Hugging Face's Free Inference API
26
+ # You must set 'HF_TOKEN' in your Space Settings (Variables and secrets)
27
+ HF_TOKEN = os.getenv("HF_TOKEN")
28
+
29
+ # --- BRANDING & ASSETS ---
30
+ COMPANY_NAME = "SpeedoDude"
31
+ APP_NAME = "CyberDeckDroid"
32
+ APP_TITLE = f"🌊 {COMPANY_NAME} {APP_NAME}"
33
+
34
+ DONATION_HTML = """
35
+ <div align="center">
36
+ <p><b>Support {company} Development</b><br>
37
+ {app_name} is free and open source. If this tool helped you, please consider donating!</p>
38
+ <a href="https://www.patreon.com/YOUR_USERNAME" target="_blank">
39
+ <img src="https://img.shields.io/badge/Support_on-Patreon-f96854?style=for-the-badge&logo=patreon&logoColor=white" alt="Support on Patreon"/>
40
+ </a>
41
+ <a href="https://ko-fi.com/YOUR_USERNAME" target="_blank">
42
+ <img src="https://img.shields.io/badge/Buy_me_a-Coffee-ff5f5f?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Buy me a Coffee"/>
43
+ </a>
44
+ </div>
45
+ """.format(company=COMPANY_NAME, app_name=APP_NAME)
46
+
47
+ LEGAL_TEXT = f"""
48
+ ### ⚠️ Legal Disclaimer & Terms
49
+ 1. **Single-Player Only:** {APP_NAME} is strictly for offline, creative use. Do not use in multiplayer environments.
50
+ 2. **Liability:** {COMPANY_NAME} is not responsible for account bans or data loss. Always backup your save files.
51
+ 3. **Ownership:** Assets generated via the {COMPANY_NAME} Generator belong to you, the user.
52
+ """
53
+
54
+ # ==============================================================================
55
+ # MODULE 1: THE GENERATOR (Assets & Textures)
56
+ # ==============================================================================
57
+ def generate_asset(prompt, style, asset_type):
58
+ """
59
+ Generates game textures/concepts using Stable Diffusion.
60
+ """
61
+ if not HF_TOKEN:
62
+ return None, "⚠️ Error: HF_TOKEN secret is missing in Space Settings."
63
+
64
+ # Model Selection: Stable Diffusion 2.1 is reliable and free on HF
65
+ model_id = "stabilityai/stable-diffusion-2-1"
66
+ client = InferenceClient(model_id, token=HF_TOKEN)
67
+
68
+ # Optimized Prompt Engineering
69
+ full_prompt = f"{prompt}, {style} style, {asset_type} game asset, high quality, 4k, flat lighting, seamless"
70
+
71
+ try:
72
+ image = client.text_to_image(full_prompt)
73
+ output_path = "/tmp/speedodude_asset.png"
74
+ image.save(output_path)
75
+ return output_path, f"✅ Success! Generated: '{full_prompt}'"
76
+ except Exception as e:
77
+ return None, f"❌ Generation Error: {str(e)}"
78
+
79
+ # ==============================================================================
80
+ # MODULE 2: THE FABRICATOR (Save File Editor)
81
+ # ==============================================================================
82
+ def analyze_save_file(file_obj):
83
+ """
84
+ Reads a .json or .xml file and shows the structure.
85
+ """
86
+ if file_obj is None: return "Please upload a file first."
87
+
88
+ try:
89
+ with open(file_obj.name, 'r') as f:
90
+ content = f.read()
91
+
92
+ # Try parsing JSON
93
+ try:
94
+ data = json.loads(content)
95
+ keys = list(data.keys())[:50] # Preview first 50 keys
96
+ return f"📂 File Valid (JSON).\nFound Top-Level Keys:\n{keys}..."
97
+ except json.JSONDecodeError:
98
+ # Fallback for XML/Text (Basic preview)
99
+ return f"📄 File Valid (Text/XML).\nPreview:\n{content[:500]}..."
100
+
101
+ except Exception as e:
102
+ return f"❌ Error reading file: {str(e)}"
103
+
104
+ def apply_hack(file_obj, key_to_find, new_value):
105
+ """
106
+ Recursively searches a JSON file for a specific key and updates it.
107
+ """
108
+ if file_obj is None: return None, "Upload a file first."
109
+
110
+ try:
111
+ with open(file_obj.name, 'r') as f:
112
+ data = json.load(f)
113
+
114
+ matches = 0
115
+
116
+ def update_recursive(d, target_k, target_v):
117
+ nonlocal matches
118
+ for k in d:
119
+ if k == target_k:
120
+ # Smart Type Conversion (Maintain Int/Float/String)
121
+ if isinstance(d[k], int):
122
+ d[k] = int(target_v)
123
+ elif isinstance(d[k], float):
124
+ d[k] = float(target_v)
125
+ else:
126
+ d[k] = str(target_v)
127
+ matches += 1
128
+ elif isinstance(d[k], dict):
129
+ update_recursive(d[k], target_k, target_v)
130
+ elif isinstance(d[k], list):
131
+ for item in d[k]:
132
+ if isinstance(item, dict):
133
+ update_recursive(item, target_k, target_v)
134
+
135
+ update_recursive(data, key_to_find, new_value)
136
+
137
+ if matches == 0:
138
+ return None, f"⚠️ Key '{key_to_find}' not found in file."
139
+
140
+ output_path = "/tmp/speedodude_modded.json"
141
+ with open(output_path, 'w') as f:
142
+ json.dump(data, f, indent=4)
143
+
144
+ return output_path, f"✅ Success! Updated {matches} instance(s) of '{key_to_find}'."
145
+ except Exception as e:
146
+ return None, f"❌ Error: {str(e)}"
147
+
148
+ # ==============================================================================
149
+ # MODULE 3: THE ARCHITECT (Alchemist, Dojo, Director, Genesis)
150
+ # ==============================================================================
151
+ def generate_blueprint(blueprint_type, name, details):
152
+ """
153
+ Generates code snippets and configuration files for various game systems.
154
+ Combines Alchemist (Items), Dojo (Combat), Director (Scenes), Genesis (Project).
155
+ """
156
+ name_clean = name.replace(" ", "")
157
+
158
+ # --- ALCHEMIST (Custom Items) ---
159
+ if blueprint_type == "Item Script (Unity C#)":
160
+ return f"""// Generated by SpeedoDude Alchemist
161
+ using UnityEngine;
162
+
163
+ [CreateAssetMenu(fileName = "{name}", menuName = "SpeedoDude/Item")]
164
+ public class {name_clean} : ItemObject {{
165
+ public string itemName = "{name}";
166
+ [TextArea] public string description = "{details}";
167
+
168
+ public override void OnUse(Character user) {{
169
+ Debug.Log("Using {name}...");
170
+ // Effect Logic: {details}
171
+ // TODO: Implement specific stat changes here.
172
+ }}
173
+ }}
174
+ """
175
+
176
+ # --- DOJO (Combat Logic) ---
177
+ elif blueprint_type == "Combat Style (JSON)":
178
+ data = {
179
+ "style_name": name,
180
+ "description": details,
181
+ "creator": COMPANY_NAME,
182
+ "moves": [
183
+ {"name": "Light Attack", "damage": 10, "anim": f"{name}_Light.anim", "frame_data": 5},
184
+ {"name": "Heavy Attack", "damage": 25, "anim": f"{name}_Heavy.anim", "frame_data": 15},
185
+ {"name": "Special", "damage": 50, "effect": details}
186
+ ]
187
+ }
188
+ return json.dumps(data, indent=4)
189
+
190
+ # --- DIRECTOR (Scene Layout) ---
191
+ elif blueprint_type == "Scene Layout (JSON)":
192
+ return json.dumps({
193
+ "scene_name": name,
194
+ "theme": details,
195
+ "lighting": {"ambient": "#1a1a1a", "sun_intensity": 0.8},
196
+ "objects": [
197
+ {"id": "player_start", "pos": [0, 1, 0]},
198
+ {"id": "enemy_spawn", "pos": [10, 0, 5]},
199
+ {"id": "prop_chest", "pos": [-5, 0, 2], "loot": "random"}
200
+ ]
201
+ }, indent=4)
202
+
203
+ # --- GENESIS (Unreal Project Config) ---
204
+ elif blueprint_type == "Unreal Project File (.uproject)":
205
+ return json.dumps({
206
+ "FileVersion": 3,
207
+ "EngineAssociation": "5.3",
208
+ "Category": "",
209
+ "Description": f"{details} - Generated by {COMPANY_NAME} Genesis",
210
+ "Modules": [
211
+ {"Name": name_clean, "Type": "Runtime", "LoadingPhase": "Default"}
212
+ ]
213
+ }, indent=4)
214
+
215
+ return "Error: Unknown Blueprint Type"
216
+
217
+ # ==============================================================================
218
+ # MAIN UI LAYOUT
219
+ # ==============================================================================
220
+ # Using 'Soft' theme with SpeedoDude colors
221
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="cyan", secondary_hue="indigo"), title=APP_TITLE) as app:
222
+
223
+ # --- HEADER ---
224
+ gr.Markdown(f"# {APP_TITLE}")
225
+ gr.Markdown(f"The ultimate cloud-based **{APP_NAME}** for single-player game modding.")
226
+ gr.HTML(DONATION_HTML) # Inject Donation Badges
227
+
228
+ # --- TABS ---
229
+ with gr.Tabs():
230
+
231
+ # TAB 1: GENERATOR
232
+ with gr.TabItem("🎨 Generator"):
233
+ gr.Markdown(f"### {COMPANY_NAME} Asset Factory")
234
+ with gr.Row():
235
+ gen_prompt = gr.Textbox(label="Prompt", placeholder="A rusty cyber-sword with glowing green edges")
236
+ gen_style = gr.Dropdown(["Realistic", "Pixel Art", "Sci-Fi", "Fantasy", "Cartoon"], label="Style", value="Realistic")
237
+ gen_type = gr.Dropdown(["Icon", "Texture", "Concept Art", "UI Element"], label="Type", value="Texture")
238
+
239
+ gen_btn = gr.Button("Generate Asset", variant="primary")
240
+
241
+ with gr.Row():
242
+ gen_image = gr.Image(label="Result")
243
+ gen_log = gr.Textbox(label="System Log")
244
+
245
+ gen_btn.click(generate_asset, inputs=[gen_prompt, gen_style, gen_type], outputs=[gen_image, gen_log])
246
+
247
+ # TAB 2: FABRICATOR
248
+ with gr.TabItem("💾 Fabricator"):
249
+ gr.Markdown(f"### {COMPANY_NAME} Save Editor")
250
+ with gr.Row():
251
+ file_input = gr.File(label="Upload Save (.json)")
252
+ analyze_btn = gr.Button("Analyze File")
253
+
254
+ file_info = gr.Textbox(label="File Structure Preview", lines=4)
255
+ analyze_btn.click(analyze_save_file, inputs=file_input, outputs=file_info)
256
+
257
+ gr.Markdown("---")
258
+ gr.Markdown("### Apply Modification")
259
+ with gr.Row():
260
+ hack_key = gr.Textbox(label="Key to Change", placeholder="e.g., gold, health, xp")
261
+ hack_val = gr.Textbox(label="New Value", placeholder="999999")
262
+
263
+ hack_btn = gr.Button("Apply Hack", variant="stop")
264
+
265
+ with gr.Row():
266
+ hack_download = gr.File(label="Download Modded Save")
267
+ hack_log = gr.Textbox(label="System Log")
268
+
269
+ hack_btn.click(apply_hack, inputs=[file_input, hack_key, hack_val], outputs=[hack_download, hack_log])
270
+
271
+ # TAB 3: ARCHITECT (Alchemist/Dojo/Director/Genesis)
272
+ with gr.TabItem("📜 Architect"):
273
+ gr.Markdown(f"### {COMPANY_NAME} Code Generator")
274
+ gr.Markdown("Generate production-ready scripts for Unity/Unreal.")
275
+
276
+ with gr.Row():
277
+ arch_type = gr.Dropdown([
278
+ "Item Script (Unity C#)",
279
+ "Combat Style (JSON)",
280
+ "Scene Layout (JSON)",
281
+ "Unreal Project File (.uproject)"
282
+ ], label="Blueprint Type")
283
+
284
+ arch_name = gr.Textbox(label="Name", placeholder="Excalibur / CyberArena")
285
+
286
+ arch_details = gr.Textbox(label="Description / Effect / Theme", placeholder="High damage sword that heals on hit...")
287
+
288
+ arch_btn = gr.Button("Generate Blueprint", variant="primary")
289
+ arch_output = gr.Code(label="Generated Output", language="csharp")
290
+
291
+ arch_btn.click(generate_blueprint, inputs=[arch_type, arch_name, arch_details], outputs=arch_output)
292
+
293
+ # --- FOOTER ---
294
+ gr.Markdown("---")
295
+ gr.Markdown(LEGAL_TEXT)
296
+ gr.Markdown(f"© 2025 {COMPANY_NAME}. All Rights Reserved.")
297
+
298
+ # ==============================================================================
299
+ # LAUNCHER (MCP ENABLED)
300
+ # ==============================================================================
301
+ if __name__ == "__main__":
302
+ # mcp=True enables Claude/Cursor to control this app as a server
303
+ app.launch(mcp=True)
304
+ '''
305
+ write_file("app.py", app_code)
306
+
307
+ # ==============================================================================
308
+ # 2. REQUIREMENTS.TXT
309
+ # ==============================================================================
310
+ req_code = """
311
+ gradio>=5.0.0
312
+ huggingface_hub
313
+ pillow
314
+ """
315
+ write_file("requirements.txt", req_code)
316
+
317
+ # ==============================================================================
318
+ # 3. README.MD (Branded & Legal)
319
+ # ==============================================================================
320
+ readme_code = """
321
+ ---
322
+ title: SpeedoDude CyberDeckDroid
323
+ emoji: 🌊
324
+ colorFrom: blue
325
+ colorTo: indigo
326
+ sdk: gradio
327
+ sdk_version: 5.0.0
328
+ app_file: app.py
329
+ pinned: false
330
+ license: mit
331
+ short_description: The official SpeedoDude™ CyberDeckDroid for AI game modding.
332
+ ---
333
+
334
+ # 🌊 SpeedoDude CyberDeckDroid
335
+
336
+ <div align="center">
337
+ <a href="https://www.patreon.com/YOUR_USERNAME">
338
+ <img src="https://img.shields.io/badge/Support_on-Patreon-f96854?style=for-the-badge&logo=patreon&logoColor=white" alt="Support on Patreon"/>
339
+ </a>
340
+ <a href="https://ko-fi.com/YOUR_USERNAME">
341
+ <img src="https://img.shields.io/badge/Buy_me_a-Coffee-ff5f5f?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Buy me a Coffee"/>
342
+ </a>
343
+ </div>
344
+ **CyberDeckDroid** is the premier open-source creative suite for next-gen game modding. Developed by **SpeedoDude**, this architect tool leverages advanced LLMs and Generative AI to help you build your dream game worlds.
345
+
346
+ ## ✨ The SpeedoDude Toolset
347
+
348
+ * **🎨 SpeedoDude Generator:** Create unique, high-fidelity game textures, UI elements, and character skins using our tuned Stable Diffusion pipeline.
349
+ * **💾 SpeedoDude Fabricator:** The ultimate save-file surgeon. Analyze and modify `.json` / `.xml` data with surgical precision.
350
+ * **📜 SpeedoDude Architect:** Summon production-ready code. Generate boilerplate modding scripts (C#, Lua, JSON) for Unity and Unreal Engine instantly.
351
+ * **☁️ SpeedoDude Cloud:** All processing happens on our optimized cloud infrastructure—no heavy local GPU required.
352
+
353
+ ---
354
+
355
+ ## ⚠️ SpeedoDude Legal Disclaimers & Terms
356
+
357
+ By accessing the **SpeedoDude CyberDeckDroid**, you agree to the following terms. **SpeedoDude** prioritizes creative freedom and safe modding practices.
358
+
359
+ ### 1. Single-Player & Creative Use Only
360
+ **SpeedoDude** tools are strictly designed for **offline, single-player** experiences.
361
+ * **DO NOT** use **CyberDeckDroid** in multiplayer, competitive, or online environments.
362
+ * **DO NOT** use **SpeedoDude** tools to bypass DRM, anti-cheat software, or paywalls.
363
+ * **SpeedoDude** and its developers condemn cheating in online ecosystems and accept no liability for users who violate third-party Terms of Service.
364
+
365
+ ### 2. Limitation of Liability
366
+ The **SpeedoDude** software suite is provided "AS IS".
367
+ * **Account Safety:** **SpeedoDude** is not responsible for account bans, suspensions, or penalties resulting from the use of our tools.
368
+ * **Data Integrity:** Modifying game files carries inherent risks. **SpeedoDude** recommends backing up all save data before using the Fabricator.
369
+
370
+ ### 3. Asset Ownership
371
+ * **Your Creations:** Any assets generated via the **SpeedoDude Generator** belong to you (the user), subject to the underlying model licenses. **SpeedoDude** claims no ownership over your creative output.
372
+
373
+ ---
374
+
375
+ ## 🛡️ Run Your Own SpeedoDude Instance
376
+
377
+ For maximum privacy and speed, we recommend duplicating the **SpeedoDude** space:
378
+
379
+ 1. Click the **Three Dots** menu (top right) -> **Duplicate this Space**.
380
+ 2. Add your own `HF_TOKEN` in the settings.
381
+ 3. Enjoy your private **SpeedoDude** studio.
382
+
383
+ ---
384
+
385
+ ## ⚖️ License
386
+
387
+ **SpeedoDude CyberDeckDroid** is licensed under the **MIT License**.
388
+
app.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import json
4
+ import random
5
+ from huggingface_hub import InferenceClient
6
+
7
+ # --- CONFIGURATION ---
8
+ # Connects to Hugging Face's Free Inference API
9
+ # You must set 'HF_TOKEN' in your Space Settings (Variables and secrets)
10
+ HF_TOKEN = os.getenv("HF_TOKEN")
11
+
12
+ # --- BRANDING & ASSETS ---
13
+ COMPANY_NAME = "SpeedoDude"
14
+ APP_TITLE = f"🌊 {COMPANY_NAME} AI Game Architect"
15
+ DONATION_HTML = """
16
+ <div align="center">
17
+ <p><b>Support {company} Development</b><br>
18
+ OmniMod is free and open source. If this tool helped you, please consider donating!</p>
19
+ <a href="https://www.patreon.com/YOUR_USERNAME" target="_blank">
20
+ <img src="https://img.shields.io/badge/Support_on-Patreon-f96854?style=for-the-badge&logo=patreon&logoColor=white" alt="Support on Patreon"/>
21
+ </a>
22
+ <a href="https://ko-fi.com/YOUR_USERNAME" target="_blank">
23
+ <img src="https://img.shields.io/badge/Buy_me_a-Coffee-ff5f5f?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Buy me a Coffee"/>
24
+ </a>
25
+ </div>
26
+ """.format(company=COMPANY_NAME)
27
+
28
+ LEGAL_TEXT = """
29
+ ### ⚠️ Legal Disclaimer & Terms
30
+ 1. **Single-Player Only:** This tool is strictly for offline, creative use. Do not use in multiplayer environments.
31
+ 2. **Liability:** SpeedoDude is not responsible for account bans or data loss. Always backup your save files.
32
+ 3. **Ownership:** Assets generated via the SpeedoDude Generator belong to you, the user.
33
+ """
34
+
35
+ # ==============================================================================
36
+ # MODULE 1: THE GENERATOR (Assets & Textures)
37
+ # ==============================================================================
38
+ def generate_asset(prompt, style, asset_type):
39
+ """
40
+ Generates game textures/concepts using Stable Diffusion.
41
+ """
42
+ if not HF_TOKEN:
43
+ return None, "⚠️ Error: HF_TOKEN secret is missing in Space Settings."
44
+
45
+ # Model Selection: Stable Diffusion 2.1 is reliable and free on HF
46
+ model_id = "stabilityai/stable-diffusion-2-1"
47
+ client = InferenceClient(model_id, token=HF_TOKEN)
48
+
49
+ # Optimized Prompt Engineering
50
+ full_prompt = f"{prompt}, {style} style, {asset_type} game asset, high quality, 4k, flat lighting, seamless"
51
+
52
+ try:
53
+ image = client.text_to_image(full_prompt)
54
+ output_path = "/tmp/speedodude_asset.png"
55
+ image.save(output_path)
56
+ return output_path, f"✅ Success! Generated: '{full_prompt}'"
57
+ except Exception as e:
58
+ return None, f"❌ Generation Error: {str(e)}"
59
+
60
+ # ==============================================================================
61
+ # MODULE 2: THE FABRICATOR (Save File Editor)
62
+ # ==============================================================================
63
+ def analyze_save_file(file_obj):
64
+ """
65
+ Reads a .json or .xml file and shows the structure.
66
+ """
67
+ if file_obj is None: return "Please upload a file first."
68
+
69
+ try:
70
+ with open(file_obj.name, 'r') as f:
71
+ content = f.read()
72
+
73
+ # Try parsing JSON
74
+ try:
75
+ data = json.loads(content)
76
+ keys = list(data.keys())[:50] # Preview first 50 keys
77
+ return f"📂 File Valid (JSON).\nFound Top-Level Keys:\n{keys}..."
78
+ except json.JSONDecodeError:
79
+ # Fallback for XML/Text (Basic preview)
80
+ return f"📄 File Valid (Text/XML).\nPreview:\n{content[:500]}..."
81
+
82
+ except Exception as e:
83
+ return f"❌ Error reading file: {str(e)}"
84
+
85
+ def apply_hack(file_obj, key_to_find, new_value):
86
+ """
87
+ Recursively searches a JSON file for a specific key and updates it.
88
+ """
89
+ if file_obj is None: return None, "Upload a file first."
90
+
91
+ try:
92
+ with open(file_obj.name, 'r') as f:
93
+ data = json.load(f)
94
+
95
+ matches = 0
96
+
97
+ def update_recursive(d, target_k, target_v):
98
+ nonlocal matches
99
+ for k in d:
100
+ if k == target_k:
101
+ # Smart Type Conversion (Maintain Int/Float/String)
102
+ if isinstance(d[k], int):
103
+ d[k] = int(target_v)
104
+ elif isinstance(d[k], float):
105
+ d[k] = float(target_v)
106
+ else:
107
+ d[k] = str(target_v)
108
+ matches += 1
109
+ elif isinstance(d[k], dict):
110
+ update_recursive(d[k], target_k, target_v)
111
+ elif isinstance(d[k], list):
112
+ for item in d[k]:
113
+ if isinstance(item, dict):
114
+ update_recursive(item, target_k, target_v)
115
+
116
+ update_recursive(data, key_to_find, new_value)
117
+
118
+ if matches == 0:
119
+ return None, f"⚠️ Key '{key_to_find}' not found in file."
120
+
121
+ output_path = "/tmp/speedodude_modded.json"
122
+ with open(output_path, 'w') as f:
123
+ json.dump(data, f, indent=4)
124
+
125
+ return output_path, f"✅ Success! Updated {matches} instance(s) of '{key_to_find}'."
126
+ except Exception as e:
127
+ return None, f"❌ Error: {str(e)}"
128
+
129
+ # ==============================================================================
130
+ # MODULE 3: THE ARCHITECT (Alchemist, Dojo, Director, Genesis)
131
+ # ==============================================================================
132
+ def generate_blueprint(blueprint_type, name, details):
133
+ """
134
+ Generates code snippets and configuration files for various game systems.
135
+ Combines Alchemist (Items), Dojo (Combat), Director (Scenes), Genesis (Project).
136
+ """
137
+ name_clean = name.replace(" ", "")
138
+
139
+ # --- ALCHEMIST (Custom Items) ---
140
+ if blueprint_type == "Item Script (Unity C#)":
141
+ return f"""// Generated by SpeedoDude Alchemist
142
+ using UnityEngine;
143
+
144
+ [CreateAssetMenu(fileName = "{name}", menuName = "SpeedoDude/Item")]
145
+ public class {name_clean} : ItemObject {{
146
+ public string itemName = "{name}";
147
+ [TextArea] public string description = "{details}";
148
+
149
+ public override void OnUse(Character user) {{
150
+ Debug.Log("Using {name}...");
151
+ // Effect Logic: {details}
152
+ // TODO: Implement specific stat changes here.
153
+ }}
154
+ }}
155
+ """
156
+
157
+ # --- DOJO (Combat Logic) ---
158
+ elif blueprint_type == "Combat Style (JSON)":
159
+ data = {
160
+ "style_name": name,
161
+ "description": details,
162
+ "creator": COMPANY_NAME,
163
+ "moves": [
164
+ {"name": "Light Attack", "damage": 10, "anim": f"{name}_Light.anim", "frame_data": 5},
165
+ {"name": "Heavy Attack", "damage": 25, "anim": f"{name}_Heavy.anim", "frame_data": 15},
166
+ {"name": "Special", "damage": 50, "effect": details}
167
+ ]
168
+ }
169
+ return json.dumps(data, indent=4)
170
+
171
+ # --- DIRECTOR (Scene Layout) ---
172
+ elif blueprint_type == "Scene Layout (JSON)":
173
+ return json.dumps({
174
+ "scene_name": name,
175
+ "theme": details,
176
+ "lighting": {"ambient": "#1a1a1a", "sun_intensity": 0.8},
177
+ "objects": [
178
+ {"id": "player_start", "pos": [0, 1, 0]},
179
+ {"id": "enemy_spawn", "pos": [10, 0, 5]},
180
+ {"id": "prop_chest", "pos": [-5, 0, 2], "loot": "random"}
181
+ ]
182
+ }, indent=4)
183
+
184
+ # --- GENESIS (Unreal Project Config) ---
185
+ elif blueprint_type == "Unreal Project File (.uproject)":
186
+ return json.dumps({
187
+ "FileVersion": 3,
188
+ "EngineAssociation": "5.3",
189
+ "Category": "",
190
+ "Description": f"{details} - Generated by SpeedoDude Genesis",
191
+ "Modules": [
192
+ {"Name": name_clean, "Type": "Runtime", "LoadingPhase": "Default"}
193
+ ]
194
+ }, indent=4)
195
+
196
+ return "Error: Unknown Blueprint Type"
197
+
198
+ # ==============================================================================
199
+ # MAIN UI LAYOUT
200
+ # ==============================================================================
201
+ # Using 'Soft' theme with SpeedoDude colors
202
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="cyan", secondary_hue="indigo"), title=APP_TITLE) as app:
203
+
204
+ # --- HEADER ---
205
+ gr.Markdown(f"# {APP_TITLE}")
206
+ gr.Markdown("The ultimate cloud-based suite for single-player game modding.")
207
+ gr.HTML(DONATION_HTML) # Inject Donation Badges
208
+
209
+ # --- TABS ---
210
+ with gr.Tabs():
211
+
212
+ # TAB 1: GENERATOR
213
+ with gr.TabItem("🎨 Generator"):
214
+ gr.Markdown("### Create Game Assets")
215
+ with gr.Row():
216
+ gen_prompt = gr.Textbox(label="Prompt", placeholder="A rusty cyber-sword with glowing green edges")
217
+ gen_style = gr.Dropdown(["Realistic", "Pixel Art", "Sci-Fi", "Fantasy", "Cartoon"], label="Style", value="Realistic")
218
+ gen_type = gr.Dropdown(["Icon", "Texture", "Concept Art", "UI Element"], label="Type", value="Texture")
219
+
220
+ gen_btn = gr.Button("Generate Asset", variant="primary")
221
+
222
+ with gr.Row():
223
+ gen_image = gr.Image(label="Result")
224
+ gen_log = gr.Textbox(label="System Log")
225
+
226
+ gen_btn.click(generate_asset, inputs=[gen_prompt, gen_style, gen_type], outputs=[gen_image, gen_log])
227
+
228
+ # TAB 2: FABRICATOR
229
+ with gr.TabItem("💾 Fabricator"):
230
+ gr.Markdown("### Save File Editor")
231
+ with gr.Row():
232
+ file_input = gr.File(label="Upload Save (.json)")
233
+ analyze_btn = gr.Button("Analyze File")
234
+
235
+ file_info = gr.Textbox(label="File Structure Preview", lines=4)
236
+ analyze_btn.click(analyze_save_file, inputs=file_input, outputs=file_info)
237
+
238
+ gr.Markdown("---")
239
+ gr.Markdown("### Apply Modification")
240
+ with gr.Row():
241
+ hack_key = gr.Textbox(label="Key to Change", placeholder="e.g., gold, health, xp")
242
+ hack_val = gr.Textbox(label="New Value", placeholder="999999")
243
+
244
+ hack_btn = gr.Button("Apply Hack", variant="stop")
245
+
246
+ with gr.Row():
247
+ hack_download = gr.File(label="Download Modded Save")
248
+ hack_log = gr.Textbox(label="System Log")
249
+
250
+ hack_btn.click(apply_hack, inputs=[file_input, hack_key, hack_val], outputs=[hack_download, hack_log])
251
+
252
+ # TAB 3: ARCHITECT (Alchemist/Dojo/Director/Genesis)
253
+ with gr.TabItem("📜 Architect"):
254
+ gr.Markdown("### Code & Blueprint Generator")
255
+ gr.Markdown("Generate production-ready scripts for Unity/Unreal.")
256
+
257
+ with gr.Row():
258
+ arch_type = gr.Dropdown([
259
+ "Item Script (Unity C#)",
260
+ "Combat Style (JSON)",
261
+ "Scene Layout (JSON)",
262
+ "Unreal Project File (.uproject)"
263
+ ], label="Blueprint Type")
264
+
265
+ arch_name = gr.Textbox(label="Name", placeholder="Excalibur / CyberArena")
266
+
267
+ arch_details = gr.Textbox(label="Description / Effect / Theme", placeholder="High damage sword that heals on hit...")
268
+
269
+ arch_btn = gr.Button("Generate Blueprint", variant="primary")
270
+ arch_output = gr.Code(label="Generated Output", language="csharp")
271
+
272
+ arch_btn.click(generate_blueprint, inputs=[arch_type, arch_name, arch_details], outputs=arch_output)
273
+
274
+ # --- FOOTER ---
275
+ gr.Markdown("---")
276
+ gr.Markdown(LEGAL_TEXT)
277
+ gr.Markdown(f"© 2025 {COMPANY_NAME}. All Rights Reserved.")
278
+
279
+ # ==============================================================================
280
+ # LAUNCHER (MCP ENABLED)
281
+ # ==============================================================================
282
+ if __name__ == "__main__":
283
+ # mcp=True enables Claude/Cursor to control this app as a server
284
+ app.launch(mcp=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=5.0.0
2
+ huggingface_hub
3
+ pillow