Skip to content

feat(parser): deep-parse v1.2 ArrayProperty<StructProperty>#8

Merged
ChrisonSimtian merged 1 commit into
mainfrom
feature/issue-138-array-struct-spline
May 17, 2026
Merged

feat(parser): deep-parse v1.2 ArrayProperty<StructProperty>#8
ChrisonSimtian merged 1 commit into
mainfrom
feature/issue-138-array-struct-spline

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Owner

Summary

  • Add a v1.2 RawProperty branch that deep-parses ArrayProperty<StructProperty> (e.g. Array<Struct<FSplinePointData>> on pipe actors).
  • Surface elements via a new RawProperty.ArrayStructValues slot (IReadOnlyList<StructElementValue>), each carrying the inner v1.2 property list.
  • Misaligned reads fall back to the outer binary-size fence (no stream desync, ArrayStructValues stays null).

Wire format (inferred from the existing Array<Object> branch)

At v1.2, the inner-tag header that v1.1 carried before the element loop is gone — the struct subtype name lives in TypeNode.Children[0] (e.g. "SplinePointData"). Value bytes are int32 count, then count element bodies, each a v1.2 property-list terminated by "None". No per-element serializationControl byte.

Test plan

  • dotnet build -c Release green (Abstracts + main + tests projects)
  • All 135 existing tests pass
  • New ArrayOfStruct_ParsesElementsAsInnerPropertyLists — two elements, IntProperty inner + "None"; verifies inner values and outer fence
  • New ArrayOfStruct_EmptyArray_ProducesEmptyValuesList — count=0 fast path

Downstream

Unblocks ERP.Satisfactory #138 (pipe polylines via Pipeline.Polyline) and lands the app on 0.4.0.

The v1.2 RawProperty path already deep-parses ArrayProperty<ObjectProperty>
(see PropertySerializer.cs:240) but falls through to the binary-size fence
for ArrayProperty<StructProperty>, leaving callers with unparseable bytes.
That's the gap blocking ERP.Satisfactory #138: pipe actors carry
`mSplineData` as Array<Struct<FSplinePointData>>, and the app can't render
pipe polylines without those inner property lists.

Wire format at v1.2 (inferred from the existing Array<Object> branch and
Unreal property conventions): the inner-tag header that v1.1 carried
before the element loop is gone — the struct subtype name lives in
TypeNode.Children[0] (e.g. "SplinePointData"). Value bytes are int32
count, then `count` element bodies, each a v1.2 property-list terminated
by "None". No per-element serializationControl byte (those only prefix
the outer object body).

Changes
- RawProperty: new `ArrayStructValues` slot exposing `StructElementValue`
  entries (each carries the inner Property list).
- PropertySerializer: new `IsStructChild` predicate + Array<Struct> branch
  in TryParseKnownValue. Reads count, drains v1.2 property-lists per
  element, respects the outer binarySize fence to recover if the format
  guess is off (ArrayStructValues stays null on misread).
- Threaded `Header` into TryParseKnownValue so the inner DeserializeProperty
  loop can resolve struct sub-property reads that need header context.

Tests
- PropertySerializerV12Tests:
  ArrayOfStruct_ParsesElementsAsInnerPropertyLists — two elements, each
  one IntProperty + "None" terminator; verifies inner values and that
  the outer fence aligns to the post-value sentinel.
- ArrayOfStruct_EmptyArray_ProducesEmptyValuesList — count=0 fast path.
- All 137 existing tests continue to pass.

Downstream: unblocks ERP.Satisfactory #138 (pipe polylines via
Pipeline.Polyline) and lands the app on 0.4.0.
@ChrisonSimtian ChrisonSimtian merged commit 8829a8d into main May 17, 2026
1 check passed
@ChrisonSimtian ChrisonSimtian deleted the feature/issue-138-array-struct-spline branch May 17, 2026 08:51
ChrisonSimtian added a commit to erp-for-factory-games/ErpForFactoryGames that referenced this pull request May 17, 2026
The vendored fork now deep-parses `ArrayProperty<StructProperty>` at v1.2
(ChrisonSimtian/SatisfactorySaveNet#8 → 4.1.3) — pipe actors expose their
`mSplineData` (`Array<Struct<FSplinePointData>>`) via the new
`RawProperty.ArrayStructValues` slot.

Wiring
- Bump SatisfactorySaveNet + .Abstracts PackageReference 4.1.2 → 4.1.3.
- New `TryGetArrayStructValues` helper on `ComponentObject`.
- `SaveFileReader.ExtractPipePolyline` walks each spline element's inner
  property list, pulls the `Location` StructProperty's vector value, and
  builds the polyline. Pipes without spline data (legacy saves, isolated
  actors) keep `Polyline = null` and fall back to point-only rendering.
- Updated `Pipeline.cs` xmldoc to reflect that the slot is now populated.

Tests
- `dotnet build` clean.
- Full ERP test suite passes (Application 24, Catalog 18, Infrastructure
  17, Save 33, Persistence 9, Web.UiTests 9).
- Fork-side coverage: PropertySerializerV12Tests adds
  ArrayOfStruct_ParsesElementsAsInnerPropertyLists and
  ArrayOfStruct_EmptyArray_ProducesEmptyValuesList (137 fork tests pass).

This is the 0.4.0 milestone feature — pipes now render as LineStrings in
the GeoJSON map alongside conveyor belts.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant