The pipeline had never actually been run end-to-end before the launch trailer. First render uncovered four issues:

  1. fonts/ directory was empty. styles.py referenced Inter-Black.ttf / Inter-Medium.ttf but neither was bundled. Switched to the game’s own Orbitron font (also matches brand identity better than Inter). Copied from Assets/Resources/Fonts/Orbitron.ttf.

  2. FFmpeg drawtext on Windows segfaults with absolute paths containing drive-letter colons (E:/…). Filter parser interprets : as option-separator regardless of single-quote wrapping. Fixed by running FFmpeg with cwd=trailer-pipeline-root and emitting RELATIVE font paths in styles.py (fonts/Orbitron.ttf). All -i input paths are still resolved to absolute via Path.resolve() so they work regardless of cwd.

  3. Gyan FFmpeg Windows build crashes if libfontconfig can’t find a config file. Added trailer-pipeline/fonts.conf (minimal, points at ./fonts) and pass FONTCONFIG_FILE + FONTCONFIG_PATH env vars when invoking subprocess.run.

  4. build_filter_graph used the BEAT index ({i}:v) for FFmpeg input stream references, but FFmpeg input indices count -i arguments only — stills are generated via lavfi color= filter sources and don’t take an input slot. With stills bookending the trailer (logo

    • tagline), beat 0/5 = stills, beat 1-4 = footage, but inputs 0-3 = footage, off-by-one. Added a separate input_index counter that only advances for footage beats.
  5. Music input was being appended to a local inputs list, then build_filter_graph was re-called and OVERWROTE that list with a fresh footage-only list. Music index then referenced a non-existent stream. Reordered to set music_idx = len(inputs) BEFORE the re-build, then append music to the new inputs list AFTER.

Also added _ffescape_path helper in overlays.py for any future code path that does need to emit absolute paths.

Output of first successful preview render: trailer-pipeline/preview.mp4 40s @ 960x540 60fps, ~31MB, H.264+AAC


Commit cbf488c by astafford8488.