···11+//! Defines the structure of a map's difficulty file(s) (i.e. `ExpertStandard.dat`).
22+13pub mod gameplay_event;
24pub mod lightshow;
35pub mod playfield;
···2830 /// | 3.2 | Translation events. | Yes |
2931 /// | 3.3 | More strobe functionality. | No |
3032 /// | 4.X | New template-like format. | No |
3333+ ///
3434+ /// [^1]: Not supported by experimental lighting calculation methods.
3135 pub version: String,
3236 pub bpm_events: Vec<BpmEvent>,
3337 #[serde(rename = "rotationEvents")]
+2
src/difficulty/gameplay_event.rs
···11+//! Events that effect gameplay and aren't purely visual.
22+13use crate::{impl_timed, loose_enum};
24use serde::{Deserialize, Serialize};
35
+2
src/difficulty/lightshow.rs
···11+//! Events that have no effect on gameplay.
22+13pub mod basic;
24pub mod boxes;
35pub mod easing;
+48-2
src/difficulty/playfield.rs
···11+//! The interactable objects of a difficulty.
22+13use crate::{impl_duration, impl_timed, loose_enum};
24use serde::{Deserialize, Serialize};
3566+/// The standard block/note.
47#[doc(alias = "Block")]
58#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
69#[cfg_attr(
···912 reflect(Debug, Clone, PartialEq)
1013)]
1114pub struct Note {
1515+ /// The position of the object in time.
1216 #[serde(rename = "b")]
1317 pub beat: f32,
1818+ /// A value representing the vertical position of the object.
1919+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
1420 #[serde(rename = "y")]
1521 pub row: i32,
2222+ /// A value representing the horizontal position of the object.
2323+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
1624 #[serde(rename = "x")]
1725 pub col: i32,
1826 #[serde(rename = "c")]
1927 pub color: NoteColor,
2028 #[serde(rename = "d")]
2129 pub direction: CutDirection,
3030+ /// The number of degrees counter-clockwise to offset the object by.
2231 #[serde(rename = "a")]
2332 pub angle_offset: f32,
2433}
···2635impl_timed!(Note::beat);
27362837loose_enum! {
3838+ /// The color of a note, which determines which saber should be used to cut it.
2939 #[derive(Default, Copy)]
3040 NoteColor: i32 {
3141 #[default]
···3545}
36463747loose_enum! {
4848+ /// The direction a note should be cut.
3849 #[derive(Default, Copy)]
3950 CutDirection: i32 {
4051 #[default]
···5162}
52635364impl CutDirection {
5454- /// Returns the number of degrees a note is rotated, with zero degrees being downward note.
5555- /// Returns zero if the cut direction is unknown.
6565+ /// Returns the number of degrees a note is rotated, with zero degrees being a downward note.
6666+ ///
6767+ /// Returns zero if the cut direction is unknown/any.
5668 pub fn get_degrees(&self) -> f32 {
5769 match self {
5870 CutDirection::Up => 180.0,
···7688 reflect(Debug, Clone, PartialEq)
7789)]
7890pub struct Bomb {
9191+ /// The position of the object in time.
7992 #[serde(rename = "b")]
8093 pub beat: f32,
9494+ /// A value representing the vertical position of the object.
9595+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
8196 #[serde(rename = "y")]
8297 pub row: i32,
9898+ /// A value representing the horizontal position of the object.
9999+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
83100 #[serde(rename = "x")]
84101 pub col: i32,
85102}
···94111 reflect(Debug, Clone, PartialEq)
95112)]
96113pub struct Wall {
114114+ /// The start position of the object in time.
97115 #[serde(rename = "b")]
98116 pub beat: f32,
117117+ /// The length (in beats) that an object takes place.
99118 #[serde(rename = "d")]
100119 pub duration: f32,
120120+ /// A value representing the vertical position of the object.
121121+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
101122 #[serde(rename = "y")]
102123 pub row: i32,
124124+ /// A value representing the horizontal position of the object.
125125+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
103126 #[serde(rename = "x")]
104127 pub col: i32,
105128 #[serde(rename = "w")]
···131154 reflect(Debug, Clone, PartialEq)
132155)]
133156pub struct Arc {
157157+ /// The start position of the object in time.
134158 #[serde(rename = "b")]
135159 pub beat: f32,
160160+ /// A value representing the vertical starting position of the object.
161161+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
136162 #[serde(rename = "y")]
137163 pub row: i32,
164164+ /// A value representing the horizontal starting position of the object.
165165+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
138166 #[serde(rename = "x")]
139167 pub col: i32,
140168 #[serde(rename = "c")]
141169 pub color: NoteColor,
142170 #[serde(rename = "d")]
143171 pub direction: CutDirection,
172172+ /// Controls how far away the starting bezier control point is in [cut direction](Self::direction).
144173 #[serde(rename = "mu")]
145174 pub control_point: f32,
146175176176+ /// The end position of the object in time.
147177 #[serde(rename = "tb")]
148178 pub tail_beat: f32,
179179+ /// A value representing the vertical ending position of the object.
180180+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
149181 #[serde(rename = "ty")]
150182 pub tail_row: i32,
183183+ /// A value representing the horizontal ending position of the object.
184184+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
151185 #[serde(rename = "tx")]
152186 pub tail_col: i32,
153187 #[serde(rename = "tc")]
154188 pub tail_direction: CutDirection,
189189+ /// Controls how far away the ending bezier control point is in [tail cut direction](Self::tail_direction).
155190 #[serde(rename = "tmu")]
156191 pub tail_control_point: f32,
157192···198233 reflect(Debug, Clone, PartialEq)
199234)]
200235pub struct Chain {
236236+ /// The start position of the object in time.
201237 #[serde(rename = "b")]
202238 pub beat: f32,
239239+ /// A value representing the vertical starting position of the object.
240240+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
203241 #[serde(rename = "y")]
204242 pub row: i32,
243243+ /// A value representing the horizontal starting position of the object.
244244+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
205245 #[serde(rename = "x")]
206246 pub col: i32,
207247 #[serde(rename = "c")]
···209249 #[serde(rename = "d")]
210250 pub direction: CutDirection,
211251252252+ /// The end position of the object in time.
212253 #[serde(rename = "tb")]
213254 pub tail_beat: f32,
255255+ /// A value representing the vertical ending position of the object.
256256+ /// In the range 0..2 inclusive, with zero being the bottom and two being the top row.
214257 #[serde(rename = "ty")]
215258 pub tail_row: i32,
259259+ /// A value representing the horizontal ending position of the object.
260260+ /// In the range 0..3 inclusive, with zero being the far left and three being the far right column.
216261 #[serde(rename = "tx")]
217262 pub tail_col: i32,
218263264264+ /// The number of links the chain has, including the connected [`Note`].
219265 #[serde(rename = "sc")]
220266 pub link_count: i32,
221267 #[serde(rename = "s")]
+17-1
src/info.rs
···11+//! Defines the structure of a map's `Info.dat` file.
22+13pub mod color_scheme;
2435pub use color_scheme::*;
···1416pub struct Beatmap {
1517 /// The info file version, in the form of `2.1.0`.
1618 ///
1717- /// ### Info File
1919+ /// ### Version Support
1820 ///
1921 /// | Version | Description | Supported |
2022 /// |---------|-----------------------------------------------|-----------|
···6769}
68706971loose_enum! {
7272+ /// The world that surrounds the player and defines which lights are available.
7373+ ///
7474+ /// For 90/360 degree mode, see [`AllDirectionEnvironment`].
7075 #[derive(Default)]
7176 Environment: String {
7277 #[default]
···121126}
122127123128loose_enum! {
129129+ /// The world that surrounds the player while playing 90/360 degree mode.
130130+ ///
131131+ /// For standard mode, see [`Environment`].
124132 #[derive(Default)]
125133 AllDirectionEnvironment: String {
126134 #[default]
···128136 }
129137}
130138139139+/// Describes a group of difficulties, all with the same [characteristic/mode](Characteristic).
131140#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
132141#[cfg_attr(
133142 feature = "bevy_reflect",
···142151}
143152144153loose_enum! {
154154+ /// Describes the type/game mode of a difficulty.
155155+ ///
156156+ /// Note that [`Lawless`](Self::Lawless) and [`Lightshow`](Self::Lightshow) are modded characteristics,
157157+ /// and may cause problems in un-modded versions of the game.
145158 #[derive(Default)]
146159 Characteristic: String {
147160 #[default]
···158171 }
159172}
160173174174+/// Describes the settings for a difficulty.
175175+///
176176+/// Note that a difficulties [characteristic](Characteristic) is defined by its [`DifficultySet`].
161177#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
162178#[cfg_attr(
163179 feature = "bevy_reflect",
+11
src/info/color_scheme.rs
···1818 pub color_scheme: ColorScheme,
1919}
20202121+/// Describes the colors of objects a lights for an environment/map.
2222+///
2323+/// This does *not* currently support while light color overrides.
2124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2225#[cfg_attr(
2326 feature = "bevy_reflect",
···2629)]
2730#[serde(rename_all = "camelCase")]
2831pub struct ColorScheme {
3232+ /// The name of the color scheme.
2933 #[serde(rename = "colorSchemeId")]
3034 pub id: String,
3535+ /// The color for the left saber/notes. Default is red.
3136 #[doc(alias = "saber_left")]
3237 #[serde(rename = "saberAColor")]
3338 pub note_left: Color,
3939+ /// The color for the right saber/notes. Default is blue.
3440 #[doc(alias = "saber_right")]
3541 #[serde(rename = "saberBColor")]
3642 pub note_right: Color,
37434444+ /// The color of walls/obstacles.
3845 #[doc(alias = "obstacle")]
3946 #[serde(rename = "obstaclesColor")]
4047 pub wall: Color,
41484949+ /// The primary light color, often matching the [left note color](Self::note_left).
4250 #[doc(alias = "environment0")]
4351 #[serde(rename = "environmentColor0")]
4452 pub light_primary: Color,
5353+ /// The secondary light color, often matching the [right note color](Self::note_right).
4554 #[doc(alias = "environment1")]
4655 #[serde(rename = "environmentColor1")]
4756 pub light_secondary: Color,
48575858+ /// The primary light color when [boost colors](crate::ColorBoostEvent) are enabled.
4959 #[doc(alias = "environment_boost_0")]
5060 #[serde(rename = "environmentColor0Boost")]
5161 pub boost_light_primary: Color,
6262+ /// The secondary light color when [boost colors](crate::ColorBoostEvent) are enabled.
5263 #[doc(alias = "environment_boost_1")]
5364 #[serde(rename = "environmentColor1Boost")]
5465 pub boost_light_secondary: Color,
+4
src/info/color_scheme/presets.rs
···5757}
58585959impl Environment {
6060+ /// Returns the default color scheme for an environment.
6161+ ///
6062 /// Values taken from [the wiki](https://bsmg.wiki/mapping/lighting-defaults.html#current-colors)
6163 /// and Kival Evan's [Typescript library](https://github.com/KivalEvan/BeatSaber-JSMap/blob/ef8afc42ab90e2f1100f1a163fa810ec56b6a9f8/src/beatmap/shared/colorScheme.ts).
6264 ///
···404406}
405407406408impl AllDirectionEnvironment {
409409+ /// Returns the default color scheme for a 90/360 degree environment.
410410+ ///
407411 /// Value taken from [the wiki](https://bsmg.wiki/mapping/lighting-defaults.html#current-colors).
408412 ///
409413 /// ChatGPT was used to help translate between formats, so there could be hallucinations.
+2
src/timing_traits.rs
···11+//! Traits that are used to get an object's position in time and duration.
22+13/// Represents any beatmap object that happens at a specific beat.
24pub trait Timed {
35 /// Returns the beat that an object takes place.