mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-27 17:38:11 +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
5.4 KiB
Markdown
116 lines
5.4 KiB
Markdown
# Goals, Quests, Questlines
|
|
|
|
This page covers pretty much everything you need to know about interacting with goals
|
|
and quests.
|
|
|
|
Although these features are fairly straightforward on the surface, their implementation is a bit complex at points. We'll get to it.
|
|
|
|
## What is a Goal?
|
|
|
|
A goal is a set of instructions that are evaluated for a player if they are subscribed to it (and it is relevant to their current import, see [Getting Relevant Goals](../import/goals.md)).
|
|
|
|
!!! example
|
|
An example goal would be something like "AAA 100 charts in the X Folder".
|
|
|
|
Users must subscribe to goals for them to be evaluated when they import scores. This is
|
|
abstracted away from the user, as the operation to create a goal will automatically subscribe
|
|
them to the same goal.
|
|
|
|
### Identification
|
|
|
|
Goals are identified by a checksum of their instructions. If two users make the goal to "AAA Freedom Dive", the goalID will be the same.
|
|
|
|
This allows us to do things like see what goals are popular, and reduce the general duplication on the database.
|
|
|
|
## User Subscriptions
|
|
|
|
Users may create and subscribe to goals. This is done with the [UGPT Create Goals Endpoint](TODO). If they create a goal that already exists, they are just subscribed to that goal.
|
|
|
|
If they create a goal that does not already exist, it is created, and they are subscribed.
|
|
|
|
Users may unsubscribe from goals that they no longer care about getting pinged for.
|
|
|
|
Subscriptions to goals are stored in a [GoalSubscriptionDocument](../../schemas/goal-sub.md).
|
|
This document is uniquely identified by the joining of the `goalID` with the `userID`.
|
|
|
|
### Instant Direct Achievements
|
|
|
|
If a user creates/subscribes to a goal that they would instantly achieve, they are denied
|
|
from adding goal directly.
|
|
|
|
### Evaluating A User's Progress
|
|
|
|
Goals have two main components in terms of evaluation -- `progress` and `outOf`. If the progress is greater than or equal to the `outOf`, the goal is marked as achieved.
|
|
|
|
Both of these values are numbers, and are not intended for human consumption. For example, the goal 'HARD CLEAR Freedom Dive' would be represented by an `outOf` of `6`, which is the internal lampIndex for a BMS HARD CLEAR.
|
|
|
|
For human representation, these values are formatted and stored in the Goal Subscription Document as `progressHuman` and `outOfHuman`, respectively. These values are prettified for human users, and leverage game-specific formatting in some cases.
|
|
|
|
!!! note
|
|
Achieved goals are still calculated -- a user may actually find themselves un-achieving goals in some stranger cases.
|
|
|
|
If their goal is something like AAA 10% of a folder, and the folder gets larger, they
|
|
may find themselves losing the achieved status on this goal.
|
|
|
|
!!! warning
|
|
Goal Subscriptions are capped by the MAX_GOAL_SUBSCRIPTIONS [conf.json5](../setup/config.md) property, and defaults to 1000.
|
|
|
|
!!! danger
|
|
Unsubscribing from goals directly is only possible if they do not have any parent quests.
|
|
More on that below.
|
|
|
|
## What is a Quest?
|
|
|
|
Quests are groups of goals, defined in a structured form, with support for assigning
|
|
notes next to goalIDs, and other generally useful stuff.
|
|
|
|
Their purpose for users is to give them a quick way to assign a bunch of goals they might care about.
|
|
|
|
For example, a dedicated user may make their own "Kaiden Checklist", and create a set of goals
|
|
they think are useful for kaidens to aim for. Another user interested in this can just
|
|
subscribe to that quest, and all the goals will be managed for them.
|
|
|
|
### Identification
|
|
|
|
Quests are identified by their `questID`, which is a completely arbitrary string.
|
|
|
|
At the moment, users cannot create quests directly, they are hard-defined by the [Database Seeds](../infrastructure/seeds.md).
|
|
|
|
### Evaluating a User's Progress
|
|
|
|
Similarly to goals, user's can subscribe to quests.
|
|
|
|
Quest subscriptions are interesting in that the `progress` factor is always an integer -- how many goals in the quest the user has achieved, and the `outOf` factor is always an integer -- how many goals need to be achieved in the quest for the quest to be marked as achieved.
|
|
|
|
Similarly, the `achieved` status on quests is identical to `progress` being greater than or equal to `outOf`.
|
|
|
|
### Parenting Goal Subscriptions
|
|
|
|
When a quest is subscribed to, all the goals in the quest are also subscribed to.
|
|
|
|
When a user is subscribed to a quest, they *must* also be subscribed to all the goals in
|
|
that quest. If they aren't, they've desynced with the quest, and that's an awful
|
|
user experience.
|
|
|
|
As such, Tachi keeps track of all the quests that care about this goal subscription, and users are *prevented from unsubscribing from this goal* while any of their quest subscriptions parent the goal.
|
|
|
|
### Instant Indirect Achievements
|
|
|
|
Subscribing to a quest *mandates* that all of the goals are assigned. It is not rare for this to mean that you subscribe to goals that are instantly achieved.
|
|
|
|
This is fine. If this does happen though, `wasInstantlyAchieved` is set on the goal, and no
|
|
webhook event is emitted.
|
|
|
|
### Unsubscribing
|
|
|
|
For all `goalID`s in the quest, we check if this goal subscription has any other parent quests.
|
|
|
|
If this quest was the only reason the goal was assigned (i.e. it wasn't assigned directly, or isn't part of another quest), this quest will be unsubscribed from.
|
|
|
|
## Questlines
|
|
|
|
Questline are ordered lists of quests. Their purpose is to group quests together
|
|
visually in an ordered manner.
|
|
|
|
Users *can not* "subscribe" to questlines, but they can use questlines as a utility for subscribing to all the related quests.
|