0.2.0 • Published 1 year ago

kshoot v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

kshoot.js

npm GitHub Workflow Status (with branch)

This is JavaScript/TypeScript library for manipulating KSH and KSON chart files of K-Shoot Mania. This library is focused on having a simple, modular, and intuitive codebase with little dependency.

NOTE: Check out kshoot-tools if you are looking for a program or a tool to do something with chart files. This library can be used to create such tools, but is not a tool by itself.

Progress

This library is currently work-in-progress with only the basic features implemented.

  • KSH/KSON I/O
    • Reading KSH
    • Reading KSON
    • Writing KSH
    • Writing KSON
    • Metadata
    • Comments
    • Notes and lasers
    • Audio effects
    • Camera effects
    • BG effects
  • Simple API
    • Iterating each note in the chart
    • Calculating median BPM

Chart file specs

Examples

Basic data structure

Chart implements kson.Kson, so be sure to read the KSON spec before using this library. Also, ByPulse<...>[] and similar lists are managed by sorted-btree.

import {parse, Chart, kson} from 'kshoot.js';

// `Chart.parseKSON`, `Chart.parseKSH`, `parse` for parsing a chart
// Note that strings without BOMs are preferred.
let chart: Chart = Chart.parseKSON("... (a valid KSON chart, with or without BOM) ...");
chart = Chart.parseKSH("... (a valid KSH chart, with or without BOM) ...");
chart = parse("... (either KSH or KSON chart, with or without BOM) ...");

// Structure of `Chart` follows that of KSON
const meta: kson.MetaInfo = chart.meta;
const beat: kson.BeatInfo = chart.beat;
const note: kson.NoteInfo = chart.note;

// Some lists such as note.bt/fx/laser and beat.bpm are not arrays,
// but they are nevertheless iterable.
for(const [y, len] of note.bt[0]) {
    /* ... */
}

Counting notes

import fs from 'node:fs';
import {parse} from 'kshoot.js';

function reportChart(chart_filename) {
    const chart_contents = fs.readFileSync(chart_filename, 'utf-8');
    const chart = parse(chart_contents);

    let short_notes = 0;
    let long_notes = 0;

    const count = (notes_arr) => {
        for(const notes of notes_arr) {
            // Note that the backing data structure for `chart.note.bt` and `chart.note.fx` may change in future.
            // The only gaurantee is that they will always remain to be iterable.
            for(const [y, len] of notes) {
                // Note that pulses use `bigint`, not `number`.
                if(len > 0n) ++long_notes;
                else ++short_notes;
            }
        }
    };

    count(chart.note.bt);
    count(chart.note.fx);

    console.log(`${chart_filename}: ${short_notes} short notes, ${long_notes} long notes`);
}

["./foo.ksh", "./bar.kson"].forEach(reportChart);

Dependencies

I want kshoot to have as little dependencies as possible. Some zero-dependency libraries are too cool to not use, though.

$ npm ls --prod --all
kshoot@0.2.0
├── sorted-btree@1.8.1
└── zod@3.21.4