mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-26 08:57:58 +03:00
* docs: migrate from mkdocs to mdbook - Rename old mkdocs docs/ to old-docs/ for reference - Set up new docs/ with mdbook (book.toml + src/ tree) - Mirror full nav structure from mkdocs.yml into SUMMARY.md - Add Justfile-docs with docs-serve, docs-build, docs-check, docs-install recipes - Import Justfile-docs from root Justfile - Rewrite .github/workflows/docs.yml: build step uses taiki-e/install-action to install mdbook, split into separate build + deploy jobs, PR builds run the check step too * ci(docs): pin actions to SHAs, install mdbook via release binary * ci(docs): install mdbook from apt instead of curling a release binary * dev: replace mkdocs python stack with mdbook in dev image * ci(docs): apt only works on Debian; restore release binary install for Ubuntu CI * docs: fix duplicate file entries in SUMMARY.md * docs: remove docs-install recipe * docs: remove site-url from book.toml to fix asset loading * dev: install mdbook from upstream release binary, not Debian apt The Debian package (0.4.x+ds) strips bundled font assets, leaving the built site without fonts/fonts.css. Use the upstream tarball (same as CI) so the theme is complete. Handles x86_64 and aarch64. * docs: vendor mdbook tarballs in dev/mdbook/, install from there Dockerfile.dev uses COPY + tar to install the right arch at build time. CI extracts the x86_64 tarball directly from the checkout. No network access required for either — and no stripped-fonts Debian package. * fix: unwritten
116 lines
3.1 KiB
Markdown
116 lines
3.1 KiB
Markdown
# User Game Stats
|
|
|
|
A user has overarching statistics for a game.
|
|
|
|
This part of the score importing process updates those
|
|
overarching statistics, such as their profile rating
|
|
and their classes.
|
|
|
|
!!! note
|
|
If a user has never played this game + playtype
|
|
combination before, a new user game stats
|
|
object is saved to the database as a result
|
|
of this update.
|
|
|
|
*****
|
|
|
|
## Format
|
|
|
|
A User Game Stats object looks like this:
|
|
```ts
|
|
{
|
|
userID: string;
|
|
game: "iidx" | "bms" // ... so on
|
|
playtype: "SP" | "DP" // ... the set of playtypes this game supports.
|
|
// A set of continuous statistics about a user.
|
|
ratings: {
|
|
// A record of numbers with keys determined
|
|
// by the game + playtype combination.
|
|
// such as:
|
|
VF6: number;
|
|
// for SDVX and USC.
|
|
},
|
|
// A set of discrete statistics about a user.
|
|
classes: {
|
|
// This typically contains things like dan ranks
|
|
// or skill divisions, such as:
|
|
dan: 14,
|
|
// for IIDX, or
|
|
skillColour: 19
|
|
// for gitadora.
|
|
|
|
// Note that instead of remembering each number
|
|
// for each class, they are defined as constants
|
|
// in common/src/constants/game.ts
|
|
}
|
|
}
|
|
```
|
|
|
|
## Ratings
|
|
|
|
Ratings are calculated for the given Game + Playtype combination.
|
|
|
|
Different combinations will have different statistics,
|
|
Gitadora will have a profile skill level, whereas SDVX
|
|
would use Profile Volforce.
|
|
|
|
All the rating functions for a game are declared
|
|
in `src/lib/score-import/framework/user-game-stats/rating.ts`.
|
|
|
|
## Classes
|
|
|
|
There are two types of classes in Tachi. Static classes
|
|
are classes that can always be derived from the data around
|
|
them. Things like this are typically discrete buckets
|
|
for continuous data, such as Skill Colours in GITADORA.
|
|
|
|
The other type of classes are external classes. These
|
|
are things like Dans, where the information cannot be
|
|
derived from any other data around it, and instead must
|
|
be explicitly told to change.
|
|
|
|
### Class Handlers
|
|
|
|
You may recall that in [Parsers and Converters](./parse-conv.md) it was documented that parsers can return a
|
|
ClassHandler. The ClassHandler is intended to handle those
|
|
explicit changes.
|
|
|
|
For example, let's say we have an import type that tells us:
|
|
```js
|
|
{
|
|
scores: [{score: 1000, songID: 1, diff: "spa"}],
|
|
sp_class: "kaiden"
|
|
}
|
|
```
|
|
|
|
We could return a classHandler from our parser function
|
|
that encloses this updated information, such as:
|
|
```ts
|
|
function CreateClassHandler(spClass: number): ClassHandler {
|
|
return (../../* classHandlers have some args but we dont need them for this example */) => {
|
|
return {
|
|
dan: spClass
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
This returned classHandler is called with 5 arguments
|
|
and is expected to return a partial record of the users
|
|
classes. This is then merged with the static classes
|
|
and returned as the users classes.
|
|
|
|
### Static Class Handlers
|
|
|
|
Static class handlers are built in, and always called
|
|
when a user's game stats is updated.
|
|
|
|
## Deltas
|
|
|
|
Once a user's classes have been calculated, they are diffed
|
|
against the current user's stats. If they have been
|
|
increased, then a redis message is sent out, and things
|
|
like the Tachi discord bot may choose to echo this
|
|
in the discord.
|
|
|
|
The deltas are returned to be part of the ImportDocument. |