Was macht Block Town (Block Town – Roblox-Stadt-Video-Generator)?
Dieser Ordner enthält das gesamte Kit: die Stadt, die Besetzung, ihre Bewegungen, den Renderer, die Stimme, die Sounds, die Musik-Einstellungen und die Schritte von einer Idee bis zu einem fertigen vertikalen Video. Der Skill-Ordner ist das Verzeichnis, das diese Datei enthält; er wird im Folgenden SKILL genannt. Episoden liegen außerhalb davon (der Benutzer benennt den Ordner), sie werden im Folgenden EPISODE genannt. Verwende absolute Pfade.
Vor dem Bauen lesen: docs/ROBLOX_LOOK.md (die Welt, die Besetzung, die Requisiten, wie Einstellungen gemacht werden),
docs/RENDER.md (der Three.js-Renderer, die Lebensschicht, Tags, Handybildschirme und bedruckte Requisiten),
docs/SCRIPT.md (wie die Geschichte geschrieben wird), docs/VOICE.md (Stimme und Musik), docs/SOUND.md (Soundeffekte,
ElevenLabs, der gleichmäßige Sprachmix). docs/PROMPTS.md enthält einen Prompt für jede Phase. docs/GUIDE.md ist das ursprüngliche
Block-Look-Handbuch: die Karte, pose(), die Bewegungen und Kameraregeln gelten weiterhin.
Wie ein Video erstellt wird (seit ep05)
Blender baut und positioniert alles aus dem Python-Code der Episode; Three.js zeichnet die finalen Frames. Der eigene Renderer von Blender wird nur für Designblätter und Einzelbilder verwendet.
episode.py ──(Blender: Stadt bauen, jeden Frame posieren, Lebensschicht)──> bake: scene.glb + anim.bin + materials.json
──(Three.js in headless Chrome)──> EPISODE/frames/f_####.jpg (~0.1-0.15 s pro Frame)
──(finish.py: Untertitel, angeglichene Stimme, Soundeffekte, Musik)──> EPISODE/<name>.mp4 und <name>_music.mp4
Eine 66-sekündige Episode benötigt etwa 10-12 Minuten von den Frames bis zu den fertigen MP4s (Blender EEVEE benötigte etwa 3 Stunden).
Niemals
- Keine Roblox-Katalogartikel, heruntergeladene Modelle oder Aufnahmen, Geschichten oder Audiodateien von anderen Erstellern. Alles im
Bild wird in Code erstellt oder von
blockworld/pictures.pygezeichnet. Virale Videos können für die Handwerkskunst studiert werden, niemals wiederverwendet. - Keine kostenpflichtigen API-Aufrufe ohne das Einverständnis des Benutzers. Fish Audio (Stimme) und ElevenLabs (Soundeffekte) kosten Geld: Sag vorher, was ein Durchlauf kosten wird.
sfx_gen.pyüberprüft die verbleibenden Credits und stoppt vor der Reserve; erhöhe niemals die Reserve oder wiederhole die Generierungen, um es „noch einmal zu versuchen“, ohne zu fragen. Frage, bevor du etwas herunterlädst. - Keine Musik und keine Referenz-Sprachclips in diesem Kit. Musik nur aus einer vom Benutzer bereitgestellten Datei und nur in der
_music.mp4-Kopie. Wenn diese Datei aus dem Video eines anderen Erstellers ausgeschnitten wurde, sage deutlich, dass die_music.mp4nicht veröffentlicht werden darf: Veröffentliche das saubere<name>.mp4und füge den Song im Sound-Picker von TikTok hinzu. - Ändere nicht die acht wiederkehrenden Charaktere (Farben, Haare, Kleidung):
blockworld/town.py. - Wechsle eine bereits laufende Episode nicht zu einem anderen Look.
- Keine unerklärten abstrakten Grafiken. Ein Strahl, eine Linie oder ein Leuchten zwischen zwei kleinen Figuren sagt dem Betrachter nichts (ep05s „Jeden Balken verschenken“-Strahl las sich als „eine blaue Linie“). Zeige das Ding selbst: Balken, die aus einem Tag fliegen, einen herunterzählenden Zähler, einen Handybildschirm, der es sagt.
Der Look
Neue Episoden verwenden den Roblox-Look: build_town(..., style="roblox"). Runde Köpfe mit Anime-Gesichtern, geschichtetes Haar,
bedruckte Kleidung, glänzendes Plastik, Sonnen-/Nebel-/Regen-Stimmungen, Karaoke-Untertitel mit 3 Wörtern. Der ältere Block-Look (Würfelköpfe,
einfarbige Farben) ist immer noch für Episoden vorhanden, die damit begonnen haben: build_town(...) ohne style gibt den Block-Look,
also schreibe in einer neuen Episode immer style="roblox".
Qualitätslatte (was der Benutzer abgelehnt oder verlangt hat)
- Nichts ist jemals statisch. Rendere mit der Lebensschicht (
BT_LIFE=1, der Standard inrender_threejs.sh): Atmen, Blicke, Gewichtsverlagerungen, ein Hüpfer bei jedem Schnitt, Kamera-Wackeln und -Hereinzoomen, schwankende Bäume, treibende Wolken, schwebende Tags, sich drehende Ladekreisel, pulsierende WLAN-Ringe, hüpfende Signalstärkebalken. Eine Einstellung, in der nur die Kamera schleicht, ist eine schwache Einstellung: Gib ihr eine eigene Aktion. - Tags und Sprechblasen werden niemals verdeckt und niemals abgeschnitten. Die Lebensschicht zeichnet sie über alles, hebt sie über die Haare und hält sie innerhalb des TikTok-Safe-Area (x 5-85 %, y oberhalb der Untertitel). Überprüfe, ob sich zwei Tags nicht gegenseitig überlappen (noch nicht automatisiert).
- Jeder Bildschirm sieht aus wie ein echtes Telefon:
big_phone(screen=...)mit einem Bild auspictures.py(Statusleiste, „Kein Netz“, App-Layout, eine Hand, die es hält), niemals eine weiße Box mit 3D-Text. In der Hand gehaltene Telefone zeigen einen Sperrbildschirm. - Requisiten lesbar in Telefongröße: Eine Papierkarte ist eine echte gezeichnete Karte (
paper_map()), ein Schild ist vollständig im Bild (ziehe die Kamera zurück: Ein 10-Stud-Schild benötigt ~25 Studs Entfernung in 9:16). - Die Stimme sinkt nie.
finish.json{"voice": "vo/voice_level.wav", "loudness": "static"}: Die Erzählung wird Satz für Satz angeglichen und der Mix erhält eine feste Verstärkung, sodass laute Effekte die Stimme nicht absenken können. Messung: Die Kurzzeitlautstärke sollte für das gesamte Video innerhalb von ±1 dB von -14 LUFS bleiben. - Keine gestapelten oder harten Effekte. Ein Sound pro Moment; nichts länger als der Moment; keine zwei „Fehler“-Sounds innerhalb einer halben Sekunde.
Eine Episode erstellen: Sieben Tore
Nach jedem Tor anhalten, das Ergebnis zeigen und auf den Benutzer warten. Wo es eine echte kreative Wahl gibt, biete zwei oder drei Optionen an und sag, welche du empfiehlst.
| Tor | Was du machst | Dem Benutzer zeigen |
|---|---|---|
| 1 Regel | Drei Regeln (aus der Idee des Benutzers oder den Tests in docs/SCRIPT.md), jede mit einer Stimmung und einer Wahrzeichen-Idee | eine Tabelle |
| 2 Drehbuch | EPISODE/script.txt (ein Satz pro Zeile) und EPISODE/SCRIPT.md: Option A und B, Beat-Tabelle, Kritiker-Bewertungen | das Drehbuch |
| 3 Stimme | vo.py, words.py, voice_check.py (kostenloser Fish-Take), level_voice.py | vo/voice.wav, seine Zahlen |
| 4 Designs | EPISODE/design/episode.py: ein Standbild von jedem neuen Wahrzeichen, Requisite, Kostüm und Charakter; EPISODE/pictures.json und pictures.py für jeden Handybildschirm und jede bedruckte Requisite | DESIGN_SHEET.jpg + die Bildschirme |
| 5 Standbilder | EPISODE/episode.py mit jeder Einstellung; check; Standbilder; korrigieren; contact_sheet.py | CONTACT_SHEET.jpg |
| 6 Hook | die ersten ~15 s: render_threejs.sh EPISODE 0 F1, Sound-Cues, finish.py | die MP4 |
| 7 Volles Video | render_threejs.sh EPISODE, Sounds, finish.py (saubere Datei + Musikdatei); nach Zustimmung, der kostenpflichtige Stimm-Take | beide MP4s |
Die Tordetails sind in docs/PROMPTS.md (Prompt 1 führt das Ganze aus). Kopiere examples/ep05-wifi, um zu beginnen: Es ist eine fertige
Episode, die auf diese Weise erstellt wurde, mit ihrem Designblatt, 42 Einstellungen, Telefonbildern, Cues und Einstellungen.
Ein kostenpflichtiger finaler Take ist eine neue Aufnahme: Führe words.py und level_voice.py erneut aus, dann check, und rendere neu (die Einstellungen
folgen den Wortzeiten). Bestätige also das Timing des kostenlosen Takes bei Tor 3, aber mache den kostenpflichtigen Take vor Tor 6, wenn der Benutzer
posten möchte.
Befehle
# Stimme (Tor 3)
python3 SKILL/blockworld/vo.py EPISODE # ein Take in der Fish "Roblox"-Stimme (vo_config.json)
python3 SKILL/blockworld/vo.py EPISODE --post-only # Straffen / Präsenz / Tempo auf dem gespeicherten Take neu machen, kein neuer Anruf
python3 SKILL/blockworld/words.py EPISODE # Wortzeiten -> vo/times.json
python3 -I SKILL/blockworld/voice_check.py EPISODE # Tempo, Pausen, Helligkeit gegen die viralen Bereiche
python3 -I SKILL/blockworld/level_voice.py EPISODE # jeden Satz auf eine Ebene -> vo/voice_level.wav
# Bilder für Requisiten (Tor 4)
python3 -I SKILL/blockworld/pictures.py EPISODE # EPISODE/pictures.json -> EPISODE/pictures/*.png
# Einstellungen (Tore 4-5): Blender, immer durch run.py mit --factory-startup
blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE check
BT_LIFE=1 blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE stills [Einstellung ...]
blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE frame 12.5
python3 -I SKILL/blockworld/contact_sheet.py EPISODE # ein nummeriertes Standbild pro Einstellung -> CONTACT_SHEET.jpg
# Finale Frames (Tore 6-7): Three.js
bash SKILL/blockworld/render_threejs.sh EPISODE # jeden Frame -> EPISODE/frames/ (~10 min für 66 s)
bash SKILL/blockworld/render_threejs.sh EPISODE F0 F1 # nur F0..F1 (der Hook, eine überarbeitete Einstellung)
# Soundeffekte (Tore 6-7): siehe docs/SOUND.md
python3 -I SKILL/blockworld/sfx_gen.py --credits # ElevenLabs-Credits übrig
python3 -I SKILL/blockworld/sfx_gen.py el-tag-pop ep07-... # benannte Sounds aus sfx/ELEVENLABS_LIST.md generieren
python3 -I SKILL/blockworld/cues.py EPISODE cues_spec.json # Cues nach Wort ("say": "froze") -> EPISODE/cues.json
# Fertigstellung (Tore 6-7)
python3 -I SKILL/blockworld/finish.py EPISODE # Untertitel + Stimme + Effekte (+ Musik) -> die MP4s
checkrendert nichts: Es führt jede Einstellung aus, gibt die Einstellungstabelle aus und warnt vor Einstellungen über 2,5 s.- Automatische Standbild-Checks (
blockworld/stillcheck.py, seit ep08): Rufefocus(character, tag, ...)in jeder Einstellung auf.checkundstillsmelden dann blockierte Gesichter (durch einen Pfosten, eine Person, ein Tag oder den eigenen Arm der Figur), Gesichter unter dem Untertitelbereich, Tags außerhalb des sicheren Bereichs (x 5-85 %, zwischen TikToks oberer Leiste und den Untertiteln), Tags, die sich gegenseitig überdecken, und alles, was sich innerhalb von 1 Stud der Linse befindet. Ergebnisse gehen anEPISODE/still_check.txt. Korrigiere jede Zeile, bevor du Standbilder zeigst, und sieh sie dir dann trotzdem an: Es beurteilt nicht die Bildkomposition oder ob das Bild die Zeile erzählt. - 60 fps mit Bewegungsunschärfe (optional):
finish.json"render_fps": 240, "blur": 4rendert 240 Frames pro Sekunde und mittelt jede 4 zu einem 60-fps-Frame. Etwa 1,6 min Rendering pro Sekunde Video. - Farbwende (optional):
finish.json"grade": {"word": 24, "ramp": 0.5, "saturation": 0.6, "brightness": -0.05, "cool": 0.1, "vignette": true}lässt das Bild ab diesem Drehbuchwort (dem Wendepunkt der Geschichte) kälter, dunkler und flacher erscheinen. Untertitel werden nicht bewertet.finish.py EPISODE --plainschreibt auch<name>_plain.mp4(30 fps, keine Unschärfe, keine Bewertung) für einen Vergleich. - ep08 (
episodes/ep08-price-tags-10s) ist der 10-Sekunden-Test dafür, mit ~1 s Einstellungen. stillsschreibt zwei halb große Blender-Bilder pro Einstellung (30 % und 85 % durch) inEPISODE/stills/. VerwendeBT_LIFE=1, damit Tags so platziert werden, wie der finale Render sie platziert. Sieh dir jedes Standbild an, bevor du eines zeigst.render_threejs.shläuft im Hintergrund, wenn deine Befehle eine Zeitüberschreitung haben (etwa 10 Minuten für 66 s). Es installiert die zwei npm-Pakete bei der ersten Verwendung (blockworld/threejs/) und benötigt Chrome oder Chromium (CHROME=/pathzur Auswahl). Es behält seinen Bake inEPISODE/threejs/; lösche das undframes/, nachdem der Benutzer das Video akzeptiert hat.- Nach jeder Änderung an
episode.py, einem Bühnenbild oder einem Bild: Führerender_threejs.sherneut aus (der Bake liest den Code; zwischen den Läufen wird nichts gecached. render_all.sh(Blender-EEVEE-Frames) wird nur für Vergleiche aufbewahrt: etwa 3-6 s pro Frame.- Der Hook:
render_threejs.sh EPISODE 0 F1wobeiF1der Frame direkt vor dem ersten Schnitt nach ~15 s ist, dannfinish.py(es verwendet die vorhandenen Frames), und benenne die MP4 um, damit das vollständige Video sie nicht überschreibt. - Sieh dir Frames im gesamten Video an (mindestens einen pro Einstellung) und miss die Lautstärke, bevor du es als fertig bezeichnest. Wenn du nicht zuhören kannst, sag es deutlich und liste auf, was du stattdessen überprüft hast.
Was wohin gehört
| Pfad | Was |
|---|---|
blockworld/town.py | die Straße, die Besetzung, pose(), Licht, Kamera, build_town(style=...) |
blockworld/roblox.py | der Roblox-Look: rchar, Plastik, Stimmungen, rule_sign, giant_clock, puddles |
blockworld/rprops.py | fertige Requisiten: Signalstärke-Tags und fliegende Balken-Token, Telefone mit echten Bildschirmen und einer Hand, beleuchtete und bedruckte Bilder, gefaltete Papierkarte, Poster, Schärpe, Zylinder, Bus, Tür, Balken, Taube, WLAN-Turm |
blockworld/pictures.py, blockworld/pictures/ | zeichnet Telefonbildschirme, Sperrbildschirme und Karten aus pictures.json; die Standardbilder des Kits |
blockworld/anim.py | Wortzeit-Hilfsfunktionen, Karten (Tags, Sprechblasen), stand, walk, der Runner |
blockworld/life.py | die Lebensschicht (BT_LIFE=1): Leerlaufbewegung, Kamera, Szenenwippen, Ladekreisel, Tag-Platzierung |
blockworld/threejs/ | der Renderer: bake.py (Blender-Seite), scene.html + capture.mjs (Three.js-Seite) |
blockworld/render_threejs.sh | bake + zeichnen, der normale Weg, um finale Frames zu erstellen |
blockworld/vo.py, words.py, voice_check.py, level_voice.py | Stimme, Wortzeiten, Sprachcheck, Angleichung |
blockworld/sfx_gen.py, sfx/ELEVENLABS_LIST.md | ElevenLabs-Soundeffekte: der Generator und die Prompt-Liste |
blockworld/finish.py | Untertitel, Stimme, Soundeffekte (auch Looping-Betten), Musik, der gleichmäßige Mix, die MP4s |
blockworld/cues.py | Cue-Listen nach Wort -> cues.json |
sfx/ | Soundeffekte: das Pixabay-Set (sfx/CREDITS.md); ElevenLabs-Sounds landen hier als el-*.mp3 / epNN-*.mp3, sobald generiert (noch keine ab ep05) |
examples/ep05-wifi | die vollständig ausgearbeitete Episode (Roblox-Look, Three.js-Renderer) |
examples/ep00-roblox-look, examples/ep01-intro | kurze Demos des Roblox-Looks und des Block-Looks |