NoteLanes
namespace Griff.Modules.Rhythm;
public sealed class NoteLanes : Component, IDrawable, IPlaytestReportA rhythm game’s lanes, with no code: notes from a chart (a table of beats and lanes) scroll toward a hit line in time with the music, and the player presses each lane’s key, button or touch zone as its notes reach the line, holding a hold note down until its end. Each press is judged by how far it is from the note’s beat as the player hears it (their audio offset allowed for), Perfect, Great, Good or Miss, which adds to the Score, the Combo and the Accuracy, pops up over the lanes and sends a message for anything else in the game to act on.
The chart is a table (Data > New Table, or Entity > Genres > Rhythm > Create Note Lanes, which makes one with a song): a row a note, with its Beat (counting from 0, the music’s first, as a BeatClock counts), its Lane (1 for the first), a Hold in beats for a note to hold down (empty or 0 for a tap) and the Difficulty it’s in (empty for every one; “Easy, Normal” for two). It plays its Song (or keeps time with the music playing) by its BeatClock, drawing the notes ahead by the player’s visual offset so they cross the line as the beat is heard, and judging each press by the beat as it’s heard. It starts as it’s shown (its Start action starts it again, Play at a difficulty), pauses with the game, and says when the song is over with its CompleteMessage. Each machine of a network game plays its own player’s lanes and judges them there; what they score goes to the host, which sends the messages and adds the points to that player’s score.
This is a component: its saved properties are on its component page.
Properties
Section titled “Properties”Accuracy
Section titled “Accuracy”public float Accuracy { get; }How well it’s going, from 0 to 100: the points scored out of what Perfects all along would have scored. 100 before the first note.
Actions
Section titled “Actions”public string? Actions { get; set; }The input actions that press the lanes, the first lane’s first, separated by commas: Lane1 to Lane4 are D, F, J and K, the arrows, and the D-pad or the face buttons. A lane without one is pressed by touch alone.
public int Best { get; set; }The best score kept for the song and difficulty it plays (see SaveBestAs), 0 before any: this play’s once it’s over and beats it. Set by the game.
BestCombo
Section titled “BestCombo”public int BestCombo { get; set; }The longest combo so far.
public string? Chart { get; set; }The table of notes to play: a row a note, with a Beat, a Lane (from 1), a Hold in beats (empty for a tap) and the Difficulty it’s in (empty for all). Empty: the table named like the Song (or the music playing).
Clicks
Section titled “Clicks”public bool Clicks { get; set; }A click or a tap on a lane presses it, and on a touch screen each finger on one does, so chords and holds play by touch.
public string? Clock { get; set; }The entity whose BeatClock times the notes. Empty: its own, or else the scene’s first.
Colors
Section titled “Colors”public string? Colors { get; set; }The notes’ colors, a lane each from the first, as hex colors separated by spaces (“#F2607E #F2BC4B”), round again for more lanes than colors.
public int Combo { get; set; }Hits in a row since the last Miss (a hold’s end counts as one).
CompleteMessage
Section titled “CompleteMessage”public string? CompleteMessage { get; set; }A message sent once the song is over (every note judged, and its song done), with the score as its data: a panel with this as its Open Message shows the results.
Controllable
Section titled “Controllable”public bool Controllable { get; set; }Untick it to have the lanes ignore the keys, mouse, touches and gamepad while the song plays on: another part of the scene has the player’s input. Its Focus action ticks it and unticks it on everything else the player plays.
Difficulty
Section titled “Difficulty”public string? Difficulty { get; set; }Which of the chart’s difficulties to play, e.g. “Hard”: its notes whose Difficulty names it, and those that name none. Empty plays only the notes that name none.
Direction
Section titled “Direction”public NoteDirection Direction { get; set; }Which way the notes travel to the hit line.
FullCombo
Section titled “FullCombo”public bool FullCombo { get; }True while every note judged so far was hit (one at least, and no Miss): a “Full combo!” on the results.
GoodWindow
Section titled “GoodWindow”public float GoodWindow { get; set; }A press this close, in milliseconds, is Good. A note this late with no press is a Miss.
public int Goods { get; set; }How many Goods so far.
public string Grade { get; }A letter for the Accuracy: S from 95, A from 90, B from 80, C from 70, D below (empty before the first note).
GreatWindow
Section titled “GreatWindow”public float GreatWindow { get; set; }A press this close, in milliseconds, is Great.
Greats
Section titled “Greats”public int Greats { get; set; }How many Greats so far.
HitLine
Section titled “HitLine”public float HitLine { get; set; }How far the hit line is from the end of the lanes the notes travel to, in world units.
HitMessage
Section titled “HitMessage”public string? HitMessage { get; set; }A message sent on each Perfect, Great and Good, with the points it scored as its data: a Counter listening for it adds up the score, and a Trigger can fire a weapon on it.
HitSound
Section titled “HitSound”public string? HitSound { get; set; }A sound played on each hit (not a Miss), e.g. “Sounds/tick.wav”. Empty plays none: the music is the sound.
IsPlaying
Section titled “IsPlaying”public bool IsPlaying { get; set; }True while its chart plays. Saved with the scene, so a rewind carries the song on from there.
Judgment
Section titled “Judgment”public string Judgment { get; }The last judgment, “Perfect”, “Great”, “Good” or “Miss” (empty before the first).
LaneColor
Section titled “LaneColor”public Color LaneColor { get; set; }The lanes’ own color, behind the notes. Transparent draws none.
LaneWidth
Section titled “LaneWidth”public float LaneWidth { get; set; }How wide each lane is, in world units.
public int Lanes { get; set; }How many lanes, side by side.
Length
Section titled “Length”public float Length { get; set; }How long the lanes are, from where the notes come in to the far end past the hit line, in world units.
MissMessage
Section titled “MissMessage”public string? MissMessage { get; set; }A message sent on each Miss.
MissSound
Section titled “MissSound”public string? MissSound { get; set; }A sound played on each Miss.
MissWindow
Section titled “MissWindow”public float MissWindow { get; set; }A press earlier than the Good Window but this close, in milliseconds, is a Miss: pressed too soon. Further off, a press isn’t taken for that note at all.
Misses
Section titled “Misses”public int Misses { get; set; }How many Misses so far.
NewBest
Section titled “NewBest”public bool NewBest { get; set; }True once the song is over with a score beating the best kept for it: a “New best!” on the results. Set by the game.
public int Notes { get; }How many notes the chart it plays has (a hold is one note, judged as it’s pressed and at its end).
public int Order { get; set; }Higher draws on top, like Order (an entity’s sprite says for it).
PerfectMessage
Section titled “PerfectMessage”public string? PerfectMessage { get; set; }A message sent on each Perfect, as well as the HitMessage: for a bonus.
PerfectWindow
Section titled “PerfectWindow”public float PerfectWindow { get; set; }A press this close to a note’s beat (early or late), in milliseconds, is Perfect.
Perfects
Section titled “Perfects”public int Perfects { get; set; }How many Perfects so far.
Played
Section titled “Played”public string? Played { get; set; }How each note went, in the chart’s order, two marks a note (the press, then a hold’s end): . not yet, P Perfect, G Great, O Good, M Miss, S left out (gone by before it started), - no end (a tap). The game sets it; a rewind takes it back.
PlayingDifficulty
Section titled “PlayingDifficulty”public string PlayingDifficulty { get; }The difficulty it plays: a saved one (see SavedDifficulty), or its Difficulty.
PopSize
Section titled “PopSize”public float PopSize { get; set; }How big the judgment that pops up as a note is hit (and the combo under it) is drawn, in world units. 0 shows none.
Progress
Section titled “Progress”public float Progress { get; }How far through the chart it is, from 0 at the start of the song to 1 at its last note’s end: a bar shows it.
SaveBestAs
Section titled “SaveBestAs”public string? SaveBestAs { get; set; }A name to keep the best score of each song and difficulty under in the save data, with its grade: “Best” keeps a Normal play of the Groove chart as “Best.Groove.Normal” (and “Best.Groove.Normal.Grade”), which Best and a SongSelect show. Empty keeps none.
SavedDifficulty
Section titled “SavedDifficulty”public string? SavedDifficulty { get; set; }A value a menu saved (a Choice’s or a SongSelect’s Save As, e.g. “difficulty”) naming the difficulty to play, when the chart has it; Difficulty otherwise.
SavedSong
Section titled “SavedSong”public string? SavedSong { get; set; }A name in the save data holding the song to play, e.g. “Song” (where a SongSelect keeps the one picked): while a song is saved there it’s played in place of Song, with its own chart (the table named like it).
public int Score { get; set; }The points scored: 300 a Perfect, 200 a Great, 100 a Good.
public string? Song { get; set; }The song to play, e.g. “Music/song.wav”: from the start as the lanes start, once through. Its chart is the table named like it (Music/Groove.wav plays the Groove table) unless Chart says. Empty keeps time with the music playing (a Background Music’s), or with none, clicks a metronome at its clock’s tempo.
SongTime
Section titled “SongTime”public float SongTime { get; set; }Seconds into its Song it has got to. The game sets it, so a rewind or a pause carries the song on from there.
public float Speed { get; set; }How fast the notes come, in world units a second: faster spreads them out. Each player can make it faster or slower still with their own note speed (Game.NoteSpeed, which a slider can set).
StartOnShow
Section titled “StartOnShow”public bool StartOnShow { get; set; }Starts as soon as it’s shown (as the scene starts, or its panel opens). Off, it waits for its Start or Play action.
Timing
Section titled “Timing”public float Timing { get; }How far the last press that was taken for a note was from its beat as the player heard it, in milliseconds: below 0 early, above 0 late. For an “Early” or “Late” under the judgment, or to see whether a player’s offset needs setting.
public string Title { get; }The name of the chart it plays (its song’s, “Groove” for Music/Groove.wav): a title over the lanes or on the results.
Volume
Section titled “Volume”public float Volume { get; set; }How loud its Song plays, 0 to 1, on top of the player’s music volume.
Methods
Section titled “Methods”ActionOf
Section titled “ActionOf”public string? ActionOf(int lane)The action that presses lane lane (from 0), or null for none.
BestKey
Section titled “BestKey”public static string BestKey(string saveAs, string chart, string? difficulty)The name in the save data the best score of chart at difficulty is kept under by lanes whose Save Best As is saveAs: “Best.Groove.Normal” (its grade under the same with “.Grade”).
ColorOf
Section titled “ColorOf”public Color ColorOf(int lane)The color of lane lane’s notes (from 0).
GradeFor
Section titled “GradeFor”public static string GradeFor(float accuracy)The grade an accuracy (0 to 100) gets: S from 95, A from 90, B from 80, C from 70, D below.
JudgmentColor
Section titled “JudgmentColor”public static Color JudgmentColor(NoteJudgment judgment)The color a judgment pops up in.
JudgmentFor
Section titled “JudgmentFor”public NoteJudgment JudgmentFor(float milliseconds)How a press milliseconds from a note’s beat (below 0 early, above late) is judged by its windows: None when it’s too far off to be taken for that note.
public void Play(string difficulty)Starts the chart from the top at difficulty (e.g. “Hard”), which becomes its Difficulty.
PointsFor
Section titled “PointsFor”public static int PointsFor(NoteJudgment judgment)The points a judgment scores.
SetupNote
Section titled “SetupNote”public override string? SetupNote()public void Start()Starts the chart from the top, at its Difficulty: the song from its start, the score at 0.
public void Stop()Stops the chart where it is, and its song.
Events
Section titled “Events”Completed
Section titled “Completed”public event Action<NoteLanes>? CompletedRaised once the song is over, every note judged.
Judged
Section titled “Judged”public event Action<NoteJudgment, int>? JudgedRaised as a note is judged (a hold twice: as it’s pressed and at its end), with the lane it’s in (from 0).
Fields
Section titled “Fields”GoodPoints
Section titled “GoodPoints”public const int GoodPointsPoints for a Perfect, a Great and a Good.
GreatPoints
Section titled “GreatPoints”public const int GreatPointsPoints for a Perfect, a Great and a Good.
JudgmentNames
Section titled “JudgmentNames”public static readonly IReadOnlyList<string> JudgmentNamesThe name of a judgment, as Judgment says it.
PerfectPoints
Section titled “PerfectPoints”public const int PerfectPointsPoints for a Perfect, a Great and a Good.