Skip to content

Conversation

@audreyality
Copy link
Member

@audreyality audreyality commented Mar 10, 2025

🛑 This PR is created to share ideas; it will not be merged.

📔 Objective

This User Achievements prototype measures user activity using a reactive stream processor. It uses the measurements to award achievements.

This system includes a reactive control loop to determine which monitors are running. The system can be fully disabled by returning an empty set of monitors.

🔮 Monitors

🫐 Achievement Hub Prototype

The achievement hub combines a collection of functions and types into a full achievement event processor. The following graphic shows a rough illustration of how these parts fit together:

image

This prototype starts with the ECS schema from #13367. User event monitors collect events into an RXJS subject. The achievement hub listens for new log entries and emits achievement logs from its own subject.

Note

Permanent state is not implemented by the prototype.

✅ The achievement processor measures user events and produces metrics and achievements:

  • pipe - input - The user event stream.
  • captured$ / metrics$ - input - The latest collection of measurements
  • validators$ - input - The rules for awarding achievements
  • pipe - output - The achievement event stream.

👍🏻 The achievement manager determines which achievement measurements are active.

  • "until-earned" criteria measure the event stream until a matching earned achievement event is tracked.
  • Metric criteria measure the event stream while a metric is between a low and high value.

✏️ The event store captures achievement events local to the client. It stores and emits achievement events. Its storage tracks the age of each event and evicts stale events (typically those that track achievement progress).

  • pipe - input - The local achievement event stream.
  • replication$ - input - (not depicted or implemented) Non-local achievement event stream (synced from other clients).
  • pipe - output - The achievement event stream.
  • captured$ - output - New log entries observed by the event store.
  • conflicts$ - output - (not depicted or implemented) Records recieved from replication$ that conflict with the local event stream.

Important

The prototype doesn't implement an event store. It uses a ReplaySubject to simulate permanent state.

🧠 Assumptions

  • It's cool to port @dasien's achievement processor types to javascript.
  • It's logs all the way down. The achievement processor watches, stores, and emits logs. Its runtime memory, if any, is calculated from its logs.
  • The runtime logs will be verbose; there are too many to sync the raw logs across clients.
  • Achievement log size should grow linearly with the total number of achievements. If we track 1000 achievements, we're going to synchronize N * 1000 entries. (Optimally, n < 1 because one log entry can track multiple achievements simultaneously).

🦕 Not included

This design was chosen to ensure that we can iterate quickly on the processor during the sprint, and then upgrade to a more robust design for the full release. Some of the features not included in this design:

  • persistence - all data is stored only in memory; shutting down a client resets the processor
  • encryption - the data in this prototype is always plaintext; the real deal should include E2E encryption.
  • replication protocol - this prototype uses hard-coded rules; it lacks server APIs for data replication

Integration tests for the completed achievement hub should cover the following scenarios:

  • 🙂 The happy path - A user is only using one client; there are no changes to sync.
  • 💻 The login path - A user just logged in and it's downloading their achievements.
  • ♻️ The sync path - A user just unlocked their client and it's downloading new items.
  • 💣 The conflict path - A user has successfully caused a race condition between clients, and this client's version of events conflict with the last-synced achievement info from the server.

🏁 Tasks

  • formal validators
  • event hub
  • event collection
  • toast support
  • achievement report
  • wrap all of this in a service

🪗 Stretch goals

  • unit test and integrate achievement manager
  • display some achievements on account switcher
  • prototype of (plaintext) replication
  • log classification
  • conflict resolution algorithm

@audreyality audreyality added the hold Hold this PR or item until later; DO NOT MERGE label Mar 10, 2025
@github-actions

This comment was marked as off-topic.

@codecov

This comment was marked as off-topic.

djsmith85 and others added 27 commits March 20, 2025 23:03
Ideally the name of the icon is present on the achievement configuration. Currently a iconMap is used to lookup the icon by achievementId
@audreyality
Copy link
Member Author

audreyality commented Mar 24, 2025

Innovation sprint concluded

This PR will now be closed. Any lessons learned and ideas can be extracted from the branch, which will not be deleted for now.

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold Hold this PR or item until later; DO NOT MERGE

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants