BMS Scope of Work
Summary and goals
Be-Music Source (BMS) is a file format for rhythm game charts
There are many BMS clients that parse BMS files allowing users to
play songs. The current BMS ecosystem runs off sites known as
Tables
. These tables are arrays of
Chart
objects sorted by difficulty.
Chart
objects do not actually contain the chart, they
instead contain and MD5 hash of the charts corresponding
.bms
file (as well as other metadata like title &
author). It is up to the user to source this file & for their
client to link the local file to the Chart object.
Sometimes, the metadata sent along with the Chart
object
includes a link to a site where the files can be downloaded. Other
times, it's up to the user to hunt down packs or other users who
already have the chart.
This app would list all Charts
in a
Table
in a easy to navigate web application. With a
majority of the data being driven by metadata provided by the table.
Admin users are able to create a corresponding object in the apps
database against a Chart, where extra metadata can be included, such
as download links & descriptions.
Once a corresponding object has been created, even if the chart is no longer in the table; it can still be viewed on the website.
This site will attempt to mirror an osu-esque style of browsing charts:
Scope Breakdown
Deliverables
- An admin panel for managing database objects
- CRUD Tables
- CRUD Charts
- An end user application for viewing database objects
- Read Tables
- Read Charts
Timeline
gantt
dateFormat YYYY-MM-DD
axisFormat %H-%M
title BMS Site timeline
section Initial Deploy
Stand up Baseline Core : a1, 2023-08-01, 1h
Deploy dev environment : after a1, 1h
Deploy prod environment : a2, after a1, 1h
Create public view webapp : a3, after a2, 2h
Deploy dev environment : deploy, after a3, 1h
Deploy prod environment : after a3, 1h
section Chart Object
Create Chart object : a4, after deploy, 1h
Allow admin to view chart objects : a5, after a4, 1h
Allow admin to edit chart objects : after a5, 1h
Allow admin to delete chart objects : after a5, 1h
section Table integration
Create localTable Object : a6, after deploy, 1h
Allow admin to configure localTable : a7, after a6, 2h
Scheduled job to ping table : a8, after a7, 1h
Link charts in system to table : after a8, 2h
Clean up dead link objects : after a8, 2h
Allow admin to view links : after a8, 2h
Technical Breakdown
Personas
- Admin User
- End User
External Integrations
Table Objects
Tables consist of two JSON files served from a URL: A header, and a body.
The header file contains the name of the table and assorted information.
The body file contains all charts in the table as an array.
There is no agreed upon schema in the community for these objects. However, most clients handle some defaults.
interface Header {
// The name of the table
name: string;
// The icon to show in clients (usually unicode shape)
symbol: string;
// URL or Path to the tables body
data_url: string;
// Order levels should be put in in clients, optional?
level_order?: string[];
// What mode (7k/14k/PMS/24k) is the table for, optional?
mode?: string;
}
type TableBody = {
// The title of the song
title: string;
// The songs artist
artist: string;
// MD5 hash used by clients to identify charts
md5: string;
// The charts level
level: string;
// The URL where the chart can be downloaded
url?: string;
// Another URL where the chart can be downloaded (stellabms only?)
url_diff?: string;
// SHA256 of the chart (stellabms only?)
sha256?: string;
// A comment by the uploader. Completely optional.
comment?: string;
}[]
Local Objects
TableMirror Objects
We should store basic metadata about the table to prevent spamming
the table host when users view our site. When users view a table we
should show extremely slim amounts of information as well as the
related localChart
objects in our system. If the user
wishes to, they can load the remaining charts we do not have dedicated
objects for.
OR
We should store clones of the tables locally to allow users to view
the entire tables list of charts in one go. Charts with
localChart
data associated will be moved to the top
&/ displayed separately.
LocalChart Objects
A more complex object containing metadata about the chart. This could include an image, a brief description, links to more reliable downloads, or even note analysis to generate stats like density/chords. We could also include an array of charts that are similar or considered other difficulties.
Linking
A chart can be in multiple tables, knowing only the chart we should be able to fetch tables its in, and knowing only the table, we should be able to fetch charts.
- Get all charts in table
- Get all tables for chart
If using dynamoDB a linking object would likely have to exist with an index for querying by table identifiers and an index for querying by chart identifiers. Since we expect to be querying this a lot it's worth making this an index
User activities
Users almost always have read only permissions to all
objects.
Admins can read and write
Admin User
- Can manage external tables we fetch from
- Manage
TableMirror
objects - Can create
LocalChart
objects based on table information - Can edit existing
LocalChart
objects - Can delete existing
LocalChart
objects
End User
- Can view
LocalChart
objects related to a table - Can view an external table
- Can view
TableMirror
objects - Can view all
LocalChart
objects paginated by creationDate
User requests
Users will be triggering the bulk of requests in the system
Request system tables
sequenceDiagram
User->>+API: Request all tables
API->>+DynamoDB: Get all tables
DynamoDB-->>-API: Return all tables
API-->>-User: Return all tables
Note right of User: User can browse tables in system
Request system localCharts
sequenceDiagram
User->>+API: Request tables charts
API->>+DynamoDB: Get local chart objects
DynamoDB-->>-API: Return local chart objects
API-->>-User: Return charts
Note right of User: User can browse charts in system
Request table charts (non-local)
sequenceDiagram
User->>+API: Request tables charts
API->>+Table: Request table charts
Table-->>-API: Return table charts
Note right of API: Mutate the returned chart objects
Note right of API: Potentially cache this?
API-->>-User: Return charts
Note right of User: User can view basic chart data
Implementation timeline
Assuming baseline core starter
- Create admin app
- Create tableMirror object admin CRUD/UI
- Create localChart object admin CRUD/UI
- Create linking object admin CRUD
- Create auto linking function when tables are updated
- Design user table list screen
- Design user chart list screen
- Design user chart view screen
- Create end user app
- Allow end users to browse tables
- Allow end users to browse local charts
- Allow end users to view chart data
Complexities
Things to keep in mind when scoping work out
- Charts can be in multiple tables
- Charts could potentially have many related charts in different
tables
- Potentially store hardcoded tables/difficulties against charts to avoid extra queries. Alert admins via UI if their local table data conflicts with the saved data against a chart?
- Table data is inconsistent