The Doomsday NFT
In the year 2022, the catastrophic failure of an orbital space project rained explosive debris across the earth.
The weeks of destruction and resulting fallout from this event would destroy all life on the planet.Only those in secure bunkers that did not receive a direct hit from the debris would survive.
Lock those blast doors and open up a fresh tin of beans because I’m about to breakdown the code and design of my new project, Doomsday NFT.
Doomsday NFT
Before we get dug into things, I should give you a basic description of the project. To alleviate your fears, no this isn’t a generic pfp shill, in fact this isn’t a shill at all. If you came here looking for things to buy, look elsewhere, we’re here to talk about tech.
In a nut shell, Doomsday NFT utilises NFTs as a component of an on-chain survival game set in a world on the verge of an apocalypse. Every token represents a Bunker hidden below a city around the world. The map-position of that bunker is stored on-chain, and when the apocalypse begins, on-chain impacts will destroy bunkers until one remains. The owner of the final surviving bunker gets to claim a prize.
This article will break down first the key tech elements as well as some of the game design choices.
The Tech
One of the key technical components used in this game is the retroactive use of the blockhash
. Long-time readers may remember that I wrote an article about this a few years ago which covered its use in a boat-racing DApp I made (and which never took off for a variety of reasons). Whether or not you read this don’t worry, the implementation is a little different (and simpler) this time.
blockhash
Solidity makes available the has of the 256 most recently mined Ethereum blocks. The blockhash is effectively unknowable to anyone ahead of time, even the person mining. When a person does successfully mine a block, they don’t have the power to change the blockhash without starting the mining process again, so unless they stand to lose millions of dollars from that particular blockhash, its unlikely they’d do so, because someone else will mine the block and get the block reward. What all this means is that blockhash, if used correctly, is a completely secure, unpredictable source of on-chain randomness.
The determinism of blockchain transactions do make on-chain randomness harder. If a tx depends on a certain random value, and that value is calculated during that tx, then it’s trivially easy to peak at the answer before you commit to the action.
However, using the blockhash of a specific block from some time in the past can’t be cheated, as long as the commitment to the result happened before that block.
An analogy would be if we were to bet on whether the temperature in my home town would be above or below 30°C (86°F) on Sunday. As long as we both commit our guesses before Sunday, and the winner can collect their prize from Monday, there’s no way to cheat. Before Sunday it was unknowable, and after Sunday it can’t be changed. (Meteorologists don’t @ me, to us mere mortals it’s all random).
How we do this with blockhashes is to offset and modulo the current block number and use that blockhash. This is what that looks like:
uint INTERVAL = 120;
uint targetBlock = block.number - (block.number % INTERVAL) - 5;bytes32 hash = blockhash(targetBlock);
INTERVAL
is how long (in blocks) the randomness source stays the same. By subtracting the INTERVAL
modulo of block.number
from block.number
, it is effectively rounding block.number
down to the nearest multiple of INTERVAL
. The reason we also subtract 5 is because chain re-orgs happen fairly often, but are rarely deeper than 1 or 2 blocks. 5 ignores the 5 most recent blocks in our randomness.
You can pick any value for INTERVAL
, or for the re-org shield, but they must sum to less than 256, because beyond that the blockhash isn’t available.
Impacts
So how does Doomsday NFT use this? Initially there is a Pre-Apocalypse period where people can acquire Bunkers, this will last for a week, and then the Apocalypse begins. At this point it uses the above method to randomly generate the location and radius of an impact every 120 blocks (30–40 min).
All bunkers have their projected map coordinates stored on-chain, and impact coordinates and radii are in the same units, so it’s simply a case of basic trigonometry to check if a bunker has been hit. If it is, then for the next 120 blocks this fact is irrefutable. During that period, anyone can call a confirmHit
transaction and register the effects. The impact is displayed on the game’s tactical map, with vulnerable cities showing in red and yellow.

0.01 ETH (25% of the mint fee) is set aside for this purpose, it is paid to whoever makes this transaction. The value was chosen as it should always be above the cost of the transaction within reasonable gas price ranges. This creates an incentive for anyone to call it, and thus ensures that any impact will be registered, as well as rewarding active participation. In the most extreme gas spikes, there is still an incentive to call this function if you are any player other than the one being hit, as you still benefit by eliminating competition.
In the late stages of the game, the average blast radius will grow as the number of survivors diminishes. This is to counteract the lower chance of hitting a remaining Bunker.
Economics
Any well designed blockchain project needs to understand incentives. If you don’t get this right, then any system you build will inevitably collapse. Doomsday NFT was designed to make participation accessible while still respecting players inevitable wish to improve their chances of success.
Mint Fees
I wanted to keep mint fees as low as possible, however, the constraining factor for mint fees was the confirm-hit transaction reward. The value of 0.01 ETH was important to keep it alluring, but I wanted to make sure at least half of the mint fees were going to the prize pool. As someone who has spent several months building this, I also needed to keep some for myself to make it worth while. This is why the mint fee of 0.04 ETH was chosen:
- 0.02 ETH to prize pool
- 0.01 ETH to hit confirmer
- 0.01 ETH to creator
0.04 ETH seemed like the smallest value that still allowed for a fair distribution.
Mint limit and scarcity
There is no limit on how many tokens someone can mint. The database of cities from which the tokens are generated contains about 38,000 unique locations, however it’s not expected this many tokens will be minted. It was chosen to allow people to select cities they knew or lived in in real life. It also adds some natural clustering to the location of the cities, and allows players to make calculated decisions on which bunkers they choose to inhabit. The high number of unique bunkers means nobody will be excluded during the mint phase, and a higher number of tokens benefits everybody as it means a larger prize pool.
However, after 7 days when the Apocalypse begins, minting will be halted permanently. At this point the total supply of tokens will only ever decrease as Bunkers are destroyed.
Evacuation and floor price
The owner of any Bunker may choose to evacuate it at any time (assuming it isn’t currently inside the blast radius). Evacuation will destroy the Bunker, and pay out a portion of the prize pool.
The formula that determines the payout is as follows:
uint payout = //Winner fee from mints less evacuated funds
((MINT_COST * TOTAL_BUNKERS * MINT_PERCENT_WINNER / 100 - evacuatedFunds) //Divided by remaining tokens
/ totalSupply()) //Divided by two
/ 2 //Plus the fee that would have been given to the confirmer
+ CONFIRM_HIT_FEE;
Effectively, if there are N tokens remaining, you get Prize / N / 2
.
The / 2 is important, as it disincentivises people bailing out too early, and guarantees that there’s always greater reward for risking playing on. What it also means is, if you aren’t in the first 50% of players to be eliminated, you can bail out at any time and still end up with more ETH than you started with. Different players will have different strategies, the ides was to build out enough to allow emergent behaviour.
However, this should set a floor price for any remaining Bunkers, as they can instantly be Evacuated for the payout stated. The market value for Bunkers should therefore be determined by different actors arbitraging what they think is the ideal strategy. So the longer the game continues, the floor price should continue to rise.
Reinforcement
Beyond strategic Bunker selection and evacuation, players have the option to reinforce their Bunker. For each time a Bunker is reinforced, it can withstand an extra hit, but the cost to do so doubles each time. This allows late-game players who have a high chance of winning a large pool of ETH to increase their chances while decreasing their expected return. The decision to use an exponential reinforcement cost was to mitigate the effect that high wealth-disparity between players would have on the game outcome, while still respecting players’ wish to use this mechanic as much as they desire. 90% of Reinforcement fees are added to the prize pool.
A note on the Bunkers
For anyone wondering about the Bunker artwork, each bunker was generated using the population of the associated city as a seed. Rather than adding or removing elements as a lot of large-batch NFT art does, the Bunker art generator maps out a unique layout, and populates it with different pre-designed rooms selected according to size, as well as a unique skyline. This was one of the benefits of using the skeuomorphic, 70s-scifi aesthetic, as this era lent on more stylised vector imagery.

Impact Imminent: Seek Shelter
So good luck if you’re a player, and if you’re a creator I hope this article provided insights you can bring to your next project. This is all very new territory, and although I built in anticipation of many conflicting behaviours, there’s too much craziness in this space to ever know how something is going to end up.
Useful project links: