I have put some thought (perhaps too much) about what I think the ideal quest system would look like (see below). While I don’t know if something like this was intended as an answer, the content is relevant when thinking about the design/architecture of the new quest system, which is why I wanted to write it here anyways. Also, I hope this is the correct place to put it (Not sure if this is what was meant by the “gov forum thread”).
Definitions used
- Governance entity: The entity, person, group of persons, smart contract, voting system or DAO that is responsible for managing quests
- Governance system: The system used by the Governance entity
Quest data storage
I would suggest creating a smart contract that keeps track of the quest creator and references a JSON file containing the quest data via URL (for example using IPFS). This smart contract should have the following functions:
- a public function for quest creation (new quests might start as a proposal before they are displayed to everyone)
- a function to accept a quest proposal (only callable by the governance entity)
- a function to edit the URL/IPFS hash should there be an error (should probably be callable by the governance entity and the quest creator, in the latter case it might make sense that the change must be accepted first)
- a function to remove a quest (only callable by the governance entity)
- a function to mark a quest as played by an address. This could be stored as a mapping(address => mapping(questID => Boolean)). (Only callable by the quest submission verification system)
- (optional) all ERC-721 methods (so that the owner can transfer ownership if he wants or even trade it).
The quest solution probably should not be stored in the quest data, as that would easily allow someone to cheat (a problem most decentralized solutions probably have).
Additionally, there should be at least one entity running an IPFS node storing quest data (even if centralized), otherwise it might happen that quest data is lost at some point.
Reasons:
- Storing the quest (and ownership) in a smart contract provides Integrity, everyone can see any changes made and the history of all quests is stored (at least while the file is on IPFS)
- Storing the quest data/settings/config via IPFS means less data needs to be stored on chain.
- Everyone can access the quest data and it is stored decentralized. That way nobody can modify it unless they use the governance system.
- This is probably the simplest system to store quest ownership and data on the blockchain while allowing a governance entity to manage/filter the quests.
- Having all quest data available allows different systems / User Interfaces to use the quest system (as proposed below)
Quest evaluation
This is probably the hardest part to decentralize without providing too many opportunities to cheat. I currently see two possible options:
- Keep quest evaluation in the centralized codebase and share quest solutions between a subset of community members (part of and/or selected by the governance entity). If the centralized company is unable to verify correct results the data is at least not lost but still available. There should also be a (well documented) public repository allowing easy deployment of an alternative. To allow the switch it might be necessary to store the URL of the quest verifier in the smart contract.
- Use a system that can store secrets on the blockchain (or in a node that provides it to the smart contract). The user could submit his (encrypted) result to a smart contract that emits an Event for which a Node listens, who then checks if the answer is correct. Currently the only system doing something similar that I know of would be ChainLink, but I don’t know much effort this would be to implement.
I do not know which solution would be better or easier to implement. The second one would probably be more resilient, as it is already decentralized. Nevertheless, only a limited amount of people should have access to the quest solutions. I would recommend to choose the first option but implement it in such a way that it is possible to switch if needed.
(optional) Centralized Cache
Given the number of quests it might be worth storing a list of them (Name, Creator, …) on a server or IPFS file, to reduce the number of requests the browser must send to display the Quest list. This should probably include the author profile pictures as they are currently quite slow to load.
Browsing Quests
I would suggest keeping a list of quests, but make the following modifications:
- Make the list sort-able (Client-side). Sometimes I only have 15min, so I’m not yet interested in quests with 30min reading time.
- Remove the Description, Quest Owner and Stage columns and instead make a quest entry expand on click to show this information below the table entry. The “Info” button never worked for me (it’s probably better to display the entire text if you clicked on a quest entry) and when searching for a quest I’m usually not immediately interested in the Quest Owner.
- Instead of the Stage column display if a quest has been beaten and how many attempts where made (I currently can’t see the attempt number until I play the quest. The number of attempts could also be only displayed after expanding a quest entry.
- Make the search completely client-side to make it faster (as far as I can tell the information is already loaded in the browser on page load)
- Don’t have anything below the Quest table, instead put it in another tab (even if the tab switch is completely on the client side). I don’t think it is user friendly if you must scroll past a long list of quests to get to other parts of the application.
- (optional) Remove tabs and improve quest filtering. Perhaps some people don’t care about how difficult a quest is because they want to get them all. Instead, I would suggest adding a show-only-beaten, show-only-attempted, show-only-new checkbox filter and do the same for difficulty. Ideally there would also be a min/max limit for the estimated play time. (In addition to the existing search option). If there are multiple quest types (as the current codebase seems to suggest) there should also be a filter option (or even a column) displaying what type of quest it is.
- Force all quest entries in the table to be of the same (pre-defined) height (if it’s possible at least). This would prevent items from moving around while the page is loading (which was previously the case, I think)
Regarding Implementation, I would suggest building this part in Vue or React, then build it to static files and deliver it from the gitcoin server and/or from IPFS.
Playing a quest
I do not have a proposal for changing how a quest is played, except for this:
- First, everything related to the quest system should be well documented. This includes how to get quest data from the smart contract and IPFS, how to use the verification system to check if an answer is correct or not and where to get all the media files used by the current/official quest system (and referenced by the quest data).
- Quest creators should be able to add custom files (for example a custom background) by including the (IPFS) URL/Hash in the json file. This would allow more flexibility in the quest creation and the media files wouldn’t have to be provided by gitcoin.
- (optional) It should be possible to create a second version of the quest system using the same quest data with the information provided by the documentation. This could, for example be using three.js to display Information or the quest environment in 3D but might be limiting which quests can be used.
- (optional) To achieve Modularity the player should be able to select which quest User Interface they want to use (for example someone with a slow PC might not want to display things in 3D). This could be done by having a selection in the quest list and a (cached) list of supported quests for each User Interface.
Similar to “Browsing Quests”, this should probably be build into a static site and hosted on the gitcoin website and/or IPFS.
Winning & receiving a reward
I do not have a good idea on how to improve this part, but here are my thoughts:
- Personally, I like that you can get Kudos for playing a quest, but I find it a bit weird that multiple quests give the same Kudos, and it is rarely related to the Quest itself (for example “Robot Found His Love” has nothing to do with the quest “Journey to IPFS”, as far as I can tell). There are so many Kudos, that perhaps each quest should give a different one (though there are probably a thousand reasons otherwise).
- If someone can come up with a good ERC-20 reward, perhaps it can be combined with rewarding Kudos: You get the ERC-20 reward for all quests (maybe the amount is based on the difficulty and/or time estimate) and some quests additionally give a Kudos. Ideally one that fits the quest.
Regarding implementation of the reward(s):
It is probably best to have a second smart contract with setQuestFinished-rights on the first smart contract that is called by the submission verifier (or the user with a valid signature of a verifier), gives the reward(s) and set’s the quest to completed in a single transaction.
Open Questions (that I can think of)
- How to keep the quest solution secret (see above for the Ideas I had)
- How to implement the time limit for questions and the attempt count. The player could receive the questions via HTTP from a server instead of them being publicly visible on the blockchain, but this would be a more centralized solution.
Please include
I’m currently studying IT-Security and have some experience in Solidity, Django, Vue3 and React.
Mainly, I wanted to give my thoughts on the topic, but I’m open to help building it, too (together with other people). Because I don’t yet know how much time I have next semester, how many people would work on it or the exact scope, I obviously cannot give a timeline.