Skip to content

Round-trip extraChartSongFields / unrecognizedSyncTrackEvents / unrecognizedEventsTrackMidiEvents - #87

Open
elicwhite wants to merge 1 commit into
chart-documentfrom
round-trip-unrecognized-extras
Open

Round-trip extraChartSongFields / unrecognizedSyncTrackEvents / unrecognizedEventsTrackMidiEvents#87
elicwhite wants to merge 1 commit into
chart-documentfrom
round-trip-unrecognized-extras

Conversation

@elicwhite

Copy link
Copy Markdown
Owner

The parser preserves three post-writer-stack round-trip buckets that the
writers weren't yet emitting:

  • metadata.extraChartSongFields (unknown [Song] keys, .chart source)
  • unrecognizedSyncTrackEvents (non-B/TS [SyncTrack] lines, .chart)
  • unrecognizedEventsTrackMidiEvents (non-text MIDI events on the EVENTS
    track — e.g. RB practice-mode
    assist-sample notes 24/25/26)

Emit them:

  • writeChartFile appends extraChartSongFields at the tail of [Song]
    (values written verbatim — no quoting added or stripped). Editors and
    consumers should treat these as opaque and never synthesize them; this
    is strictly a round-trip aid for tools like Moonscraper that author
    deprecated fields (Player2, HoPo, PreviewEnd, audio-stream
    filenames, etc.). Any audio file discovery should go through folder
    scan, not via [Song].*Stream values.

  • writeChartFile emits unrecognizedSyncTrackEvents alongside tempos +
    time signatures in [SyncTrack], sorted by tick (TS < B < raw at the
    same tick for determinism). Text is written verbatim as
    ${tick} = ${text}, so tempo anchors (A <microseconds>) and any
    future SyncTrack event types survive a parse → write loop without
    parser updates.

  • writeMidiFile appends unrecognizedEventsTrackMidiEvents to the
    EVENTS track after sections / end events / unrecognized text events /
    coda. Events arrive with absolute-tick deltaTime (scan-chart's
    post-process) and get re-deltified by finalizeMidiTrack.

.chart-only fields (extraChartSongFields, unrecognizedSyncTrackEvents)
are dropped when writing to .mid, and unrecognizedEventsTrackMidiEvents
is dropped when writing to .chart — tests pin both contracts so a future
writer change doesn't accidentally smuggle them through as something else.

11 new tests in round-trip-unrecognized-extras.test.ts cover legacy-field
preservation, tempo-anchor round-trip, forward-compat for unknown SyncTrack
types, co-occurrence with tempos/TS at the same tick, practice-assist note
round-trip on .mid, and the cross-format drop contracts. All 1020 tests
pass (1009 existing + 11 new).

@elicwhite
elicwhite marked this pull request as ready for review April 21, 2026 23:20
…ognizedEventsTrackMidiEvents

The parser preserves three post-writer-stack round-trip buckets that the
writers weren't yet emitting:

  - `metadata.extraChartSongFields` (unknown `[Song]` keys, .chart source)
  - `unrecognizedSyncTrackEvents`   (non-B/TS `[SyncTrack]` lines, .chart)
  - `unrecognizedEventsTrackMidiEvents` (non-text MIDI events on the EVENTS
                                         track — e.g. RB practice-mode
                                         assist-sample notes 24/25/26)

Emit them:

- `writeChartFile` appends `extraChartSongFields` at the tail of `[Song]`
  (values written verbatim — no quoting added or stripped). Editors and
  consumers should treat these as opaque and never synthesize them; this
  is strictly a round-trip aid for tools like Moonscraper that author
  deprecated fields (`Player2`, `HoPo`, `PreviewEnd`, audio-stream
  filenames, etc.). Any audio file discovery should go through folder
  scan, not via `[Song].*Stream` values.

- `writeChartFile` emits `unrecognizedSyncTrackEvents` alongside tempos +
  time signatures in `[SyncTrack]`, sorted by tick (TS < B < raw at the
  same tick for determinism). Text is written verbatim as
  `${tick} = ${text}`, so tempo anchors (`A <microseconds>`) and any
  future SyncTrack event types survive a parse → write loop without
  parser updates.

- `writeMidiFile` appends `unrecognizedEventsTrackMidiEvents` to the
  EVENTS track after sections / end events / unrecognized text events /
  coda. Events arrive with absolute-tick `deltaTime` (scan-chart's
  post-process) and get re-deltified by `finalizeMidiTrack`.

`.chart`-only fields (`extraChartSongFields`, `unrecognizedSyncTrackEvents`)
are dropped when writing to `.mid`, and `unrecognizedEventsTrackMidiEvents`
is dropped when writing to `.chart` — tests pin both contracts so a future
writer change doesn't accidentally smuggle them through as something else.

11 new tests in `round-trip-unrecognized-extras.test.ts` cover legacy-field
preservation, tempo-anchor round-trip, forward-compat for unknown SyncTrack
types, co-occurrence with tempos/TS at the same tick, practice-assist note
round-trip on `.mid`, and the cross-format drop contracts. All 1020 tests
pass (1009 existing + 11 new).
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