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>
14 KiB
Format pliku EU7v2 (.eu7v2)
Dokumentacja oparta na kodzie źródłowym z:
scene/eu7/v2/— format, emitter, loader, testy roundtripscene/eu7/eu7_bake_parser.cpp— headless bake scenariuszaeu07-parser/include/eu07/scene/bake/— pool bake, streaming terenuStan: czerwiec 2026, wersja kontenera v1 (
kVersion = 1).
Spis treści
- Przegląd ogólny
- Nagłówek pliku
- Struktura chunku
- Rodzaje pliku (
file_kind) - Katalog chunków
- Typy podstawowe
- STRS — tablica łańcuchów
- META — metadane modułu
- INCL — include rekurencyjne
- PLCE — placementy modułów wielokrotnego użytku
- PROT + INST — prototypy i instancje modeli
- SHPE — kształty (triangles)
- MESH — teren (tile)
- LINE — linie
- Rekordy symulacji
- Bake headless i drzewo modułów
- Ś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
.eu7v2per.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. STRS → 53 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:
.inc→file_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:
- Root
.scn→ enqueue drzewa modułów (dedup po ścieżce kanonicznej) - Pool workerów bake'uje moduły równolegle
- Każdy
.scm/.inc→ osobny.eu7v2obok źródła tekstowego - Placement
.scm→ PLCE + enqueue unikalnych.incjakomodule - Root emit na końcu (PACK → PROT+INST, includes z podmodułów)
- 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.