# Contract 4: GameEngine - The Game Logic Hub

#### Combat System

```solidity
function fightEnemy(uint256 tokenId) external nonReentrant {
    require(evolutionNFT.ownerOf(tokenId) == msg.sender, "Not owner");
    require(block.timestamp >= lastActionTime[tokenId] + 1 hours, "Cooldown active");
    
    uint256 currentLevel = traitFusion.getTraitAsUint(address(evolutionNFT), tokenId, "level");
    uint256 currentEnergy = traitFusion.getTraitAsUint(address(evolutionNFT), tokenId, "energy");
    
    require(currentEnergy >= 20, "Not enough energy");
```

**What's happening here?**

* Checks if player owns the NFT
* Enforces 1-hour cooldown between fights
* Gets current level and energy from TraitFusion
* Requires at least 20 energy to fight

```solidity
// Consume energy
traitFusion.setTraitUint(address(evolutionNFT), tokenId, "energy", currentEnergy - 20);

// Gain XP and potentially level up
uint256 xpGain = 10 + (currentLevel / 2);
uint256 newLevel = currentLevel + (xpGain / 100);

if (newLevel > currentLevel) {
    traitFusion.setTraitUint(address(evolutionNFT), tokenId, "level", newLevel);
    // Increase strength on level up
    uint256 currentStrength = traitFusion.getTraitAsUint(address(evolutionNFT), tokenId, "strength");
    traitFusion.setTraitUint(address(evolutionNFT), tokenId, "strength", currentStrength + 5);
}
```

**What's happening here?**

* Reduces energy by 20 points
* Calculates XP gain (higher level = more XP)
* Every 100 XP = 1 level up
* When leveling up, adds 5 strength points
* **This is where the evolution happens!**

#### Real-World Data Integration

```solidity
function updateSteps(uint256 tokenId, uint256 steps) external onlyRole(ORACLE_ROLE) {
    dailySteps[tokenId] = steps;
    
    // Convert steps to stamina (1 step = 0.01 stamina)
    uint256 currentStamina = traitFusion.getTraitAsUint(address(evolutionNFT), tokenId, "stamina");
    uint256 staminaBonus = steps / 100;
    uint256 newStamina = currentStamina + staminaBonus;
    if (newStamina > 200) newStamina = 200; // Cap at 200
    
    traitFusion.setTraitUint(address(evolutionNFT), tokenId, "stamina", newStamina);
```

**What's happening here?**

* Only oracle can call this (real-world data source)
* Converts real walking steps to in-game stamina
* 100 steps = 1 stamina point
* Caps stamina at 200 to prevent infinite growth

```solidity
// Milestone rewards
if (steps >= 10000) {
    gameToken.mint(evolutionNFT.ownerOf(tokenId), 200 * 10**18);
    emit QuestCompleted(tokenId, "daily_10k_steps", 200);
}
```

**What's happening here?**

* If player walks 10,000+ steps, they get 200 game tokens
* Real-world activity = in-game rewards!

#### Loot Box System with Chainlink VRF

```solidity
function openLootBox(uint256 tokenId) external nonReentrant {
    require(evolutionNFT.ownerOf(tokenId) == msg.sender, "Not owner");
    require(gameToken.balanceOf(msg.sender) >= 100 * 10**18, "Not enough GAME tokens");
    
    gameToken.burn(msg.sender, 100 * 10**18);
    
    uint256 requestId = vrfCoordinator.requestRandomWords(
        keyHash,
        subscriptionId,
        requestConfirmations,
        callbackGasLimit,
        1
    );
    
    vrfRequests[requestId] = tokenId;
```

**What's happening here?**

* Player burns 100 tokens to open loot box
* Requests truly random number from Chainlink VRF
* Maps the request ID to the token ID for later processing

```solidity
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
    uint256 tokenId = vrfRequests[requestId];
    uint256 randomValue = randomWords[0] % 100;
    
    // Loot rarity: 0-49 = common, 50-79 = rare, 80-94 = epic, 95-99 = legendary
    if (randomValue >= 95) {
        // Legendary loot
        uint256 currentStrength = traitFusion.getTraitAsUint(address(evolutionNFT), tokenId, "strength");
        traitFusion.setTraitUint(address(evolutionNFT), tokenId, "strength", currentStrength + 50);
        traitFusion.setTraitString(address(evolutionNFT), tokenId, "loot_tier", "legendary");
```

**What's happening here?**

* Chainlink calls this function with random number
* Converts random number to percentage (0-99)
* 5% chance for legendary loot (+50 strength)
* 15% chance for epic loot (+25 strength)
* 30% chance for rare loot (+10 strength)
* 50% chance for common loot (+5 strength)
