We're building an NFT card game called Block Monsters. The high level vision is to be "Roblox on the blockchain", where there's no central authority that extracts 30% or more of creator profits. We’re focusing on card games because there are no decentralized card game engines on Ethereum. There's two ideas that we're focusing on. The first is community generated cards where players and creators make their own custom cards. Normally, all cards are defined by the game creators and the community cannot make cards. In our project, cards are minted through a character-creator. Users can select from a number of visual traits and provide a name and a story for their monsters. All of this gets minted directly on-chain. The second feature is evolving NFTs that change based on player skill. As players play the game, their monsters can level up. When a monster levels up, the NFT card changes and the actual graphics of the card change as well. The NFT’s metadata URI is computed on chain as a data URI, allowing the card’s graphics and other metadata to programmatically change as the player plays the game.
We used scaffold-ETH, which consists of React, Ethers.js, and Hardhat. There are a few key functionalities in the contract code: (1) on-chain tokenURI generation using data URIs, (2) random generation of monster stats based on block timestamp, (3) upgrading a monster’s stats using skill points. The on-chain tokenURI generation is especially interesting. It lets the NFT’s image (and other metadata) change based on gameplay. It also allowed us to build a decentralized “character-creator” where the user can choose a number of stylistic attributes and pass those attributes to the chain in the mint function, rendering a valid NFT card. If the character-creator mechanism was not on chain, users would be able to “cheat” the character creator and mint tokens with arbitrary metadata. On the frontend, we use React for our UI and React reducers for the gameplay engine, with Ethers.js to communicate with the chain.