The Two Windows#
Dance Machine has two interfaces, and it helps to know which is which from the start.
Window | Opened with | What it is for |
|---|---|---|
The song menu |
| Everything a player does: pick a track, a difficulty, a mode and a stage, and open their profile, the ranking and their key bindings. |
The admin panel |
| One window with two tabs: Machines, where cabinets are placed and edited, and Music, where songs are generated and edited. Each command opens on its own tab. |
Machines, song details and charts are saved to the database and pushed to every connected player the moment you save. Nothing in this page needs a restart, except adding a brand-new audio file.
What a Fresh Server Opens With#
Nineteen original tracks, each with Easy, Normal and Hard charts already generated once database/sql.sql has been imported. No machine is placed: the first one is yours to put wherever your arcade, club or bar is.
Track | Artist | BPM | Length |
|---|---|---|---|
404:Heart.exe | NEKØBYTE | 99 | 1:21 |
Arcade Fantasy | Neon Gravity | 131 | 1:31 |
Binary Dreams | ARCFLOW | 144 | 2:03 |
Cosmic Bounce | Eclipse Motion | 137 | 2:58 |
Crystal Pulse | Zenith Avenue | 148 | 2:29 |
Crystal Rain | Juno | 131 | 2:49 |
Destiny Machine | Nova Sphere | 131 | 2:48 |
Digital Bloom | Iris Vector | 128 | 1:47 |
Flash Memory | Pixel Horizon | 131 | 2:35 |
Ghost in the Broadcast | VANTA | 117 | 2:31 |
Horror Show | District | 113 | 3:00 |
Last Token | S!GNAL | 144 | 2:11 |
Marionette's Last Smile | Hollow Choir | 131 | 3:20 |
Midnight Tokyo | Azure Reactor | 125 | 1:50 |
Neon Horizon | Eclipse Drive | 117 | 0:45 |
Night Voltage | Arcadia Future | 122 | 2:22 |
Parallel Hearts | Polaris Fiction | 117 | 2:06 |
Silent Motion | Atlas Project | 117 | 0:53 |
Velocity Zero | Quantum Pop | 128 | 2:33 |
Placing a Machine#
/dancecreator → Machines → +. Fill in the form, then press Select under Placement: the window closes and a see-through cabinet follows wherever your camera points. Nothing about a machine is ever typed as a coordinate.
Key | Does |
|---|---|
Mouse | Aim the ghost: it sits on whatever surface the camera looks at, up to 50 m away. |
| Confirm the position. |
| Hold to rotate, at |
Mouse wheel | Raise or lower it, |
| Cancel and go back to the form. |
The heading and height offset are shown at the top of the screen while you work, and the buttons along the bottom always show the keys that work right now.
The form#
Section | What you set there |
|---|---|
Machine Info | The name shown in the creator's list. |
Players | 1 Player — one pad, solo only. 2 Players — two pads, which is what makes Duo and Versus possible. The default is two. |
Pricing | What a game costs and whether it is paid in Cash Money or by Bank Transfer. 0 is free to play. |
Game Modes | Which of Single, Versus and Co-op (Duo) players may start here. All three are on by default. |
Placement | Select the first time, Re-select to place it again. |
Save Machine spawns it for every player within Config.StreamDistance and stores it in dance_machines, so it is back after every restart.
Managing machines#
The list on the left holds every machine with a search box. Each card can teleport you to it (after a confirmation), and selecting one opens it for editing: change any field, Reposition it, Save Changes or Delete it.
Machines in the config file#
Machines can also be listed in Config.Machines. They are created on every start from the file and are not written to the database, so the creator is the better home for anything you expect to move.
Config.Machines = {
{
coords = vec3(-1371.56, -470.58, 71.03),
heading = 145.0,
label = 'Legion Square',
players = 2, -- 1 = solo only, 2 = enables Duo and Versus
price = 0,
paymentMethod = 'money', -- 'money' (cash) or 'bank'
allowedModes = { 'solo', 'duo', 'versus' },
},
}Where the players stand#
Config.Pads holds where each player is put on the cabinet, relative to the prop: one position for a 1-player machine and two for a 2-player one. A vec3 faces the player towards the machine on its own; a vec4 forces the heading. The shipped values fit the included cabinet. If you swap the model, stand at a machine and use /dancepad — see Commands and Exports.
Adding Songs#
Any song you have the rights to can become a playable chart. The script listens to the audio and writes the notes itself.
Copy the audio into songs/
MP3, OGG or WAV, in either layout:
lua songs/ ├── My_Track.mp3 -- a file on its own: the song id is My_Track └── my_track/ └── song.mp3 -- a folder: the song id is the folder nameInside a folder the script looks for
song.mp3,song.oggorsong.wavfirst, then any audio file.Restart the resource
restart qs-dancemachine. The folder is read once when the resource starts, and the game only serves files that were there at that moment. The console reports how many songs it found.Generate it
/dancemusiclists the new song marked not generated. Select it, type its name and artist, choose the difficulties players may pick, and press Generate.Play it
When the analysis finishes, the chart is saved and the song appears on every machine at once — for players already standing at one, too.
The song id is the file or folder name. Letters, digits, _ and - are kept as they are; spaces, accents and symbols are turned into underscores, and when the resource stops such files are renamed on disk so they can be served. Mi Canción (Remix).mp3 becomes Mi_Cancion_Remix.mp3. Players never see the id — they see the name you type.
How a chart is generated#
Generation runs inside the game of the admin who presses the button, not on the server, so it costs the server nothing. An overlay follows it stage by stage — it takes from a few seconds to about a minute, depending on the track:
Stage | What happens |
|---|---|
Decoding audio | The file is loaded and mixed down to one channel. |
Spectral analysis (FFT) | The track is split into frequencies, frame by frame. |
Detecting onsets | Every drum hit and attack is found. |
Tracking beats | The tempo is measured — this is the BPM the song menu shows. |
Placing notes | Each difficulty picks the strongest hits it can fit, spreads them over the six lanes and turns some into hold notes. |
Saving beatmap | The server checks the chart, stores it in |
Tracks with a clear, steady beat give the best charts. A song that is silent, very short or has no beat the analysis can follow is refused with a reason — see Common Errors. Only one admin can generate a given song at a time.
Editing a song#
Field | What it does |
|---|---|
Song name · Artist | What players see in the song menu, the results and the rankings. Up to 80 characters each. |
BPM | Measured during generation and used to time the cameras and dance moves. Before a song is generated you can set it by hand. |
Start · End | The part of the track that is played, as mm:ss or by dragging the timeline and pressing Set as start / Set as end. AUTO plays to the end. Notes outside the window are dropped, and the preview in the song menu starts at Start. Available once the song is generated. |
Difficulties | Which of Easy, Normal and Hard players may choose. At least one always stays available. |
Save Changes applies the details at once. Regenerate analyses the track again — useful after changing Config.Beatmap. Delete takes the song out of the game: its chart is cleared and it leaves every machine's list, but it stays in the Music Manager, ready to be generated again. To remove a track for good, delete its file from songs/ and restart.
Difficulties and star levels#
How dense each difficulty is comes from Config.Beatmap:
Difficulty | maxNps | minGapMs | jumps |
|---|---|---|---|
Easy | 0.9 | 650 | false |
Normal | 1.35 | 440 | false |
Hard | 2.0 | 300 | false |
maxNps is the most notes a second, minGapMs the shortest gap between two notes, and jumps allows two notes at once on the strongest hits. Each chart then gets a star level from 1 to 20, worked out from its notes per second, the tempo and the length — so a fast, long Hard song rates higher than a slow, short one. A change to Config.Beatmap applies to songs generated or regenerated afterwards.
Playing#
A player walks up to a machine and presses E at the [E] - Pump It Up prompt — or uses the ox_target option, when target is on. A dancer moves behind the menu while a preview of the selected track plays.
Key | Track list | Mode list | Start screen |
|---|---|---|---|
| Browse the songs | Choose a mode | Start or Return |
| Choose the difficulty | — | Choose the stage |
| Continue to the modes | Continue to the Start screen | Play |
| Settings: profile, ranking, keybinds | — | — |
| Leave the machine | Back to the tracks | Back to the modes |
Every song shows its star level and BPM. A song the player has never played carries a NEW badge; one they have played shows their best grade. Walking away from the machine closes the menu.
The lanes and keys#
Notes fly out from the centre of the screen towards six targets, three on each side, and are hit as they reach them:
Left side | Default key | Right side | Default key |
|---|---|---|---|
Upper left |
| Upper right |
|
Left |
| Right |
|
Lower left |
| Lower right |
|
Each player can rebind them in Settings → Keybinds: pick a lane, press the new key, and R puts the defaults back. Bindings are saved on the player's own PC. The defaults every player starts with are Config.DefaultKeys, written as browser key codes — 'KeyW', 'ArrowUp', 'Space'.
Notes, judgments and score#
There are three kinds of note. A tap is pressed once. A hold is pressed and kept down until its tail arrives — letting go early counts as a Miss. A bonus note, about one tap in 26, is worth 2.5× the points. Every hit is judged by how close it lands to the beat:
Judgment | Window | Points | Life |
|---|---|---|---|
PERFECT | ± 45 ms | 100% | +2 |
GREAT | ± 90 ms | 75% | +1 |
GOOD | ± 135 ms | 40% | 0 |
BAD | ± 180 ms | 10% | −4 |
MISS | Later, or never | 0 | −8 |
A note is worth 1,000 points times its judgment, times the combo multiplier, which grows by 5% every 25 notes in a row up to 2×. A Miss breaks the combo. The life bar starts at 50 of 100; if it empties, the stage is failed. Every one of these numbers lives in Config.Gameplay — life.failEnabled = false lets every song be played to the end.
The run ends with a grade by accuracy:
SSS | SS | S | A | B | C | D | F |
|---|---|---|---|---|---|---|---|
99% | 97% | 94% | 88% | 80% | 70% | Below 70% | Stage failed |
ESC or BACKSPACE during a song asks whether to quit; a quit run is not saved. On the results screen, ENTER goes back to the music list and G plays the same song again. A new personal best or server record is announced right there.
Game Modes#
Mode | How it plays |
|---|---|
Single | One player, all six lanes. |
Duo | Co-op. Pad 1 plays the left side ( |
Versus | Both players play every lane of the same chart, with the rival's score and combo live on screen. The higher score wins — ties go to accuracy, then max combo, then a draw. Failing or quitting is an instant loss. |
Duo and Versus need a 2 Players machine that allows them and a second player at the song menu; until then they show FREE PAD and cannot be picked. A two-player game goes like this:
One player chooses
Whoever moves on to the modes first holds the selection; the other is asked to wait until they finish. They choose the track, difficulty, mode and stage, and press Start.
The partner is invited
The other player sees an invitation with the song and the stage the host chose, and accepts with Start or declines with Return. An invitation left unanswered expires after
Config.Multiplayer.inviteTimeoutMs(30 seconds).Both pay and start together
Each player pays the machine's price. If either cannot, the game does not start and nobody is charged. Both clocks are synced with the server, so the first note lands at the same moment on both screens.
If a partner leaves during Duo, the other keeps playing alone. If one leaves during Versus, the one who stayed wins.
The Cinematic Dance Stage#
When the song starts, the player's screen cuts away from the arcade. A copy of their character — same clothes, same face — dances on a stage somewhere in Los Santos, filmed from fifteen camera angles that change every 8 beats, with a zoom punch on every beat. Everyone else keeps seeing the player dancing on the machine. In Duo, the partner's copy dances beside them.
Stage | id | Where |
|---|---|---|
Funfair |
| The Del Perro Pier funfair. The default. |
Rooftop |
| A helipad high above downtown. |
National |
| The Vinewood Bowl stage. |
Asylum |
| A dark interior below the city. |
Bunker |
| An underground bunker. |
Life Invader |
| The Life Invader office. |
FBI |
| High up inside the FIB building. |
The stage is chosen on the Start screen with ← →; in a two-player game the host chooses it for both. The dance moves change every 8 beats and get bigger as the combo grows — calmer under 8, livelier from 8, all-out from 20 (Config.Animations.intensity). A short orbiting shot of the dancer, arms crossed, covers the countdown.
For the player's own screen only, the menu is lit as daytime and the song is played at night (Config.DanceStage.forceNight, nightHour) under a cinematic colour grade (timecycle); the server's time comes back as soon as they leave. Common weather-sync resources are paused for that time — see Integrations.
Adding or moving a stage
Each stage is one line in Config.DanceStage.stages: an id, the label players see and a vec4 with the spot and the way the dancer faces. default names the one selected first.
Config.DanceStage = {
enabled = true,
default = 'amusement',
stages = {
{ id = 'amusement', label = 'Funfair', coords = vec4(-1651.27, -1117.60, 13.02, 308.98) },
{ id = 'beach', label = 'Beach', coords = vec4(-1520.40, -1395.10, 5.20, 120.0) },
-- ...
},
}Choose open spots: the cameras orbit up to a few metres around the dancer.
Tuning the cameras
Config.DanceStage.cams lists the angles, relative to the dancer, played in order. switchBeats sets how often they cut, interpMs how long the glide between them lasts and fovPulseAmp how hard the beat punches. The intro* values shape the countdown shot. To frame the angles by eye, use /dancecam with debug on: it prints a ready-to-paste cams table to the F8 console.
Playing at the machine instead
Config.DanceStage.enabled = false keeps the player at the arcade, filmed by Config.Camera. Its mode is fixed, front, side or dynamic, which cycles angles every switchBeats.
The dancer behind the menu
Config.Preview stages the player's character in front of the dance_machine_background backdrop from dancemachine-assets, in an empty spot under the map. It frames the dancer on the left while browsing tracks, on the right — with a partner when Duo is possible — while choosing a mode, and posing while the settings are open. Change stage only if another resource uses that spot; enabled = false turns the backdrop off.
Records and Leaderboards#
Record | Where it shows |
|---|---|
Personal best | Kept per song and difficulty. Its grade is the badge on the song in the track list, and beating it shows NEW RECORD! on the results. |
Server record | The best score anybody has on that song and difficulty. A new one shows SERVER RECORD! and is announced to every player online ( |
Ranking | Settings → Ranking: the server's top players by score, max combo and accuracy, |
Profile | Settings → Profile: the player's last runs by mode, each opening its score, combo, accuracy, judgments and date. |
A cleared run always beats a failed one for a personal best, whatever the score, and only cleared runs can set a server record.



