I’m working on developing an NFT project and want to add different tiers or levels to make it more interesting for collectors. I’ve seen other projects that have basic, rare, epic, and legendary categories with different attributes and values.
Right now I have a simple NFT setup but I want to expand it to include multiple levels with different rarity percentages. Each level should have unique properties and maybe different artwork or stats.
I’m currently using Python along with brownie framework for compiling and deploying my smart contracts. What would be the best approach to implement this kind of leveling system? Should I handle the rarity logic in the smart contract itself or generate the metadata beforehand?
Any guidance on structuring the contract code and metadata would be really helpful.
metadata approach is def the way to go. i pre-generate all rarities using weighted random selection, then just reference them when minting. gas costs are way lower and u can test everything locally. just shuffle your metadata JSONs so rare items aren’t always tokens #1-100. used this for 3 collections now.
In my experience with a gaming NFT project, I implemented rarity directly within the minting contract using a pseudo-random generator to manage weighted probabilities for different tiers. We capped the supply for each tier—e.g., just 100 legendary tokens out of a potential 10,000.
A key takeaway was to keep rarity logic separate from metadata creation. The contract determined the tier at the time of minting and emitted an event with that information. This allows your backend to acknowledge these events and create the appropriate metadata and artwork afterward.
For efficiency, I chose to store only the tier level in the contract, rather than all attributes, which lowered gas costs. The metadata URI was designed to dynamically deliver the complete properties based on the tier, allowing for updates to artwork or stats without needing to redeploy the entire contract.