NFT Breeding System Development
NFT breeding—creating new NFT by "crossing" two existing ones with inherited characteristics. Mechanic became popular with CryptoKitties and Axie Infinity. Properly implemented breeding system creates multi-level economy: market for "breeders", market for "purebreds", strategic decisions about breeding combinations.
Genetic System Design
Key question: how do attributes pass from parents to offspring?
Gene Encoding
Each NFT has gene set—numerical attribute values. Typical structure:
struct Genes {
uint8 bodyType; // 0-255, encodes body type
uint8 color; // 0-255, color
uint8 speed; // 0-100, speed
uint8 strength; // 0-100, strength
uint8 intelligence; // 0-100, intelligence
uint8 rarity; // 0-7, rarity level
uint8[4] hiddenGenes; // recessive genes (invisible, but passed on)
}
Recessive genes—hidden genes not affecting current NFT characteristics but possibly manifesting in offspring. Creates system depth: two ordinary-looking NFTs can produce rare offspring.
Inheritance Mechanic
function _inheritGene(
uint8 parentAGene,
uint8 parentBGene,
uint256 random,
uint8 geneIndex
) internal pure returns (uint8 childGene) {
// 50% chance for each parent
bool fromParentA = (random >> geneIndex) & 1 == 1;
uint8 inheritedGene = fromParentA ? parentAGene : parentBGene;
// 10% mutation chance
uint256 mutationRoll = (random >> (geneIndex + 8)) & 0xFF;
if (mutationRoll < 26) { // ~10% (26/256)
// Random mutation within ±20% of inherited value
int16 mutation = int16(uint16((random >> (geneIndex + 16)) & 0xFF)) - 128;
int16 mutated = int16(uint16(inheritedGene)) + mutation / 10;
childGene = uint8(uint16(mutated < 0 ? 0 : mutated > 255 ? 255 : mutated));
} else {
childGene = inheritedGene;
}
}
Smart Contract: Full Implementation
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BreedableNFT is ERC721, AccessControl, VRFConsumerBaseV2Plus {
struct NFTData {
uint256 tokenId;
uint256 generation; // generation (0 = genesis)
uint256 breedCount; // how many times bred
uint256 maxBreeds; // max breeds allowed
uint256 lastBreedTime; // timestamp of last breeding
uint256 breedCooldown; // in seconds
Genes genes;
bool isOnBreedingMarket;
}
mapping(uint256 => NFTData) public nftData;
// Breeding cost in ERC-20 tokens
IERC20 public breedingToken;
uint256[] public breedingCosts; // by generation: gen0 cheaper, gen5 expensive
// Cooldown increases per breed
uint256 public baseCooldown = 12 hours;
mapping(uint256 => BreedingRequest) public pendingBreeds;
struct BreedingRequest {
address breeder;
uint256 parent1Id;
uint256 parent2Id;
bool fulfilled;
}
event BreedingInitiated(uint256 requestId, uint256 parent1, uint256 parent2);
event BreedingCompleted(uint256 requestId, uint256 newTokenId, Genes childGenes);
function breed(uint256 parent1Id, uint256 parent2Id)
external returns (uint256 requestId)
{
// Check rights
require(ownerOf(parent1Id) == msg.sender, "Not owner of parent1");
require(
ownerOf(parent2Id) == msg.sender || nftData[parent2Id].isOnBreedingMarket,
"No access to parent2"
);
// Check limits
NFTData storage p1 = nftData[parent1Id];
NFTData storage p2 = nftData[parent2Id];
require(p1.breedCount < p1.maxBreeds, "Parent1 max breeds reached");
require(p2.breedCount < p2.maxBreeds, "Parent2 max breeds reached");
require(
block.timestamp >= p1.lastBreedTime + p1.breedCooldown,
"Parent1 on cooldown"
);
require(
block.timestamp >= p2.lastBreedTime + p2.breedCooldown,
"Parent2 on cooldown"
);
// Prevent inbreeding (optional)
require(!_areRelated(parent1Id, parent2Id), "Inbreeding not allowed");
// Pay for breeding
uint256 gen = Math.max(p1.generation, p2.generation);
uint256 cost = breedingCosts[Math.min(gen, breedingCosts.length - 1)];
breedingToken.transferFrom(msg.sender, address(this), cost);
// Update parents
p1.breedCount++;
p1.lastBreedTime = block.timestamp;
p1.breedCooldown = baseCooldown * (1 + p1.breedCount); // increasing cooldown
p2.breedCount++;
p2.lastBreedTime = block.timestamp;
p2.breedCooldown = baseCooldown * (1 + p2.breedCount);
// Request VRF for offspring genes
requestId = _requestVRF();
pendingBreeds[requestId] = BreedingRequest({
breeder: msg.sender,
parent1Id: parent1Id,
parent2Id: parent2Id,
fulfilled: false,
});
emit BreedingInitiated(requestId, parent1Id, parent2Id);
}
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)
internal override
{
BreedingRequest storage req = pendingBreeds[requestId];
require(!req.fulfilled, "Already fulfilled");
req.fulfilled = true;
NFTData storage p1 = nftData[req.parent1Id];
NFTData storage p2 = nftData[req.parent2Id];
// Generate offspring genes
Genes memory childGenes = _generateChildGenes(p1.genes, p2.genes, randomWords[0]);
// Determine rarity
uint8 rarityRoll = uint8(randomWords[0] % 100);
if (rarityRoll < 1) {
childGenes.rarity = 7; // Legendary (1%)
} else if (rarityRoll < 5) {
childGenes.rarity = 6; // Epic (4%)
} else if (rarityRoll < 15) {
childGenes.rarity = 5; // Rare (10%)
} else {
// Inherit from parents
childGenes.rarity = uint8(Math.max(p1.genes.rarity, p2.genes.rarity));
}
// Mint offspring
uint256 newTokenId = ++tokenCounter;
_mint(req.breeder, newTokenId);
nftData[newTokenId] = NFTData({
tokenId: newTokenId,
generation: Math.max(p1.generation, p2.generation) + 1,
breedCount: 0,
maxBreeds: _calculateMaxBreeds(childGenes),
lastBreedTime: 0,
breedCooldown: baseCooldown,
genes: childGenes,
isOnBreedingMarket: false,
});
emit BreedingCompleted(requestId, newTokenId, childGenes);
}
}
Breeding Marketplace
Owner can list NFT "for breeding" for fee:
struct BreedingOffer {
uint256 sireId; // NFT available for breeding
uint256 price; // cost in tokens
bool onlyWhitelisted; // only specific addresses
mapping(address => bool) whitelist;
}
Genealogy Tree
Storing parent history for display and anti-inbreeding:
CREATE TABLE nft_lineage (
token_id BIGINT PRIMARY KEY,
parent1_id BIGINT REFERENCES nft_lineage(token_id),
parent2_id BIGINT REFERENCES nft_lineage(token_id),
generation INTEGER NOT NULL DEFAULT 0,
bred_at TIMESTAMPTZ
);
Economic Balance
Breeding system must be economically balanced with supply control via limited breeds, growing costs, cooldowns, demand drivers through unique visuals, gameplay advantage, rarity hunting, and breeding market revenue.
Timeline
- Basic breeding (genes + VRF + inheritance): 5-7 weeks
- Breeding marketplace: +2-3 weeks
- Genealogy tracking + visualization: +2-3 weeks
- Anti-cheat + economic tuning: +2-3 weeks
- Security audit: mandatory, +4-5 weeks
- Total: 3-4 months







