General-purpose scripting module for Beat Saber beatmap using TypeScript.
npm install bsmapGeneral-purpose Beat Saber beatmap scripting library with
TypeScript, fully-typed schema and flexible tool to ease
scripting development surrounding beatmap.
It is designed to be simple and familiar with traditional scripting with barely hidden layer of
abstraction. It is optimised for speed with minimal compromise allowing for faster work iteration.
> [!WARNING]
>
> API changes, structural changes, or game updates that require restructuring may result in breaking
> changes in future update. Many work has been placed in order to minimise the breakage on minor
> version update.
- Latest Schema: Supports all latest official schema including modded features.
- Supported version: v4.1.0, v3.3.0, v2.6.0, v1.5.0.
- Version-agnostic Wrapper: Readable and cross-version core allows for seamless version
transferring.
- Partial Creation: Define beatmap object partially and let default fill the rest of fields.
- Mod Compatible: Chroma, Cinema, Noodle Extensions, and Mapping Extensions is supported out of
the box.
- Helpers are available in main for essentials such as getting modded position.
- Class method may contain function parameter to access any arbitrary data.
- Tree-shakeable: Modularity approach minimise build size.
- Built-in Utility: Relevant utilities including math, colour, easings, and more.
- Validator & Optimiser: Customisable tool ensuring beatmap schema is valid to the game and
optimised for storage.
- Any TypeScript supported runtime/transpiler
- Deno
- Bun
- Node.js
- Vite
- Basic JavaScript or TypeScript knowledge
- Module is entirely TypeScript, but for common use case you do not need an in-depth knowledge.
Before you start, you may want to understand how Beat Saber stores the
beatmap data here.
You may get this package from NPM or
JSR using respective package manager.
To get scripting, simply create a .ts file anywhere, preferably inside map folder for simpler
setup, import module via module specifier or package manager, and then run the script. That's it. Do
check out the the guide for usage detail.
This is for beginner on how to import library and use the script. Importing bsmap into script file
can be done in various ways, it is recommended that you run the command in the same folder as the
script file.
#### Deno
``tsdeno add bsmap
// Choose one of the four ways, prioritise top to bottom
import * as bsmap from 'jsr:@kvl/bsmap';
import * as bsmap from '@kvl/bsmap'; // via package.json
import * as bsmap from 'npm:bsmap';
import * as bsmap from 'bsmap'; // if previously used NPM exist
// Run command: deno run script.ts`
#### Bun
`tsbun add bsmap
// via
import * as bsmap from 'bsmap';
// Run command: bun script.ts`
#### Node.js & Browser NPM (ESM)
`tsnpm install bsmap
// via
import * as bsmap from 'bsmap';
// Run command: ts-node script.ts`
// Refer below for browser
#### Node.js NPM (CJS)
`tsnpm install bsmap
// via
const bsmap = require('bsmap');
// Run command: ts-node script.ts`
Once you've imported the library, you can try the bare minimum example:
`ts`
const data = bsmap.readDifficultyFileSync('ExpertPlus.beatmap.dat', 4);
// ... arbitrary code
bsmap.writeDifficultyFileSync(data, 4);
You may also clone the library to store and import locally, and make any modification as you wish.
If you are using the script outside of the map directory, you can specify the map directory without
the need to explicitly apply directory on IO function. This can be any valid directory as long as
it points to directory. If directory is explicitly written in IO function, then that will instead be
prioritised.
`ts`
// you should always use absolute path for this,
// otherwise it will try to resolve path with your CWD
bsmap.globals.directory = '/PATH/TO/YOUR/BEAT_SABER/MAP_FOLDER/';
Module uses respective vendor API for filesystem and path functionality to handle read and writenode:
module, currently supporting Deno, Bun, and Node.js. This may also work on other runtime given that built-in module is available on import, otherwise you may be required to provide thefs
following and path functionality in shims module.
As it is written in TypeScript, you may need transpiler such as tsc or vite that will compile
down to single JavaScript file to be able to be used on browser, depending on build option down to
ES5 support.
Typical browser do not have filesystem functionality and thus read and write module may not workload
as expected. You may use and save which can read from web input.
Deno is used for development, simply install and setup workspace, no other
setup is required to get started as it provides necessary toolchain.
If you wish to contribute, do follow the guidelines. Make pull request for feature
addition/enhancement/fix or create an issue if you encounter error/problem or want an improvement.
#### Styling & Documentation
- Use deno fmt for standard formattingdeno.json
- Do not change configurationI
- File names shall use camel case
- Exported types, interfaces, fields, and functions should be accompanied by JSDoc comment right
above its definition
- Function/method should provide usage example
- Interfaces that are exposed to user must use prefix to indicate interface rather than
instantiable object.
#### Coding
- Top-level function shall use regular function
- No dependencies shall be used outside of examples, extensions, and tests
- Vendor dependency is allowed so long it gracefully handles every platform possible
- Prefer types over concrete type for parameter/return typenode:` built-in import if needed
- Use generic if necessary
- Use ESM
- Avoid circular imports
- Avoid URL imports
- Avoid default export
- Prefer
- Write JSDoc on every important bit
- Separate class method to own function
- Add more helper for Chroma and Noodle Extensions
- As beatmap module here is version agnostic, certain data such as bomb direction, info set custom
data, etc. are either renamed, restructured or unavailable.
- Certain beatmap version do not contain certain information in schema and are therefore not
present in-game.
- HSV conversion algorithm
- CIE-L\*ab and Delta E2000 algorithm
- Uninstaller and Qwasyx (improving it) for note swing detection
algorithm OfficialMECH for improving and maintaining codebase
- Top_Cat for math guidance
- Others for helpful feedback & indirect contribution