mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-16 05:37:42 +00:00
Improve wording in terminology cleanup
Replace the placeholder noun left by the previous pass with context-fit phrasing (arrangement XML, chart, custom songs, etc.).
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
"""Audio extraction and conversion for the source game custom song."""
|
"""Audio extraction and conversion for custom songs."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|||||||
+13
-13
@@ -1,4 +1,4 @@
|
|||||||
"""Convert Guitar Pro files (.gp5/.gp4/.gp3) to the source game arrangement XML."""
|
"""Convert Guitar Pro files (.gp5/.gp4/.gp3) to arrangement XML."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
@@ -544,7 +544,7 @@ def convert_track(
|
|||||||
*,
|
*,
|
||||||
expand_repeats: bool = True,
|
expand_repeats: bool = True,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Convert a GP track to the source game arrangement XML string.
|
"""Convert a GP track to arrangement XML string.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
song: Parsed Guitar Pro song
|
song: Parsed Guitar Pro song
|
||||||
@@ -558,7 +558,7 @@ def convert_track(
|
|||||||
once in authored order — equivalent to the pre-expansion behavior.
|
once in authored order — equivalent to the pre-expansion behavior.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
XML string of the the source game arrangement
|
XML string of the chart arrangement
|
||||||
"""
|
"""
|
||||||
track = song.tracks[track_index]
|
track = song.tracks[track_index]
|
||||||
num_strings = len(track.strings)
|
num_strings = len(track.strings)
|
||||||
@@ -1149,7 +1149,7 @@ def list_tracks(gp_path: str) -> list[dict]:
|
|||||||
|
|
||||||
|
|
||||||
def auto_select_tracks(gp_path: str) -> tuple[list[int], dict[int, str]]:
|
def auto_select_tracks(gp_path: str) -> tuple[list[int], dict[int, str]]:
|
||||||
"""Auto-select guitar/bass/keys tracks and assign the source game arrangement names.
|
"""Auto-select guitar/bass/keys tracks and assign the standard arrangement names.
|
||||||
|
|
||||||
Includes piano/keyboard tracks as "Keys" arrangements alongside
|
Includes piano/keyboard tracks as "Keys" arrangements alongside
|
||||||
guitar and bass tracks.
|
guitar and bass tracks.
|
||||||
@@ -1205,7 +1205,7 @@ def auto_select_tracks(gp_path: str) -> tuple[list[int], dict[int, str]]:
|
|||||||
role = "bass" if t["is_bass"] else "guitar"
|
role = "bass" if t["is_bass"] else "guitar"
|
||||||
selected.append((t["index"], role))
|
selected.append((t["index"], role))
|
||||||
|
|
||||||
# Assign the source game names: Lead, Rhythm, Combo, Bass, Keys, Drums
|
# Assign the standard arrangement names: Lead, Rhythm, Combo, Bass, Keys, Drums
|
||||||
track_indices = []
|
track_indices = []
|
||||||
name_map = {}
|
name_map = {}
|
||||||
lead_count = 0
|
lead_count = 0
|
||||||
@@ -1243,14 +1243,14 @@ def convert_piano_track(
|
|||||||
*,
|
*,
|
||||||
expand_repeats: bool = True,
|
expand_repeats: bool = True,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Convert a GP piano/keyboard track to the source game XML using MIDI encoding.
|
"""Convert a GP piano/keyboard track to arrangement XML using MIDI encoding.
|
||||||
|
|
||||||
Encodes MIDI notes into the source game's string+fret format:
|
Encodes MIDI notes into the string+fret format:
|
||||||
string = midi_note // 24
|
string = midi_note // 24
|
||||||
fret = midi_note % 24
|
fret = midi_note % 24
|
||||||
|
|
||||||
This gives a range of 0-143, covering the full piano range within
|
This gives a range of 0-143, covering the full piano range within
|
||||||
the source game's 6-string x 24-fret structure. The piano highway plugin
|
the 6-string x 24-fret structure. The piano highway plugin
|
||||||
decodes back via: midi = string * 24 + fret.
|
decodes back via: midi = string * 24 + fret.
|
||||||
|
|
||||||
Honors GP repeat brackets and D.S./D.C./Coda/Fine jumps when
|
Honors GP repeat brackets and D.S./D.C./Coda/Fine jumps when
|
||||||
@@ -1342,7 +1342,7 @@ def convert_piano_track(
|
|||||||
base_midi = 60 # fallback to middle C
|
base_midi = 60 # fallback to middle C
|
||||||
midi_note = base_midi + note.value
|
midi_note = base_midi + note.value
|
||||||
|
|
||||||
# Encode into the source game string+fret
|
# Encode into the string+fret
|
||||||
rs_string = midi_note // 24
|
rs_string = midi_note // 24
|
||||||
rs_fret = midi_note % 24
|
rs_fret = midi_note % 24
|
||||||
|
|
||||||
@@ -1449,9 +1449,9 @@ def convert_drum_track(
|
|||||||
*,
|
*,
|
||||||
expand_repeats: bool = True,
|
expand_repeats: bool = True,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Convert a GP drum/percussion track to the source game XML using MIDI encoding.
|
"""Convert a GP drum/percussion track to arrangement XML using MIDI encoding.
|
||||||
|
|
||||||
Encodes MIDI drum note numbers into the source game's string+fret format:
|
Encodes MIDI drum note numbers into the string+fret format:
|
||||||
string = midi_note // 24
|
string = midi_note // 24
|
||||||
fret = midi_note % 24
|
fret = midi_note % 24
|
||||||
|
|
||||||
@@ -1534,7 +1534,7 @@ def convert_drum_track(
|
|||||||
if midi_note not in GM_DRUM_MAP:
|
if midi_note not in GM_DRUM_MAP:
|
||||||
continue # Skip unknown percussion sounds
|
continue # Skip unknown percussion sounds
|
||||||
|
|
||||||
# Encode into the source game string+fret
|
# Encode into the string+fret
|
||||||
rs_string = midi_note // 24
|
rs_string = midi_note // 24
|
||||||
rs_fret = midi_note % 24
|
rs_fret = midi_note % 24
|
||||||
|
|
||||||
@@ -1778,7 +1778,7 @@ def convert_file(
|
|||||||
*,
|
*,
|
||||||
expand_repeats: bool = True,
|
expand_repeats: bool = True,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""Convert a GP file to the source game XMLs.
|
"""Convert a GP file to arrangement XMLs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
gp_path: Path to .gp5/.gp4/.gp3 file
|
gp_path: Path to .gp5/.gp4/.gp3 file
|
||||||
|
|||||||
+9
-9
@@ -663,7 +663,7 @@ def list_tracks(gp_path: str) -> list[dict]:
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# convert_file — mirrors gp2rs.convert_file interface
|
# convert_file — mirrors gp2rs.convert_file interface
|
||||||
# Converts GPX tracks directly to the source game XML, reusing gp2rs._build_xml
|
# Converts GPX tracks directly to arrangement XML, reusing gp2rs._build_xml
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -816,7 +816,7 @@ def _collect_tone_events(
|
|||||||
|
|
||||||
def _inject_tones(xml_str: str, tone_events: list[tuple[float, str]]) -> str:
|
def _inject_tones(xml_str: str, tone_events: list[tuple[float, str]]) -> str:
|
||||||
"""
|
"""
|
||||||
Inject a <tones> element into a the source game arrangement XML string.
|
Inject a <tones> element into a chart arrangement XML string.
|
||||||
|
|
||||||
Parses the prettified XML returned by _build_xml, inserts the tones
|
Parses the prettified XML returned by _build_xml, inserts the tones
|
||||||
block before </song>, and re-serialises. Noop if tone_events is empty.
|
block before </song>, and re-serialises. Noop if tone_events is empty.
|
||||||
@@ -1124,7 +1124,7 @@ def convert_file(
|
|||||||
*,
|
*,
|
||||||
expand_repeats: bool = True,
|
expand_repeats: bool = True,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""Convert a .gpx file to the source game XML arrangement files.
|
"""Convert a .gpx file to arrangement XML arrangement files.
|
||||||
|
|
||||||
Mirrors gp2rs.convert_file so the editor plugin can call it transparently.
|
Mirrors gp2rs.convert_file so the editor plugin can call it transparently.
|
||||||
expand_repeats is accepted for API compatibility but repeat expansion from
|
expand_repeats is accepted for API compatibility but repeat expansion from
|
||||||
@@ -1809,10 +1809,10 @@ def _is_vocal_track(track: dict) -> bool:
|
|||||||
|
|
||||||
def _gpx_lyric_to_rs(raw: str) -> str:
|
def _gpx_lyric_to_rs(raw: str) -> str:
|
||||||
"""
|
"""
|
||||||
Convert a GPX lyric token to the source game vocal lyric format.
|
Convert a GPX lyric token to the vocal lyric format.
|
||||||
|
|
||||||
GPX encodes syllable continuation with a trailing hyphen (e.g. "in-", "t-").
|
GPX encodes syllable continuation with a trailing hyphen (e.g. "in-", "t-").
|
||||||
the source game uses the same convention for mid-word syllables. For word-final
|
charts use the same convention for mid-word syllables. For word-final
|
||||||
syllables with no hyphen, RS requires a "+" suffix to signal "connect to
|
syllables with no hyphen, RS requires a "+" suffix to signal "connect to
|
||||||
next syllable without a space" — but only when the next beat is a
|
next syllable without a space" — but only when the next beat is a
|
||||||
continuation of the same word. We handle this at the sequence level in
|
continuation of the same word. We handle this at the sequence level in
|
||||||
@@ -1849,7 +1849,7 @@ def convert_vocal_track(
|
|||||||
arr_name: str = 'Vocals',
|
arr_name: str = 'Vocals',
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Convert a GPX vocal track to a the source game vocals arrangement XML.
|
Convert a GPX vocal track to a chart vocals arrangement XML.
|
||||||
|
|
||||||
Each beat with a lyric and a note becomes a <vocal> element:
|
Each beat with a lyric and a note becomes a <vocal> element:
|
||||||
time — seconds from song start + audio_offset
|
time — seconds from song start + audio_offset
|
||||||
@@ -1864,7 +1864,7 @@ def convert_vocal_track(
|
|||||||
Beats with a lyric but no pitch note are included as pitch-0 rests so the
|
Beats with a lyric but no pitch note are included as pitch-0 rests so the
|
||||||
display timeline stays intact. Beats with no lyric are skipped entirely.
|
display timeline stays intact. Beats with no lyric are skipped entirely.
|
||||||
|
|
||||||
The output is a minimal but valid the source game vocals XML. It does not include
|
The output is a minimal but valid vocals XML. It does not include
|
||||||
ebeats or phrases (RS parses vocal XMLs without them).
|
ebeats or phrases (RS parses vocal XMLs without them).
|
||||||
"""
|
"""
|
||||||
string_pitches = track['string_pitches'] # high→low, standard guitar if vocal
|
string_pitches = track['string_pitches'] # high→low, standard guitar if vocal
|
||||||
@@ -2018,10 +2018,10 @@ def _build_vocals_xml(
|
|||||||
vocals: list[dict],
|
vocals: list[dict],
|
||||||
tempo: int,
|
tempo: int,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Build a the source game vocals arrangement XML string."""
|
"""Build a chart vocals arrangement XML string."""
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
|
|
||||||
# the source game vocals arrangement is a flat <vocals> document — NOT a
|
# vocals arrangement is a flat <vocals> document — NOT a
|
||||||
# <song> wrapper. Every lyric consumer in the codebase keys off the root
|
# <song> wrapper. Every lyric consumer in the codebase keys off the root
|
||||||
# tag being literally "vocals" (lib/loosefolder.py, server.py highway
|
# tag being literally "vocals" (lib/loosefolder.py, server.py highway
|
||||||
# loader), so a <song> root would be silently skipped and the generated
|
# loader), so a <song> root would be silently skipped and the generated
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ def _resolve_audio_asset(zf, root=None) -> tuple[str, str | None]:
|
|||||||
|
|
||||||
# GP8 uses 44100 Hz internally for FrameOffset values regardless of the
|
# GP8 uses 44100 Hz internally for FrameOffset values regardless of the
|
||||||
# OGG file's own sample rate. The embedded OGG is typically 48000 Hz
|
# OGG file's own sample rate. The embedded OGG is typically 48000 Hz
|
||||||
# (the source game's preferred rate) and should be passed through as-is —
|
# (the preferred rate) and should be passed through as-is —
|
||||||
# do NOT resample it. The 44100 constant is only used here to convert
|
# do NOT resample it. The 44100 constant is only used here to convert
|
||||||
# FrameOffset integers to seconds for timing math; it never touches audio.
|
# FrameOffset integers to seconds for timing math; it never touches audio.
|
||||||
# Verified: 44100 gives <10ms sync error; 48000 gives ~530ms error.
|
# Verified: 44100 gives <10ms sync error; 48000 gives ~530ms error.
|
||||||
|
|||||||
+1
-1
@@ -176,7 +176,7 @@ def _arr_type_from_filename(stem: str) -> tuple:
|
|||||||
|
|
||||||
|
|
||||||
def _parse_xml_meta(xml_path: Path) -> dict:
|
def _parse_xml_meta(xml_path: Path) -> dict:
|
||||||
"""Parse a the source game arrangement XML and return song-level metadata."""
|
"""Parse a chart arrangement XML and return song-level metadata."""
|
||||||
try:
|
try:
|
||||||
root = ET.parse(str(xml_path)).getroot()
|
root = ET.parse(str(xml_path)).getroot()
|
||||||
if root.tag != "song":
|
if root.tag != "song":
|
||||||
|
|||||||
+1
-1
@@ -349,7 +349,7 @@ def instrument_for_arrangement(arr_entry) -> str:
|
|||||||
# arrangements often carry a generic type (lead/rhythm/combo) but have a
|
# arrangements often carry a generic type (lead/rhythm/combo) but have a
|
||||||
# name like "Keys" or "Piano". Name overrides the generic type for all
|
# name like "Keys" or "Piano". Name overrides the generic type for all
|
||||||
# well-known non-guitar instruments so that scored keys runs advance the
|
# well-known non-guitar instruments so that scored keys runs advance the
|
||||||
# keys path and quests even when the the source game XML type was not updated.
|
# keys path and quests even when the chart XML type was not updated.
|
||||||
if "bass" in name:
|
if "bass" in name:
|
||||||
return "bass"
|
return "bass"
|
||||||
if "drum" in name or "percussion" in name:
|
if "drum" in name or "percussion" in name:
|
||||||
|
|||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
"""the source game arrangement XML parser and song data models."""
|
"""arrangement XML parser and song data models."""
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -88,7 +88,7 @@ class HandShape:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class PhraseLevel:
|
class PhraseLevel:
|
||||||
"""One difficulty tier's worth of note/chord/anchor/hand-shape data for a
|
"""One difficulty tier's worth of note/chord/anchor/hand-shape data for a
|
||||||
single phrase iteration. the source game's XML stores these as `<level
|
single phrase iteration. the arrangement XML stores these as `<level
|
||||||
difficulty="N">` blocks that repeat for every difficulty tier the chart
|
difficulty="N">` blocks that repeat for every difficulty tier the chart
|
||||||
author wrote; slopsmith used to collapse them to the phrase's
|
author wrote; slopsmith used to collapse them to the phrase's
|
||||||
maxDifficulty and throw the rest away. Keeping them around lets the
|
maxDifficulty and throw the rest away. Keeping them around lets the
|
||||||
@@ -129,7 +129,7 @@ class Arrangement:
|
|||||||
chord_templates: list[ChordTemplate] = field(default_factory=list)
|
chord_templates: list[ChordTemplate] = field(default_factory=list)
|
||||||
# None for single-level sources (GP converter, old sloppaks) — frontends
|
# None for single-level sources (GP converter, old sloppaks) — frontends
|
||||||
# should treat a missing `phrases` as "no per-phrase difficulty data
|
# should treat a missing `phrases` as "no per-phrase difficulty data
|
||||||
# available, disable the slider". Populated from the source game XML when
|
# available, disable the slider". Populated from arrangement XML when
|
||||||
# multiple `<level>` tiers exist.
|
# multiple `<level>` tiers exist.
|
||||||
phrases: list[Phrase] | None = None
|
phrases: list[Phrase] | None = None
|
||||||
# Tone data lifted from the source archive by the sloppak converter and
|
# Tone data lifted from the source archive by the sloppak converter and
|
||||||
@@ -681,7 +681,7 @@ def _int_optional(elem, attr, default=-1):
|
|||||||
|
|
||||||
Use for fields that are merely metadata hints (right-hand fingering,
|
Use for fields that are merely metadata hints (right-hand fingering,
|
||||||
pick direction, etc.) where a malformed value from a third-party
|
pick direction, etc.) where a malformed value from a third-party
|
||||||
the source game XML emitter shouldn't abort the whole arrangement parse.
|
arrangement XML emitter shouldn't abort the whole arrangement parse.
|
||||||
|
|
||||||
Required-field readers (`string`, `fret`, `chordId`, …) keep using
|
Required-field readers (`string`, `fret`, `chordId`, …) keep using
|
||||||
`_int` so a corrupted required attribute still fails fast at parse
|
`_int` so a corrupted required attribute still fails fast at parse
|
||||||
@@ -708,7 +708,7 @@ def _bool(elem, attr):
|
|||||||
|
|
||||||
|
|
||||||
def _hand_shape_arpeggio_flag(elem) -> bool:
|
def _hand_shape_arpeggio_flag(elem) -> bool:
|
||||||
"""the source game / EOF may mark arpeggio on ``<handShape>`` (various casings)."""
|
"""charts / EOF may mark arpeggio on ``<handShape>`` (various casings)."""
|
||||||
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
|
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
|
||||||
if _bool(elem, attr):
|
if _bool(elem, attr):
|
||||||
return True
|
return True
|
||||||
@@ -716,7 +716,7 @@ def _hand_shape_arpeggio_flag(elem) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def _chord_template_arpeggio_flag(elem) -> bool:
|
def _chord_template_arpeggio_flag(elem) -> bool:
|
||||||
"""the source game commonly tags arpeggio templates in ``displayName`` via ``-arp``."""
|
"""charts commonly tag arpeggio templates in ``displayName`` via ``-arp``."""
|
||||||
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
|
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
|
||||||
if _bool(elem, attr):
|
if _bool(elem, attr):
|
||||||
return True
|
return True
|
||||||
@@ -766,7 +766,7 @@ def _parse_note(n) -> Note:
|
|||||||
|
|
||||||
|
|
||||||
def parse_arrangement(xml_path: str) -> Arrangement:
|
def parse_arrangement(xml_path: str) -> Arrangement:
|
||||||
"""Parse a the source game arrangement XML file."""
|
"""Parse a chart arrangement XML file."""
|
||||||
tree = ET.parse(xml_path)
|
tree = ET.parse(xml_path)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
|
|
||||||
@@ -1049,7 +1049,7 @@ def parse_arrangement(xml_path: str) -> Arrangement:
|
|||||||
# wrote at or below this phrase's max — these are what the
|
# wrote at or below this phrase's max — these are what the
|
||||||
# master-difficulty slider selects between at render time.
|
# master-difficulty slider selects between at render time.
|
||||||
# Tiers above max_diff exist in some XMLs (authoring leftovers)
|
# Tiers above max_diff exist in some XMLs (authoring leftovers)
|
||||||
# and are skipped to match the source game's in-game behaviour.
|
# and are skipped to match the reference player's behaviour.
|
||||||
# Capture the extracted slices so the flat max-mastery merge
|
# Capture the extracted slices so the flat max-mastery merge
|
||||||
# below can reuse one of them.
|
# below can reuse one of them.
|
||||||
phrase_levels: list[PhraseLevel] = []
|
phrase_levels: list[PhraseLevel] = []
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ def _convert_riff_wem(data: bytes, output_path: str) -> bool:
|
|||||||
|
|
||||||
if codec == 0xFFFF or codec == 0x0069:
|
if codec == 0xFFFF or codec == 0x0069:
|
||||||
# Wwise Vorbis — audio_data contains raw Ogg pages or encoded Vorbis
|
# Wwise Vorbis — audio_data contains raw Ogg pages or encoded Vorbis
|
||||||
# For the source game custom song, the data is typically packed Vorbis
|
# For custom songs, the data is typically packed Vorbis
|
||||||
# Try writing raw data as OGG (some WEM files have valid OGG inside)
|
# Try writing raw data as OGG (some WEM files have valid OGG inside)
|
||||||
if _try_extract_ogg_pages(audio_data, output_path):
|
if _try_extract_ogg_pages(audio_data, output_path):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Pins the fret-spacing setting in plugins/highway_3d/screen.js (PR #329).
|
// Pins the fret-spacing setting in plugins/highway_3d/screen.js (PR #329).
|
||||||
// The board can render fret columns either Uniform (equal width, the source game
|
// The board can render fret columns either Uniform (equal width, the chart
|
||||||
// Remastered style) or Logarithmic (real instrument geometry), switchable at
|
// Remastered style) or Logarithmic (real instrument geometry), switchable at
|
||||||
// runtime via window.h3dSetFretSpacing and persisted in localStorage. A
|
// runtime via window.h3dSetFretSpacing and persisted in localStorage. A
|
||||||
// refactor that renames the storage key, drops the uniform/log branch in
|
// refactor that renames the storage key, drops the uniform/log branch in
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ def test_year_sort_asc_oldest_first(client, seeded):
|
|||||||
|
|
||||||
def test_tuning_sort_down_tuned_before_up_tuned_at_same_distance(client, server_mod):
|
def test_tuning_sort_down_tuned_before_up_tuned_at_same_distance(client, server_mod):
|
||||||
"""Within an ABS(tuning_sort_key) tier, the down-tuned variant
|
"""Within an ABS(tuning_sort_key) tier, the down-tuned variant
|
||||||
must come before the up-tuned one so the order matches the source game's
|
must come before the up-tuned one so the order matches the chart's
|
||||||
grouping (Eb Standard before F Standard at distance 6, etc.).
|
grouping (Eb Standard before F Standard at distance 6, etc.).
|
||||||
Earlier code used signed-key DESC for the tiebreaker, which put
|
Earlier code used signed-key DESC for the tiebreaker, which put
|
||||||
+6 before -6 — the opposite of intent. Regression for Copilot
|
+6 before -6 — the opposite of intent. Regression for Copilot
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ def test_int_optional_falls_back_on_overflow():
|
|||||||
def test_parse_note_falls_back_to_default_on_malformed_numeric_attrs():
|
def test_parse_note_falls_back_to_default_on_malformed_numeric_attrs():
|
||||||
"""Malformed numeric XML attributes degrade gracefully.
|
"""Malformed numeric XML attributes degrade gracefully.
|
||||||
|
|
||||||
Third-party the source game XML occasionally emits empty / non-numeric
|
Third-party arrangement XML occasionally emits empty / non-numeric
|
||||||
values for fields like `rightHand`. `_int_optional` (used for
|
values for fields like `rightHand`. `_int_optional` (used for
|
||||||
optional metadata fields like `rightHand` and `pickDirection`)
|
optional metadata fields like `rightHand` and `pickDirection`)
|
||||||
falls back to the caller's default instead of raising, so a
|
falls back to the caller's default instead of raising, so a
|
||||||
|
|||||||
Reference in New Issue
Block a user