[title: "LoadExternalSongs Class"] ← Back to index

Loads user-added songs from external storage

[heading: "Description"]

A loading state that scans external storage (or, on non-mobile platforms, lets the user pick a directory) for StepMania songs, parsing every .sm or .ssc chart file found. It supports sequential and batched parallel loading with progress feedback, caches the results in window.externalSongs for the rest of the game, and then transitions into the requested next state.

[heading: "Properties"] [table header] [ Property | Type | Description ] [ nextState | string | Game state key to start once external songs are loaded ] [ nextStateParams | Array | Parameters forwarded to the next state ] [ loadingDots | LoadingDots | Animated loading indicator dots ] [ progressText | ProgressText | Bilingual progress text shown while songs load ] [ fileSystem | FileSystemTools | Helper for reading directories and files ] [ songs | Array<Object> | Parsed external song charts ] [ songs | Array<Object> | Parsed external song charts collected so far ] [ parser | ExternalSMParser | Parser used to read external chart files ] [ currentIndex | number | Running index used to keep load order stable ] [ loadedCount | number | Count of songs loaded successfully ] [ failedCount | number | Count of directories that failed to load ] [ totalCount | number | Total number of song directories to process ] [ currentlyLoading | Set<string> | Names of directories currently being loaded ] [/table] [heading: "Methods"] [table header] [ Method | Parameters | Description ] [ init | (nextState, nextStateParams) | Stores the target state and the parameters to hand to it once loading completes. ] [ create | () | Sets up loading UI, state tracking fields, and file system access, then either loads songs from external storage or falls back to a file input picker. ] [ loadSongsFromStorage | () | Lists every directory under the external songs path and loads each one, either in parallel batches or sequentially depending on the ENABLE_PARALLEL_LOADING flag. ] [ loadDirectoriesParallel | (directories) | Splits the directory list into batches no larger than MAX_PARALLEL_DOWNLOADS and processes each batch concurrently to bound resource usage. ] [ processDirectoryBatch | (batch) | Loads every directory in a batch concurrently, tolerating individual failures. ] [ loadDirectoriesSequential | (directories) | Loads the given directories one at a time, ensuring only a single song is parsed at any moment. ] [ processSongDirectoryWithTracking | (dirEntry) | Loads one directory while tracking its progress: it waits for a free parallel slot, parses the folder, records success or failure, and refreshes the progress display. ] [ processSongDirectory | (dirEntry) | Reads all files inside a directory, finds its .sm/.ssc chart files, and returns the first chart that parses successfully, or null if the folder is not a chart folder. ] [ updateProgress | () | Writes the current load progress percentage and loaded/failed counts to the progress text overlay. ] [ showFileInput | () | Opens a native webkitdirectory file picker and forwards the chosen files to the processing pipeline on selection. ] [ processFileInput | (files) | Groups the files picked by the user into per-directory maps and processes them, either in parallel batches or sequentially. ] [ processFileDirectoriesParallel | (directories, dirNames) | Splits the directory names into parallel-safe batches and processes each batch. ] [ processFileDirectoryBatch | (directories, batch) | Processes a single batch of picked directories concurrently, tolerating failures. ] [ processFileDirectoriesSequential | (directories, dirNames) | Processes every picked directory sequentially, one at a time. ] [ processSongFilesWithTracking | (files, folderName) | Parses the files of one picked folder while tracking progress and refresh the progress display once the folder has been processed. ] [ processSongFiles | (files, folderName) | Finds the .sm/.ssc files within a picked folder and returns the first chart that parses successfully, or null if the folder holds no loadable chart. ] [ showError | (message) | Displays an error message on the progress text and returns to the main menu after a short delay. ] [ finish | (resetIndex) | Sorts the loaded songs, caches them in window.externalSongs, and starts the next state, defaulting to the song select screen, or shows an error if nothing loaded. ] [/table] [heading: "Example Usage (Modding)"] [codeblock javascript] // Load all user songs, then drop the player into the song select screen. game.state.add('LoadExternalSongs', LoadExternalSongs); game.state.start('LoadExternalSongs', true, false, undefined); [/codeblock] [footer: "© Retora 2026"]