Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement scores via events #33999

Merged
merged 10 commits into from
Sep 15, 2019
Merged

Conversation

jbytheway
Copy link
Contributor

Summary

SUMMARY: Infrastructure "Support json-defined scores as a function of events"

Purpose of change

Working towards #4173.

Use the new events system to allow scores to be defined in json. This provides a flexible framework for scores without needing to hardcode too much, and allows mods to add their own scores where it makes sense (e.g. Magiclysm might want to score how many magical creatures you slay, which the core game would not).

Describe the solution

Introduce three new json structures:

  • event_transformation which can take a multiset of events (generally, all events of a given type) and filter them in some way based on the values in those events (more types of transformations can be added in the future).
  • event_statistic which summarizes a multiset of events into a single number. The simplest statistic is just a count of events, but other options are available.
  • score which specifies that a particular event_statistic should be treated as a score, and provides a human-readable description thereof.

These are all calculated using stats_tracker (#33782). Some updates to the stats_tracker code support this.

For sanity-checking, we need runtime access to the format of each event_type. Previously this was only accessible at compile time. Add event::get_fields to this end.

Add the avatar's character_id to the game_start event so that it's possible for these transformations to filter on events pertaining to the avatar (rather than other characters).

Add tests and documentation.

Replace the "Lifetime stats" section of the memorial file with values calculated using the new scores. Add scores in a new data/scores.json which cover the stats that were previously listed here (and a bit more to test other functionality).

Describe alternatives you've considered

You might wonder why score and event_statistic are separate. This is because the statistics can be used for other things. This is already happening in that you can use statistic values to filter events in an event_transformation. In the future I also plan to use event_statistics to implement achievements.

Additional context

Currently the only was to actually see your scores is via the memorial file. The next step is to add an in-game UI to see them "live". I also want to save them alongside the memorial file in a machine-readable format so they can be viewed in aggregate to provide the "top scores" feature (#4173).

Here's an example extract from a memorial file for a very short-lived character I created in testing:

Lifetime Stats and Scores
  Number of monsters killed: 7
  Distance moved: 87 squares
  Distance walked: 87 squares
  Damage taken: 340 damage
  Damage healed: 0 damage
  Headshots: 0

Currently all these event multisets and statistics are recalculated on demand every time any score is needed. This is fine for scores, but I don't expect it to be sufficiently performant for achievements. My plan is to allow the stats_tracker to cache these various values and update them incrementally, so that each individual event can be processed efficiently but also trigger achievements as appropriate.

It's already possible to extract the required fields and their types for
an event at compile time.  Make it possible to also do so at runtime.
@ZhilkinSerg ZhilkinSerg added <Enhancement / Feature> New features, or enhancements on existing [C++] Changes (can be) made in C++. Previously named `Code` [JSON] Changes (can be) made in JSON [Markdown] Markdown issues and PRs Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style labels Sep 13, 2019
Change event_tracker into event_multiset, because we want it to be a
more generic object used for more than just tracking events.  It now
represents any collection of events of the same type.

Introduce three new json-defined objects:

- event_transformation, which converts one multiset of events to
  another.  For example, it can filter all kill events to just kill
  events attributed to the avatar.

- event_statistic, which converts a multiset of events into a single
  value.  The simplest case, for example, is counting the number of
  events.

- score, which uses an event_statistic to produce a score, which can be
  saved as a permanent record of a game.  Currently scores' only purpose
  is to be written to the memorial log.
The new "description" field is expected to include a '%s' field for the
value of the score to be inserted into.
This is used for things like total damage received in the game.
Rather than the hardcoded scores we previously had, just iterate over
all the json-defined scores.

Also, add new json scores to cover all the stats that were previously
listed.
Want a test for the new "total" stat feature.  Rearrange the other tests
into SECTIONs at the same time.
@kevingranade kevingranade merged commit fbdc8f3 into CleverRaven:master Sep 15, 2019
@jbytheway jbytheway deleted the scores_via_events branch September 15, 2019 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C++] Changes (can be) made in C++. Previously named `Code` Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style <Enhancement / Feature> New features, or enhancements on existing [JSON] Changes (can be) made in JSON [Markdown] Markdown issues and PRs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants