Розробка системи енергії/витривалості GameFi

Розробка системи енергії/витривалості GameFi Ми стикалися із завданням створення on-chain системи енергії, яка не спалює газ при регенерації. Звичайний підхід — оновлення storage щосекунди — вбиває економіку та робить гру неіграбельною. Наша реалізація використовує lazy evaluation, що дозволяє об

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1003

Розробка системи енергії/витривалості GameFi

Ми стикалися із завданням створення on-chain системи енергії, яка не спалює газ при регенерації. Звичайний підхід — оновлення storage щосекунди — вбиває економіку та робить гру неіграбельною. Наша реалізація використовує lazy evaluation, що дозволяє обчислювати поточну енергію без запису. За 5+ років досвіду ми виробили архітектуру, що балансує між gas economy та захистом від чітерів. У цій статті розберемо ключові механіки: time-based regen без write, прив'язку до NFT, tradeable energy та anti-cheat.

Система енергії — механіка обмеження ігрової активності. Гравець витрачає енергію на дії (битви, фармінг, крафт), енергія відновлюється з часом або через покупку. У Web2 це просто лічильник у базі даних. У Web3 це on-chain ресурс, що створює і можливості (tradeable енергія, verifiable regen), і проблеми (gas за кожне оновлення, cheating prevention). Правильна архітектура енергетичної системи — одна з ключових інженерних задач GameFi. Її неправильна реалізація або робить гру неіграбельною (занадто багато on-chain операцій), або відкриває експлойти (безкоштовна енергія через manipulation).

Архітектура lazy evaluation для економії газу

Інтуїтивне рішення: зберігати енергію в mapping, оновлювати щосекунди. Це погано — нескінченна кількість транзакцій. Правильний підхід: lazy evaluation. Зберігаємо не поточну енергію, а момент останньої зміни та значення в той момент. Поточна енергія обчислюється on-the-fly при кожному читанні:

contract EnergySystem { struct EnergyState { uint128 storedEnergy; uint64 lastUpdateTime; uint64 maxEnergy; } mapping(address => EnergyState) private energyStates; uint256 public constant REGEN_RATE = 1e18; uint256 public constant MAX_ENERGY = 100e18; function currentEnergy(address player) public view returns (uint256) { EnergyState storage state = energyStates[player]; uint256 elapsed = block.timestamp - state.lastUpdateTime; uint256 regenerated = elapsed * REGEN_RATE; uint256 total = uint256(state.storedEnergy) + regenerated; uint256 max = state.maxEnergy == 0 ? MAX_ENERGY : uint256(state.maxEnergy); return total > max ? max : total; } function _updateEnergyState(address player) internal { EnergyState storage state = energyStates[player]; state.storedEnergy = uint128(currentEnergy(player)); state.lastUpdateTime = uint64(block.timestamp); } function spendEnergy(address player, uint256 amount) internal { uint256 current = currentEnergy(player); require(current >= amount, "Insufficient energy"); _updateEnergyState(player); energyStates[player].storedEnergy -= uint128(amount); } function addEnergy(address player, uint256 amount) internal { _updateEnergyState(player); uint256 max = energyStates[player].maxEnergy == 0 ? MAX_ENERGY : energyStates[player].maxEnergy; uint256 newEnergy = uint256(energyStates[player].storedEnergy) + amount; energyStates[player].storedEnergy = uint128(newEnergy > max ? max : newEnergy); } } 

Ключовий момент: currentEnergy()view функція, не витрачає gas. Storage оновлюється лише при spendEnergy/addEnergy — тобто при реальній ігровій дії. Lazy evaluation знижує gas consumption у 10 разів порівняно з постійним оновленням storage. Згідно з документацією Solidity, packed structs економлять storage gas.

Параметр Lazy evaluation Постійне оновлення
Write operations 0 у фоні, лише при дії Щосекунди (мільйони TX)
Gas cost за дію ~50 000 gas ~100 000 gas + фонові
Складність імплементації Середня Низька
Підходить для High-traffic GameFi Прості симуляції

Як прив'язати енергію до NFT?

Енергія прив'язана до конкретного NFT, а не до EOA гаманця. Це важливо: гравець може мати кілька персонажів з незалежною енергією, торгувати персонажами разом з їхньою поточною енергією.

contract CharacterEnergySystem { struct CharacterEnergy { uint128 storedEnergy; uint64 lastUpdate; uint8 tier; } mapping(uint256 => CharacterEnergy) public characterEnergy; function regenRateForTier(uint8 tier) public pure returns (uint256) { if (tier == 3) return 3e18; if (tier == 2) return 2e18; return 1e18; } function maxEnergyForTier(uint8 tier) public pure returns (uint256) { return 100e18 + uint256(tier) * 50e18; } function currentEnergy(uint256 tokenId) public view returns (uint256) { CharacterEnergy storage ce = characterEnergy[tokenId]; uint8 tier = nftContract.getTier(tokenId); uint256 elapsed = block.timestamp - ce.lastUpdate; uint256 regen = elapsed * regenRateForTier(tier); uint256 total = uint256(ce.storedEnergy) + regen; uint256 max = maxEnergyForTier(tier); return total > max ? max : total; } } 

При трансфері NFT енергія переходить з персонажем автоматично, оскільки зберігається в маппінгу по tokenId.

Чому anti-cheat критичний?

Без захисту гравці можуть маніпулювати регенерацією через re-org або replay атак. Наше рішення використовує signed actions з nonce:

struct GameAction { uint256 characterId; uint256 actionType; uint256 energyCost; uint256 nonce; uint256 deadline; } mapping(address => uint256) public actionNonces; function executeAction( GameAction calldata action, bytes calldata serverSignature ) external { bytes32 digest = _hashTypedData(action); address signer = ECDSA.recover(digest, serverSignature); require(signer == GAME_SERVER_SIGNER, "Invalid signature"); require(action.nonce == actionNonces[msg.sender], "Invalid nonce"); actionNonces[msg.sender]++; require(block.timestamp <= action.deadline, "Expired"); spendEnergy(action.characterId, action.energyCost); _processAction(action); } 

Додатково вводимо cooldown модифікатор для частих дій:

mapping(uint256 => mapping(uint8 => uint256)) public lastActionTime; uint256 public constant BOSS_FIGHT_COOLDOWN = 4 hours; modifier withCooldown(uint256 charId, uint8 actionType, uint256 cooldown) { require( block.timestamp >= lastActionTime[charId][actionType] + cooldown, "Action on cooldown" ); _; lastActionTime[charId][actionType] = block.timestamp; } function fightBoss(uint256 charId) external withCooldown(charId, ACTION_BOSS, BOSS_FIGHT_COOLDOWN) { spendEnergy(charId, BOSS_FIGHT_ENERGY_COST); // ... } 

Які ризики виникають при використанні ERC-20 енергії?

Більш складна модель: окремий ERC-20 токен як енергія, яку можна купити/продати. Trade-off: гравці можуть купити енергію на DEX → pay-to-win ризик. Якщо це допустимо — ERC-20 енергія дає економічну цінність. Якщо ні — енергія має бути non-transferable (не токен, а internal accounting).

Економічна модель: sink та source

Енергетична система працює як регулятор економіки. Важливо балансувати sources та sinks. Рекомендовані параметри:

Параметр Рекомендації
Regen rate Заповнення з 0 до max за 8–12 годин
Max energy 1–3 ігрових сесії по 2–3 години
Premium refill Не більше 2–3 повних refill на день
Tier multiplier Max 2x–3x, не більше

Орієнтири за термінами та вартістю

Базова система (lazy regen, spend, cooldowns): 2–3 тижні. Повна система (tier-based regen, ERC-20 energy token, DEX інтеграція, anti-cheat signed actions, dashboard аналітики): 5–7 тижнів. Вартість розраховується індивідуально після аналізу вашої механіки.

Що входить у роботу

  • Аудит існуючої механіки
  • Проектування смарт-контрактів з урахуванням gas optimization
  • Розробка та unit-тести (Foundry з vm.warp)
  • Розгортання та верифікація контрактів
  • Інтеграція з ігровим бекендом (ethers.js, viem)
  • Документація API та приклади використання
  • Підтримка після релізу (1 місяць)
Приклад тесту регенерації в Foundry ```solidity function test_energyRegenOverTime() public { uint256 tokenId = 1; vm.prank(player); game.spendAllEnergy(tokenId); assertEq(energy.currentEnergy(tokenId), 0); vm.warp(block.timestamp + 50); assertEq(energy.currentEnergy(tokenId), 50e18); vm.warp(block.timestamp + 200); assertEq(energy.currentEnergy(tokenId), 100e18); } ```

Ми гарантуємо відсутність реентерабельності та використання перевірених патернів (OpenZeppelin). Наш досвід — 5+ років у Web3, 30+ реалізованих проєктів. Зв'яжіться з нами для консультації щодо вашої GameFi механіки. Замовте розробку системи енергії під ключ.