RFC: Quests #4194
Replies: 12 comments 26 replies
-
|
It isn't immediately clear if I could specify a set of games for a counter objective. Like if an objective is "beat any version of Ultima III" I'd expect it to be a counted objective with a target of 1 with parameters being a set of game IDs that is basically ever Ultima III release that has a set. |
Beta Was this translation helpful? Give feedback.
-
|
Can you share more information on your vision for how legacy awards would work? Some folks already feel overwhelmed trying to earn all the event badges because they are time-limited in nature. However, I think those same people with a fear of missing out will feel the need to tackle any new quest immediately for fear that a new version could lock them out of a badge. This goes against the intent of the quest system as proposed. Suppose a newly supported console requires an addition of new Super Mario games to the "Beat all SMB Games" quest (for example, Super Mario Galaxy 1 + 2 with the release of Wii). If new assets are being created for this new version of the event, could the new tier be added on top of the existing quest while still allowing players to earn both as they clear the requirements? Xionx recommended allowing players that have earned multiple tiers to choose which version of the quest badge to display. The downside to this is that some players may choose to only go for the lowest tier of the quest (Pre-Wii Mario) and ignore the Galaxy games entirely, and going against the intent of the quest to beat all Mario games. However, this could avoid ire towards quest revisions by allowing a quest to change while also preserving the initial quest design. |
Beta Was this translation helpful? Give feedback.
-
|
A few scenarios based on experience with events that should be considered:
If a revision changes the beat requirements of a set, how does that affect the quest requirement?
|
Beta Was this translation helpful? Give feedback.
-
|
One more use case I could think of that would be nice to see supported is specifying a certain amount of beats or masteries needed not just for a system or hub, but also for specific developers. I see the parameters are currently defined as this.
We have a lot of developers on the site who have worked on a great number of sets. Highlighting some of the most prolific developers with their own quest could be a nice way to show appreciation for their hard work. Adding another parameter option here could give some additional flexibility to support things like these. |
Beta Was this translation helpful? Give feedback.
-
|
After thinking through some of the given quest examples some more, I believe that the addition of way to restrict certain sets from being eligible for a quest based on their characteristics could be useful to have. To give a concrete use case to illustrateWe may have a quest asking people to master 50 Gameboy games for completion, which is a reasonably challenging number to reach if you follow the intent of the quest and explore the breadth of the Gameboy library. However, the system also has a plethora of small homebrews, which oftentimes take less than half an hour to master. The bottom 50 sets on the GB in terms of points are all below 40 points and consist almost entirely of homebrews and very tiny hacks. In this scenario, I think that the quest would be better at fulfilling its intent of getting people to interact with the library if we could in some way restrict the elegibility of sets. We already use similar low effort rules for some of the more freeform tasks in events like Challenge League, and I think having the option to add some for quests too would be useful. Ways the restriction could workThe easiest way I could think of is being able to specify eligible set types (e.g. Retail only) in addition to the system or hub to use, and I think this would already cover the majority of use cases. Another approach that we have taken in Challenge League is restricting sets under a certain total point threshold. I'm not sure if this would also be needed in addition to set type filtering, but it might be an idea worth considering. |
Beta Was this translation helpful? Give feedback.
-
|
Could the LeaderboardScore source be expanded to include time-based leaderboards, and some sort of combined time for multiple of them in one quest? (technically this could also be done for score-based leaderboards but I couldn't think of a usecase as one game could potentially be played infinitely and make no need for playing the others, the proposal's DK Million Points club is a much better idea as you are required to get a minimum in each game) For example, a quest to achieve the community challenge of the Super MariHour by beating 1 to 64 Any% in less than an hour, or something like a tiered quest for beating all 6 NES Mega Man games in under 6 hours, then 4 then 2 etc. It could even be tiered underneath the first tier of beating them in the first place. As cool as this would be, I have two concerns with this idea. The first would be whether there would be a major performance cost on the server calculating the total time for every single quest any time a leaderboard entry is made. I assume it wouldn't be much for a small number of quests, but if they can be freely user-submitted it may be taxing with hypothetical hundreds of them linked to a single game. My other concern would be some way to game the system. Say in the Mega Man example, the requirement for the first tier was having all 6 games beaten AND your total leaderboard entries under 6 hours. If you beat all six games legitimately, then submit a glitched leaderboard entry, you could speed to the final tier of the quest very quickly. The proposal mentions regressing progress if a leaderboard entry is removed, but this would also heavily reduce the combined time, so a way to ensure that each linked leaderboard has a valid entry before completing the quest would be necessary. (I started writing this assuming there was a way for a user to remove their entry manually, but as far as I can tell there isn't, so it wouldn't be as common of a problem as I thought but still potentially an issue) A minor consideration for something like the MariHour is that it doesn't follow the leaderboard rules of the whole run having to be played in one sitting, which RA has no way to track so the quest requirement would just be a combination of your best times. However, I don't see this as a real concern as speedrunning is not the main focus of RA and a badge would be more of a cool bonus on your profile that you are technically able to do it, rather than competing directly with other users over your best time. (presuming that your combined time is not visible as a seperate leaderboard, and even if it were it still isn't that big of a deal imo) |
Beta Was this translation helpful? Give feedback.
-
|
The I can think of two possible solutions:
|
Beta Was this translation helpful? Give feedback.
-
|
Not sure if such thing would be feasible or hard to implement, but besides all the straightforward ideas like beating entire series and etc, how about some more diverse Quests in terms of group of cheevos of the same kind spread across games? Examples: Master of the Robots: Completed no damage for all Mega Man robot masters in the mainline games; (Gathering all cheevos of that kind for each game) and so on... there would be tons of options and ideas, obviously the list would be curated and decided by the ones developing those quests, so no pression with stuff about "who determines this or that", we would just have cool lists based on common themes when it makes sense, and new ones added if applicable. I think these kind of stuff would instigate users more and more to put value into individual cheevos rather than full masteries like it happens today, and more dev work is enjoyed since we are attracting people that would not mastery those games, but would take on specific challenges like these, or like the name says, quests. |
Beta Was this translation helpful? Give feedback.
-
|
One feature of event achievements that I find very helpful, is the ability to set decorators to give additional context to players. We're getting a lot of use out of this feature, with it finding an application in the majority of auto-tracked events nowadays. Given that many quests might follow a similar structure to memorial events or RAD, by being a curated and guided experience through a selection of games, I think that having a similar option to assign a label to objectives might be a nice optional feature to have. Like a quest to beat best selling games for each year, or a quest to accomplish a task / beat a game related to every character in the Smash Bros roster. This could also help with making objectives containing multiple targetIDs more legible at a glance. For instance, "Beat any version of Super Mario Bros. 2" is instantly understandable to people, even if they are not aware that Super Mario Advance is a remake of SMB2. If we simply listed both games, this may not be as immediately apparent to players less familiar with the series. |
Beta Was this translation helpful? Give feedback.
-
|
I think this looks good, the only thing I have a question about is the Quest's mode parameter - I feel like setting/storing that is unnecessary, given that it can be determined by the quest requirements (if there's any leaderboard requirement, it is hardcore only). Leaving this requirement out of the spec, and having it inferred by the quest contents, would also help the system expand to future applications - for example, both Devember and the new Community Events allow for softcore players, even if those softcore players are unlocking hardcore event badges - so a quest like "earn 3 event badges" would be achievable by softcore players and erroneously marked as exclusive to hardcore players. This also eliminates potential confusion if a quest like "beat all of the classic Mega Man games" is created with a hardcore requirement but "beat all of the Pokemon games" isn't, unless there's some reason that quests should be able to explicitly require hardcore outside of hardcore-only features. |
Beta Was this translation helpful? Give feedback.
-
|
I understand how much has to be different on the backend here as compared to the current state of auto-tracked Events, but solely from a user perspective, I think this is a confusing distinction. New users will not intuitively understand the difference between Quests and Events, and per the current proposal, it cannot be explained simply. Quests are not time-gated, unlike Events, except for Evergreen events which also aren't. But Quests are auto-tracked, unlike some Events, but some Events also are, but not when they include things like leaderboard scores, which Quests can do. I see the comparison table in the proposal and it's understandable to someone who's familiar with the site as it is, but I don't think it translates well to the new user experience at all; new users are already quite confused about how Events work with the time gating, evergreen and prior credit, and things like that. This wouldn't help. I would suggest one of two things, at least for the user-facing side:
All of this may just come down to presentation and be up to the event team more than the implementation, but I think it's still worth discussing at this stage. |
Beta Was this translation helpful? Give feedback.
-
|
Some thoughts on this.
I'm thinking of CL 2024, and wondering could we automate all of it into a quest. Not to actually convert that specific event into a quest (or maybe we should?) , but more considering do we have the functionality here to do so? But beyond that, could we also do "Beat X games released in X year" or "X month"?
(Also do we have a way to mark someone as having done something, let's say we say "Beat 5 new X mega man games" but I've beat all but 3 of them and the quest is to beat 5 of them... Admin probably should have the ability to give me credit for that one step)
PS. If there's a quest team I'd be interested in assisting with this. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Version History
developer_idandsole_developerparameters to count-based objectivesexclude_game_tagsparameter to filter out certain types of games from objectivesSummary
This RFC proposes adding Quests as a third type of "playable" to RetroAchievements, alongside Games and Events.
Quests are curated, long-form, evergreen challenges that span multiple objectives: things like "beat all Mega Man games" or "master 50 SNES games" or "beat all/N games in this hub". Like events, they support tiered badge awards. They can be extended with new tiers over time while preserving existing progress.
Motivation
The Problem
RetroAchievements currently has two types of playables:
Players have routinely expressed interest in curated, long-term goals that span multiple games (eg: "hub masteries"). Currently, there's no support for this, and users often track such goals individually and informally.
Why Quests?
"Hub masteries" are undesirable because they would tightly couple an award to core site navigation infrastructure. Hubs are very routinely updated as the site evolves. Hub masteries would constantly be undergoing "revisions".
Quests address this issue, as well as the gaps mentioned in the above problem statement, by providing structured challenges that:
Here's a detailed visualization for how Quests would differ from Games and Events:
Glossary
Detailed Design
Quests can require any combination of:
Data Model
QuestThe core quest entity. Uses self-healing URLs via the
HasSelfHealingUrlstrait (same pattern as Events).QuestAwardTierAward tiers within a quest. Each tier has its own concretely-defined requirements. Note: the quest's display image is derived from the highest tier's
award_type_meta.image_asset_path. While the system supports independent tiers, quest authors should design tiers as cumulative goals (eg: Silver builds on Bronze requirements). New tiers can be added to published quests, but existing tiers cannot be modified.QuestObjectiveIndividual requirements within a
QuestAwardTier. If the user completes these requirements, they receive the award.Objective Alternatives
Some objectives may be satisfied by completing any one of several alternatives. For example, "Beat Final Fantasy I" could be satisfied by beating the NES, GBA, PSP, or WonderSwan version. To support this,
target_idsis a JSON array. For specific-target objectives, the objective is complete when ANY target in the array is satisfied. For count-based objectives,target_idsis null.Examples:
target_ids: [1234]target_ids: [1234, 5678, 9012](complete when any one is done)PlayerQuestTracks a user's overall progress on a given quest. This is analogous to
player_gamesorplayer_achievement_setsin the database. Note: bothcompleted_atandcompleted_hardcore_atare tracked because users may toggle between softcore and hardcore modes during their playthrough.PlayerQuestObjectiveTracks a user's completion of individual quest objectives. This is analogous to
player_achievementsin the database.QuestSeriesOptional grouping for related quests (eg: "1980 Greatest Hits", "1981 Greatest Hits", "1982 Greatest Hits", etc). This is very similar to hubs, but exclusive to quests and may have a much different UI treatment.
QuestEventA lightweight queue table for tracking platform actions that may affect quest progress. Processed by a periodic batch job that would run every 10 minutes. Once the job is done, all the rows in the table are deleted.
Enum Values
QuestStateNote on deletion: Only quests in
Draftstate can be soft deleted. Once a quest is published (state becomesActive), it can only beRetired(permanently ended), never deleted. This preserves integrity of any user progress or awards. Users who earned badges from retired quests keep them, displayed with a subtle "retired" indicator. This is similar to awards for~Z~'d games.QuestModeQuestObjectiveTypeThis RFC includes 10 objective types, split into two categories:
Specific target types (require
QuestObjective.target_ids, satisfied when ANY target is completed):GameBeaten: user has beaten a specific game.AchievementSetCompleted: user has completed or mastered a specific achievement set.AchievementUnlocked: user has unlocked a specific achievement.LeaderboardScore: user has achieved a minimum score on a leaderboard (be sure to account forLowerIsBetter).LeaderboardRank: user has achieved a minimum rank on a leaderboardQuestAwardTierEarned: user has earned a specific award tier in another quest (enables quest nesting)EventAwardTierEarned: user has earned a specific award tier in an event (should be an evergreen event)Count-based types (
target_idsis null, optional filters defined inQuestObjective.parameters):GamesBeatenCount: user has beaten N games matching prescribed filtersSetsMasteredCount: user has mastered N achievement sets matching prescribed filtersSetsWithAchievementsCount: user has unlocked achievements from N different achievement sets (think: "World Tour")Objective Parameters Reference
GameBeaten[game_id, ...]{}AchievementSetCompleted[achievement_set_id, ...]{}AchievementUnlocked[achievement_id, ...]{}LeaderboardScore[leaderboard_id, ...]{min_score: int}LeaderboardRank[leaderboard_id, ...]{min_rank: int}QuestAwardTierEarned[quest_id, ...]{min_tier: int}EventAwardTierEarned[event_id, ...]{min_tier: int}GamesBeatenCount{count: int, system_id?: int, hub_id?: int, developer_id?: int, sole_developer?: bool, exclude_game_tags?: string[]}SetsMasteredCount{count: int, system_id?: int, hub_id?: int, developer_id?: int, sole_developer?: bool, exclude_game_tags?: string[]}SetsWithAchievementsCount{count: int, system_id?: int, hub_id?: int, developer_id?: int, sole_developer?: bool, exclude_game_tags?: string[]}Developer Filtering for Count-Based Objectives
The
developer_idandsole_developerparameters allow quests to target content developed by specific achievement developers:developer_id: Filter to games where this user hasuser_idon achievements in the game's achievement sets.sole_developer(default: false): When false, a game qualifies if the developer authored any published achievement. When true, a game qualifies only if the developer authored all published achievements.The scope of "achievement sets" varies by objective type:
GamesBeatenCount: Looks at the base achievement set only (since beaten status is determined by progression/win condition achievements, which are only in base sets).SetsMasteredCount: Looks at all achievement sets (base and subsets).SetsWithAchievementsCount: Looks at all achievement sets.Game Tag Filtering for Count-Based Objectives
The
exclude_game_tagsparameter filters out games by their tags. Valid values:demo,hack,homebrew,prototype,test_kit,unlicensed.Games are tagged via the
~Tag~pattern in titles (eg: "~Hack~ Super Mario 64"). "Retail" is not a tag - it's the absence of several of these tags. To restrict an objective to retail games only, exclude all tags exceptunlicensed.Note: Subsets inherit their parent game's tags, so excluding
hackwill also exclude subsets of hack games.Extension Model
Quests are designed to be stable, long-term goals. However, they can be extended with new tiers over time (eg: a new game is added to a series, unlocking a higher tier).
Design Philosophy:
Quests should be cautiously & judiciously designed. Once published, existing tiers are largely immutable, with very limited exceptions for strictly additive changes. This forces quest authors to design carefully upfront and prevents the FOMO that would result from constantly-changing requirements.
Why allow additive changes?
Strict immutability creates problems for real-world scenarios where the platform evolves:
any_nto let players earn credit from any 2 of 3 AOTW years. Without additive changes, a future year's AOTW can never be added as an option.Additive-only changes solve these problems while preserving the core immutability principle: quests never get harder for existing players.
What can be changed after publication:
tier_indexhigher than existing tiers).any_nrequirement type tiers (adds options, never makes tier harder).What cannot be changed after publication:
requirement_type, orrequired_count.allrequirement type tiers.Backfill on Additive Changes:
When new target_ids are added to an objective, a backfill job is dispatched to credit users who already completed the newly-added targets. The original completion timestamp from platform data is used, ensuring users get proper credit for work they've already done.
When should a quest be retired?
If a quest's premise is fundamentally broken (eg: references content that will never be restored), the quest should be retired. Retirement is intentionally heavy-handed to discourage casual changes:
~Z~'d game badges.Quests should be designed such that quest retirement is an exceptionally rare last resort to preserve the integrity of the quests system itself.
Underlying Data Changes
Quest objectives are initially evaluated against current platform completion state. Once a
PlayerQuestObjectiveis marked complete (completed_at/completed_hardcore_atis set), it becomes a durable record. However, certain platform changes can cause a player's quest progress to regress.Data Sources for Quest Objectives:
GameBeatenplayer_gamesbeaten_at,beaten_hardcore_atAchievementSetCompletedplayer_achievement_setscompleted_at,completed_hardcore_atAchievementUnlockedplayer_achievementsunlocked_at,unlocked_hardcore_atLeaderboardScoreleaderboard_entriesscore(compared againstmin_scoreparameter)LeaderboardRankleaderboard_entriesQuestCompletedplayer_questscompleted_at,completed_hardcore_atEventAwardTierEarnedplayer_badgesAwardType,AwardData,AwardDataExtraGamesBeatenCountplayer_statsSetsMasteredCountplayer_statsSetsWithAchievementsCountplayer_achievementsCOUNT(DISTINCT achievement_set_id)calculated on the flyProgress Evaluation
Quest progress is calculated automatically for all users based on their normal activity on RA. Users can browse quests and immediately see their current progress.
To ensure server health is unaffected, quest progress is determined via queue-based batch processing, not too dissimilar from search updates (Laravel Scout) for games and achievements.
Triggering Events
The following platform events will insert rows into
quest_events:PlayerBeatenGamesStatsUpdated- for game beaten objectives and count-based beaten objectivesPlayerBadgeAwarded- for mastery/completion objectives and event award tier objectivesPlayerAchievementUnlocked- for achievement unlock objectivesAn example flow would be:
UpdatePlayerBeatenGamesStatsActionfires (this already happens today).player_statsis updated, andPlayerBeatenGamesStatsUpdatedis dispatched.QuestProgressListenerpicks up this dispatched event.quest_events, which acts as a queue.quest_eventsqueue every 10 minutes, updating the affectedPlayerQuestObjectiverecords.The
quests_eventstable acts like a queue, with a periodic background batch job processing events. When an event is processed, matching quest objectives are found, andPlayerQuestObjectiverecords get updated.It may be desirable to give impatient players a "manual refresh" option on the quest page. If implemented, this should be rate limited (eg: once per minute per user).
PlayerStatType Extensions
Count-based objectives will leverage the existing
player_statstable rather than recalculating counts on the fly. This requires extendingPlayerStatTypewith new stat types:Note:
SetsWithAchievementsCountobjectives should be calculated on the fly viaCOUNT(DISTINCT achievement_set_id)queries rather than maintaining a dedicated stat, since these "World Tour" style objectives are likely to be relatively rare.Tags
Quests shall use
spatie/laravel-tagswith a "quest" namespace. We can have some starting tags that are system-based ("nes", "snes", etc), type-based ("series", "beginner", "expert"), and theme-based ("rpg", "platformer").Awards
Quests shall integrate with the existing
PlayerBadge(SiteAwards table) system:Access Control
Quest creation and editing will be restricted to either the admin team or an as-of-yet unformed "Quest Team" role. All published quests are visible to all users.
Example Quest Definitions
Series Quest: Mega Man NES
Beat All Final Fantasy Games Quest (with alternatives)
This example shows how
target_idssupports alternative targets. Each FF game has multiple versions, and beating ANY version satisfies the objective.Beat Some Retail SNES Games Quest
This quest has objectives which specifically exclude games with tags.
Donkey Kong Million Point Club Quest (leaderboard scores)
This example shows how quests can require achieving minimum scores on leaderboards via
LeaderboardScore.Beat Any 3 of These 5 Games Quest
Console Conqueror Quest (quest nesting)
This example shows how quests can require completion of other quests via
QuestAwardTierEarned.Achievement of the Week Veteran Quest (event tiers)
This example shows how quests can require earning tiers across multiple evergreen events via
EventAwardTierEarned.Developer Appreciation Quest
This example shows how quests can celebrate prolific developers by requiring players to beat or master sets they've worked on.
Beta Was this translation helpful? Give feedback.
All reactions