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

Update events to account for ability to swap avatars (debug or upon death) #63488

Merged
merged 13 commits into from
Mar 22, 2023

Conversation

cake-pie
Copy link
Contributor

@cake-pie cake-pie commented Feb 8, 2023

Summary

Bugfixes "Update events to account for ability to swap avatars (debug or upon death)"

Purpose of change

Resolves #63455

#51450 and #53606 gave the ability to switch to another character.
Preexisting game events (that feed into memorial, stats, achievements, conducts, scores) are not equipped to handle this, as they only recorded the starting character in event_type::game_start and then death and last words in event_type::game_over. This oversight causes some things to break.

Describe the solution

  • split game_avatar_new off from game_start and game_avatar_death from game_over
  • add migration for existing saves that retroactively populates game_avatar_new from available information
    • where game_start is available, get starting character information from it
      • if current character is different from starting character, add it as well, treating current turn as the time they took over
    • if game_start is also not available (pretty old save!) treat current character as starting character.
  • adjust existing event emissions (split into two events accordingly)
  • emit game_avatar_new at the end of avatar::control_npc() when new avatar takes over
  • show the "tombstone" screen and prompt for last words on death of all player characters (not just the final one when you run out of "continues" or choose not to do so)
  • emit game_avatar_death to record last words of all dead PCs
  • change avatar_id event statistic to pull its value from the most recent game_avatar_new event
  • memorial logger logs game_avatar_death instead of game_over
  • memorial logger logs game_avatar_new instead of game_start, and will have different text for a character swap rather than a brand new game
  • past games info will try to account for multiple characters over the course of a save, insofar as the information is available. It will pull the starting character name from the first game_avatar_new entry. Depending on how many game_avatar_new entries there are, it will append "et. al." to indicate that there was/were subsequent character(s) that took over from the starting character due to death or debug. If there are no game_avatar_new entries, it will fall back on the legacy approach and pull the starting character name from game_start.

Behavior of stats after this PR

  • any statistic that doesn't rely on comparison against the avatar_id statistic continue working as they did
  • any statistic that depends on avatar_id will switch to the "lifetime" stats of the new avatar when switching to them
    • this includes things they did as an NPC, e.g. any kills, skill gain etc that was captured by the events system

This is imperfect, but now we are at least capturing an event whenever player control switches from one character to another. This ensures that save games will contain the information needed when a fuller solution is developed.

Subsequent work can look into a different way for event transformation to filter events (e.g. kills) to match them against the player character avatar_id at the time the event occurred rather than the current avatar, so that the affected scores, achievements and conducts are on the basis of player action.

Additional context

I can't do anything about information that was lost between #51450 / #53606 and now, because it wasn't able to be captured.

This will probably break some achievements in existing saves, because they'd look for avatar_id but be unable to resolve a value for it when there are no game_avatar_new events yet. There's no way in the event statistics system to "union" two event streams (game_start with game_avatar_new) and implementing such a feature looks like it will get really complex, so I don't think it's worth it just for the sake of this one unusual case. Perhaps some other migration strategy could be devised? In any case, the affected achievements are already broken anyway ( #63455 ) so I'd be satisfied with fixing things so that they work correctly for new saves henceforth.

Describe alternatives you've considered

Hijack the existing game_start and game_over so that they are also emitted whenever there is a character swap, but that seems weird esp. with respect to the game version and total play time fields.

Testing

Simple test case: TestLand.zip

  1. Build this PR, load the save in and verify that the score screen shows 5 monsters killed as the first stat on top. Spawn a slow, harmless monster e.g. water strider and kill it; check that the count has increased to 6.

  2. Using the debug menu, p, x to switch to the follower NPC. Check the score screen, which should now shows 0 kills (Antonia Boswell's lifetime stats). Spawn water strider; kill; check that the count has increased to 1.

  3. Switch back to the original character. Check score screen, which should list 6 kills.

  4. Fire up a recent experimental build and load up the original save file again. Verify that the score screen shows 5 monsters killed.

  5. Switch to the follower NPC. Check that score screen; it shows 5 kills. Spawn water strider; kill; check the count, which did not increase.

  6. Save the game and transfer it to the PR build. The score screen should reflect Antonia's 1 kill.

  7. Spawn water strider; kill; check count increased to 2.

  8. Switch back to the original character. The score screen should reflect their 5 kills.

@github-actions github-actions bot added [C++] Changes (can be) made in C++. Previously named `Code` [JSON] Changes (can be) made in JSON Game: Achievements / Conducts / Scores Player goals and how they are tracked. <Bugfix> This is a fix for a bug (or closes open issue) astyled astyled PR, label is assigned by github actions json-styled JSON lint passed, label assigned by github actions labels Feb 8, 2023
@cake-pie cake-pie mentioned this pull request Feb 8, 2023
@github-actions github-actions bot added Code: Tests Measurement, self-control, statistics, balancing. BasicBuildPassed This PR builds correctly, label assigned by github actions labels Feb 8, 2023
@cake-pie cake-pie marked this pull request as ready for review February 9, 2023 06:51
@cake-pie
Copy link
Contributor Author

cake-pie commented Feb 9, 2023

Added migration from existing saves that makes best-effort attempt to populate game_avatar_new retroactively with what information is available. Imperfect but better than nothing.

Ready for testing and review.

@cake-pie cake-pie force-pushed the events-avatar-swap branch from 1a90334 to 4d708e9 Compare March 3, 2023 13:37
@cake-pie
Copy link
Contributor Author

cake-pie commented Mar 3, 2023

Rebased to resolve conflicts.

E: test failure unrelated, fixed in #63911

@kevingranade kevingranade merged commit 82b6ecb into CleverRaven:master Mar 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
astyled astyled PR, label is assigned by github actions BasicBuildPassed This PR builds correctly, label assigned by github actions <Bugfix> This is a fix for a bug (or closes open issue) [C++] Changes (can be) made in C++. Previously named `Code` Code: Tests Measurement, self-control, statistics, balancing. Game: Achievements / Conducts / Scores Player goals and how they are tracked. [JSON] Changes (can be) made in JSON json-styled JSON lint passed, label assigned by github actions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Some scores/achievements broken due to take over follower NPC upon death of starting character
2 participants