16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 00:49:19 +02:00
Files
maszyna/docs/eu7v2-format.md
maj00r beacc00932 Add headless parallel eu7v2 scenario bake with streaming and PLCE placements
Enable --eu7v2-bake from the main binary: parallel module pool, bounded-RAM
spool flush, streaming terrain triangles, flat include/model parsing, and
eu7v2 emit/load with optional verify. Large placement .scm files emit lean
PLCE records and bake referenced .inc modules separately for reuse.

- CLI: --eu7v2-bake, --eu7v2-verify, --eu7v2-mem-limit-gb, --eu7v2-threads,
  --eu7v2-max-parse; wire max_threads through to the bake parser
- eu7v2 v2 records: PLCE placements, runtime emitter/loader, batch verify
- Parallel bake pool with session cache; drop heavy-serial parse gate in spool
  mode; parse concurrency matches thread count
- Streaming terrain: batched parallel parse+bake, scan/bake pipeline, shape
  spool with persistent buffered I/O and flush-before-read
- Parallel flat-file streaming for models/includes; pack/model spool for
  low-memory incremental flush
- Optional 50 GB private-bytes guard during headless bake

Braniewo_szeroki: 160 modules, verify PASS, ~34s bake (nmt100 ~17s vs ~190s
serial baseline).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 21:15:42 +02:00

14 KiB
Raw Blame History

Format pliku EU7v2 (.eu7v2)

Dokumentacja oparta na kodzie źródłowym z:

  • scene/eu7/v2/ — format, emitter, loader, testy roundtrip
  • scene/eu7/eu7_bake_parser.cpp — headless bake scenariusza
  • eu07-parser/include/eu07/scene/bake/ — pool bake, streaming terenu

Stan: czerwiec 2026, wersja kontenera v1 (kVersion = 1).


Spis treści

  1. Przegląd ogólny
  2. Nagłówek pliku
  3. Struktura chunku
  4. Rodzaje pliku (file_kind)
  5. Katalog chunków
  6. Typy podstawowe
  7. STRS — tablica łańcuchów
  8. META — metadane modułu
  9. INCL — include rekurencyjne
  10. PLCE — placementy modułów wielokrotnego użytku
  11. PROT + INST — prototypy i instancje modeli
  12. SHPE — kształty (triangles)
  13. MESH — teren (tile)
  14. LINE — linie
  15. Rekordy symulacji
  16. Bake headless i drzewo modułów
  17. Ścieżki plików

1. Przegląd ogólny

Plik .eu7v2 to binarny format skompilowanego modułu scenerii:

  • Moduły wielokrotnego użytku — osobny plik .eu7v2 per .inc / .scm, placementy jako lean PLCE
  • Prototypy + instancje — chunk PROT (deduplikacja meshów) + INST (transformacja w world-space)
  • Chunki pomijalne — nieznany FourCC można pominąć po polu size
  • Little-endian — deterministyczny zapis niezależny od endianness hosta
  • Centralna tablica STRS — wszystkie stringi przez string_id (uint32)

Magic pliku: EU7C (FourCC 'E','U','7','C').


2. Nagłówek pliku

Offset  Rozmiar  Typ       Opis
------  -------  --------  -------------------------
0       4        uint32    Magic = 'EU7C'
4       2        uint16    Version (= 1)
6       2        uint16    file_kind (patrz sekcja 4)
8       4        uint32    Reserved (= 0)
12      4        uint32    Reserved (= 0)
16      ...      chunks    Strumień chunkowy (do EOF)

Nagłówek ma 16 bajtów. Brak pola „rozmiar całego pliku”.


3. Struktura chunku

Offset  Rozmiar  Typ      Opis
------  -------  -------  -----------------------------------------
0       4        uint32   Chunk ID — FourCC little-endian
4       8        uint64   Payload size (tylko payload, BEZ nagłówka chunku)
12      ...      bytes    Payload

Pole size to rozmiar samego payloadu (uint64), bez nagłówka chunku.

Chunki są sekwencyjne do EOF. Nieznany chunk: seek(payload_size).

FourCC — bajty w pliku w kolejności ASCII (np. STRS53 54 52 53).


4. Rodzaje pliku (file_kind)

Wartość Nazwa Typowy źródłowy plik Opis
1 sim .scn, .scm, .sbt, .ctr Moduł scenariusza / root
2 module .inc Moduł wielokrotnego użytku (trawa, drzewo…)
3 tile (planowane) Kafel 1 km — teren + instancje
4 manifest (planowane) Indeks kafli / modułów mapy

Emitter runtime (eu7v2_emit_runtime.cpp) ustawia:

  • .incfile_kind::module
  • pozostałe rozszerzenia modułów → file_kind::sim

Loader akceptuje sim i module (eu7v2_load.cpp).


5. Katalog chunków

FourCC Stała C++ Typ pliku Opis
STRS chunk::strs wszystkie Tablica stringów (zawsze pierwszy logicznie)
META chunk::meta sim/module Metadane modułu (first-init, placement params)
INCL chunk::incl sim/module Include rekurencyjne (submoduły .eu7v2)
PLCE chunk::plce sim/module Lean placementy → osobne moduły .eu7v2
PROT chunk::prot sim/module/tile Prototypy modeli (mesh bez transformacji)
INST chunk::inst sim/module/tile Instancje modeli (proto + transform)
MESH chunk::mesh tile/sim Teren — mesh z origin f64 + wierzchołki f32
SHPE chunk::shpe sim/module Kształty triangles/strip/fan (nie-teren)
LINE chunk::line sim/module Geometria linii
TRAK chunk::trak sim Tory
TRAC chunk::trac sim Przewody trakcyjne
PWRS chunk::pwrs sim Źródła zasilania
MEMC chunk::memc sim Komórki pamięci
LAUN chunk::laun sim Wyzwalacze zdarzeń
EVNT chunk::evnt sim Zdarzenia
SOND chunk::sond sim Dźwięki
DYNM chunk::dynm sim Pojazdy dynamiczne
TRST chunk::trst sim/module Zestawy wagonowe
TRGR chunk::trgr sim Precomputed track graph (planowane)
SIDX chunk::sidx manifest Indeks sekcji przestrzennej (planowane)

Chunki o zerowej liczności (pusta tablica) nie są zapisywane przez emitter.


6. Typy podstawowe

Typ w pliku Rozmiar Opis
uint8 1 B Bajt bez znaku
uint16 2 B LE
uint32 4 B LE
uint64 8 B LE
int32 4 B LE, ze znakiem
float32 4 B IEEE 754
float64 8 B IEEE 754 — pozycje world-space, originy mesh
string_id 4 B Indeks STRS; 0xFFFFFFFF = brak (kNoString)

Współrzędne instancji modeli i placementów: float64 (x/y/z).
Wierzchołki mesh/shape: float32 względem origin (f64).


7. STRS — tablica łańcuchów

uint32   count
Powtórzone count razy:
    uint32   length
    char[]   data (length bajtów, bez null-terminatora)

Indeks 0xFFFFFFFF (kNoString) oznacza brak stringu.


8. META — metadane modułu

Layout wersjonowany (pole layout_version):

uint32   layout_version          (= 1)
uint32   first_init_count
uint8    has_terrain_chunk        (informacyjne)
uint8    has_pack_chunk           (informacyjne)
uint8    placement_origin_x       (numer parametru include, 0 = brak)
uint8    placement_origin_y
uint8    placement_origin_z
uint8    placement_rotation_y

9. INCL — include rekurencyjne

Submoduły wczytywane rekurencyjnie (np. zagnieżdżone .scm, tory, CTR):

uint32   count
Powtórzone count razy:
    uint32      source_line
    string_id   source_path        (.scm/.inc tekstowy)
    string_id   binary_path        (.eu7v2)
    uint32      param_count
    string_id[] parameters
    TransformRecord site_transform:
        uint32   origin_stack_count
        dvec3[]  origin_stack
        uint32   scale_stack_count
        dvec3[]  scale_stack
        dvec3    rotation            (stopnie, XYZ)
        uint32   group_depth

10. PLCE — placementy modułów wielokrotnego użytku

Pliki placement (flora, dekoracje) emitują lean rekordy wskazujące na osobny moduł .eu7v2:

uint32   count
Powtórzone count razy:
    string_id   module_path        (np. scenery/grass_l61/20.eu7v2)
    string_id   texture_override   (kNoString jeśli brak)
    float64     x, y, z            (world-space)
    float32     rotation_y         (stopnie)
    uint8       cell_id             (0xFF = brak)

Bake: unikalne .inc z placement file są bake'owane jako osobne moduły file_kind::module.
Runtime: loader syntetyzuje include z PLCE (ładuje wskazany moduł z transformacją).

Typowy rozmiar: ~37 B / placement.

Przykład: 204_trawky_ter.scm (110k linii include) → .eu7v2 ~4 MB (PLCE) + osobne grass_l61/20.eu7v2 per unikalny .inc.


11. PROT + INST — prototypy i instancje modeli

PROT — prototyp

uint32   count
Powtórzone count razy:
    string_id   model_file
    string_id   texture_file
    uint8       flags              (bit 0=transition, 1=is_terrain, 2=instanceable)
    float32     range_min
    float32     range_max
    uint32      light_state_count
    float32[]   light_states
    uint32      light_color_count
    uint32[]    light_colors

INST — instancja

uint32   count
Powtórzone count razy:
    uint8       flags              (bit 0=has_scale, 1=texture_override, 2=has_node)
    uint32      proto              (indeks PROT)
    float64     x, y, z
    float32     ax, ay, az         (kąty Eulera, stopnie)
    uint8       cell_id
    [flags & 1]: float32 sx, sy, sz
    [flags & 2]: string_id texture_override
    [flags & 4]: node_record

Root scenariusza: modele z PACK bake są deduplikowane do PROT+INST (flattened world-space).


12. SHPE — kształty (triangles)

uint32   count
Powtórzone count razy:
    node_record     node
    uint8           translucent
    string_id       material
    lighting_block  (12 × float32: diffuse/ambient/specular RGBA)
    float64         ox, oy, oz     (origin world-space)
    uint32          vertex_count
    Powtórzone vertex_count razy:
        float32 px, py, pz       (względem origin)
        float32 nx, ny, nz
        float32 u, v

Typ węzła (node.type) niesie subtype: triangles, triangle_strip, triangle_fan.

Duże pliki terenu (same node … triangles) mogą być streamowane przy bake; shapes trafiają do shape spool na dysku, potem do chunku SHPE przy emit.


13. MESH — teren (tile)

Format terenu dla kafli 1 km (origin f64 + relative f32):

uint32   count
Powtórzone count razy:
    string_id   material
    uint8       translucent
    float64     ox, oy, oz
    uint32      vertex_count
    Powtórzone vertex_count razy:
        float32 px, py, pz, nx, ny, nz, u, v

14. LINE — linie

uint32   count
Powtórzone count razy:
    node_record
    lighting_block
    float32     line_width
    float64     ox, oy, oz
    uint32      vertex_count
    dvec3[]     vertices           (float64 × 3)

15. Rekordy symulacji

Chunki symulacji: TRAK, TRAC, PWRS, MEMC, LAUN, EVNT, SOND, DYNM, TRST.
Wspólny nagłówek węzła: node_record. Stringi przez STRS. Pozycje torów/krzywych Béziera: float64.

Szczegóły pól: scene/eu7/v2/eu7v2_records.h (funkcje write_* / read_*).


16. Bake headless i drzewo modułów

CLI (binarny eu07, bez GUI):

eu07.exe --eu7v2-bake <sciezka.scn|.inc> [opcje]
Opcja Opis
--eu7v2-verify Roundtrip: przeładuj .eu7v2, porównaj liczności rekordów
--eu7v2-mem-limit-gb N Limit pamięci procesu (domyślnie 50 GB); włącza tryb spool
--eu7v2-threads N Wątki pool bake (0 = auto = liczba rdzeni)
--eu7v2-max-parse N Równoległe parse (0 = auto)
--eu7v2-heavy-parse-mb N Próg serial parse dużych plików (0 = wyłączony w trybie spool)

Przepływ bake scenariusza:

  1. Root .scn → enqueue drzewa modułów (dedup po ścieżce kanonicznej)
  2. Pool workerów bake'uje moduły równolegle
  3. Każdy .scm/.inc → osobny .eu7v2 obok źródła tekstowego
  4. Placement .scmPLCE + enqueue unikalnych .inc jako module
  5. Root emit na końcu (PACK → PROT+INST, includes z podmodułów)
  6. Opcjonalnie verify batch wszystkich modułów

Implementacja: scene/eu7/eu7_bake_parser.cpp, eu07-parser/.../bake_tree.hpp.


17. Ścieżki plików

binary_path_from_text("scenery/foo/bar.scm")   scenery/foo/bar.eu7v2
binary_path_from_text("scenery/grass_l61/20.inc")  scenery/grass_l61/20.eu7v2
binary_path_from_text("scenery/foo/base.ctr")  scenery/foo/base.ctr.eu7v2

Rozszerzenia .scm, .scn, .sbt, .inc<stem>.eu7v2.
Inne (np. .ctr) → <nazwa_pliku>.eu7v2 (bez utraty suffixu).


Pliki implementacji

Temat Plik
Format core scene/eu7/v2/eu7v2_format.h
Scene payloads scene/eu7/v2/eu7v2_scene.h
Sim records scene/eu7/v2/eu7v2_records.h
Emit RuntimeModule scene/eu7/v2/eu7v2_emit_runtime.cpp
Load runtime scene/eu7/v2/eu7v2_load.cpp
Test roundtrip scene/eu7/v2/eu7v2_test.cpp
Headless bake scene/eu7/eu7_bake_parser.cpp
Bake pool eu07-parser/include/eu07/scene/bake/bake_tree.hpp

Dokumentacja na podstawie kodu; stan na 17 czerwca 2026.