writeChartFile: emit instrument track sections#102
Open
elicwhite wants to merge 4 commits into
Open
Conversation
d34492e to
6392059
Compare
384bfaf to
6251e3a
Compare
This was referenced Apr 20, 2026
88f54cf to
ae62751
Compare
2 tasks
78f6b77 to
143d91d
Compare
Builds a minimal valid ParsedChart from scratch: default 480 resolution, 120 BPM at tick 0, 4/4 time signature at tick 0, empty tracks/sections/ metadata/vocal parts/unrecognized events. chartBytes defaults to an empty Uint8Array (no source bytes), format defaults to 'chart', iniChartModifiers to the library defaults. Options let callers override resolution, bpm, timeSignature, and format. Useful for programmatic chart generation (e.g. downstream code that builds charts up from scratch rather than parsing source bytes).
Serializes IniMetadata (Partial<typeof defaultMetadata> + extraIniFields) back to song.ini text with: - [song] header - Known fields emitted in the canonical defaultMetadata order - Undefined values skipped - Booleans as True/False (Clone Hero convention) - extraIniFields appended in insertion order - CRLF line endings Derives its field order from Object.keys(defaultMetadata) rather than hardcoding a separate FIELD_ORDER list, so new fields added to defaultMetadata automatically participate in writing. Tests exercise writeIniFile only via round-trip through parseChartAndIni, per reviewer feedback: build a metadata object, write it, re-parse, and assert on parsedChart.metadata. No assertions about the serialized ini text itself (CRLF, field order, True/False formatting, quoting) — those are implementation details.
…emission Port of the non-instrument-track half of the chart writer into scan-chart: - [Song] emits the subset of metadata the chart body supports (Name, Artist, Charter, Album, Genre, Year, Resolution, Offset, PreviewStart, Difficulty). Other fields live exclusively in song.ini. - [SyncTrack] emits tempos as `B millibeats` and time signatures as `TS numerator [denominator-exponent]`, sorted by tick with TS before B at the same tick. - [Events] emits section markers (wrapped as [section name] to survive the parser's greedy trailing-\] regex), end events, unrecognized global events (with bracket-stripping when source is .mid so round-trip to .chart emits naked text), and vocal phrase_start/phrase_end/lyric events from the normalized vocalTracks.parts.vocals. - Unrecognized chart sections are re-emitted verbatim. Instrument tracks ([ExpertSingle] etc.) land in a follow-up PR.
Completes writeChartFile with per-track section emission: - [ExpertSingle], [HardDrums], etc. named from instrument + difficulty. - Drum tracks: base notes (N 0..4 or 0..5 for 5-lane), cymbal markers (N 66/67/68) only in fourLanePro, accent (N 34..38) and ghost (N 40..44) markers matching the emitted note's eventType, one N 109 flam per group, double kick as N 32 only. - 5-lane round-trip: greenDrum+cymbal emits as N 4 (orange) while plain greenDrum stays at N 5; blueDrums coinciding with greenDrum+cymbal emit as N 5 to keep the parser's drumType detection on fiveLane. - Fret/GHL tracks: notes via the 5-fret and 6-fret maps, tap as N 6, forceUnnatural (N 5) when the note's hopo/strum flag disagrees with the natural-HOPO state. - Star power S 2, activation lanes S 64, flex lanes S 65/66, versus phrases S 0/1, solo sections as E 'solo'/'soloend' (tick + length - 1 for soloend to round-trip). - Per-track text events (including disco flip mix markers). - Disco-flip state transitions per difficulty from red/yellow drum disco/discoNoflip flags → 'mix <diff> drums0[d|dnoflip]' text events. - Coda events: if no 'coda' in unrecognizedEvents, synthesize from drumFreestyleSections where isCoda=true. - hasForcedNotes backstop: if hasForcedNotes is set but no forceUnnatural emitted, append N 5 0 at a vacant tick in the first fret track to preserve the flag on round-trip.
143d91d to
914ea70
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Completes `writeChartFile` with per-track section emission.
Features
No `hasForcedNotes` backstop — per-note natural-HOPO comparison is sufficient to preserve `hasForcedNotes` state under the state-derived definition introduced in PR #98.
Depends on
PRs #97 + #98 + #99 + #100 + #101 — stacked above.