Розробка гри Slots на блокчейні

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка гри Slots на блокчейні
Середній
~1-2 тижні
Часті запитання

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

Етапи блокчейн-розробки

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

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

Розробка блокчейн-гри Slots

Слоти (ігрові автомати) — найпопулярніша категорія казино-ігор. На блокчейні ключева задача: генерувати символи барабанів через верифіковану випадковість, забезпечити заявлений RTP (Return to Player) та запобігти маніпуляціям результатом ні зі сторони казино, ні зі сторони гравця.

Механіка та математика Слотів

Класичний слот: 5 барабанів × 3 рядки = 15 позицій. Кожен барабан має віртуальний стрип (наприклад, 64 позиції з різними символами). Випадкове число → позиція на стрипі → видимі символи. Виплата визначається комбінацією символів на paylines.

RTP 96% означає: з кожних $100 ставок гравці отримують $96 у довгостроковій перспективі. Це досягається через математично верифіковані таблиці виплат.

Реалізація Smart Contract

contract BlockchainSlots is VRFConsumerBaseV2Plus {
    // Віртуальні стрипи барабанів
    // Індекс = позиція на стрипі, значення = символ (0-8)
    uint8[64] public reel1Strip;
    uint8[64] public reel2Strip;
    uint8[64] public reel3Strip;
    uint8[64] public reel4Strip;
    uint8[64] public reel5Strip;
    
    // Pay table: комбінація символів -> множник (в basis points)
    mapping(bytes32 => uint256) public payTable;
    
    struct SpinRequest {
        address player;
        uint256 betAmount;
        uint256 lines; // кількість активних paylines
    }
    
    mapping(uint256 => SpinRequest) public pendingSpins;
    
    function spin(uint256 lines) external payable returns (uint256 requestId) {
        require(lines >= 1 && lines <= 20, "Invalid lines");
        require(msg.value >= MIN_BET * lines, "Insufficient bet");
        
        requestId = _requestRandomWords(3); // 3 випадкові числа
        
        pendingSpins[requestId] = SpinRequest({
            player: msg.sender,
            betAmount: msg.value,
            lines: lines,
        });
    }
    
    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
        SpinRequest memory spinReq = pendingSpins[requestId];
        delete pendingSpins[requestId];
        
        // Визначаємо позиції барабанів з випадкового числа
        uint8[5] memory reelPositions;
        reelPositions[0] = uint8(randomWords[0] % 64);
        reelPositions[1] = uint8((randomWords[0] >> 8) % 64);
        reelPositions[2] = uint8((randomWords[0] >> 16) % 64);
        reelPositions[3] = uint8(randomWords[1] % 64);
        reelPositions[4] = uint8((randomWords[1] >> 8) % 64);
        
        // Отримуємо символи для 3 рядків кожного барабана
        uint8[5][3] memory grid = _buildGrid(reelPositions);
        
        // Обчислюємо виплату за всіма активними paylines
        uint256 totalPayout = _calculatePayout(grid, spinReq.betAmount, spinReq.lines);
        
        if (totalPayout > 0) {
            payable(spinReq.player).transfer(totalPayout);
        }
        
        emit SpinResult(spinReq.player, reelPositions, grid, totalPayout, requestId);
    }
    
    function _buildGrid(uint8[5] memory positions) internal view returns (uint8[5][3] memory grid) {
        // Для кожного барабана беремо 3 послідовних символи (wrap-around)
        for (uint i = 0; i < 5; i++) {
            uint8 pos = positions[i];
            grid[i][0] = _getSymbol(i, (pos + 63) % 64);  // рядок вище
            grid[i][1] = _getSymbol(i, pos);               // середній рядок
            grid[i][2] = _getSymbol(i, (pos + 1) % 64);   // рядок нижче
        }
    }
    
    function _calculatePayout(
        uint8[5][3] memory grid,
        uint256 betAmount,
        uint256 activeLines
    ) internal view returns (uint256 payout) {
        uint256 betPerLine = betAmount / activeLines;
        
        // Перевіряємо кожну payline
        for (uint l = 0; l < activeLines; l++) {
            uint8[5] memory line = _getPayline(l, grid);
            uint256 lineMultiplier = _getLineMultiplier(line);
            
            if (lineMultiplier > 0) {
                payout += (betPerLine * lineMultiplier) / 100;
            }
        }
    }
}

Бонусні функції

Слоти без бонусних механік неконкурентоспроможні. Обов'язкові функції:

Free Spins: scatter символи (зазвичай 3+) запускають серію безкоштовних спінів з підвищеним множником.

Wild символи: замінюють будь-який інший символ для формування виграшної комбінації.

Multiplier Wilds: wild з ×2, ×3 множником.

Expanding Wilds: розширюються на весь барабан при приземленні.

Bonus game: спеціальна мініігра з механікою вибору (виберіть з N скриньок).

function _checkBonusFeatures(uint8[5][3] memory grid) internal pure 
    returns (bool hasFreeSpin, uint256 freeSpinCount, bool hasBonusGame) 
{
    uint256 scatterCount = 0;
    for (uint col = 0; col < 5; col++) {
        for (uint row = 0; row < 3; row++) {
            if (grid[col][row] == SCATTER_SYMBOL) scatterCount++;
        }
    }
    
    if (scatterCount >= 3) {
        hasFreeSpin = true;
        freeSpinCount = scatterCount == 3 ? 10 : scatterCount == 4 ? 15 : 20;
    }
    
    // Bonus game на 3+ бонусних символах на payline 1
    hasBonusGame = _checkBonusLine(grid);
}

Офлайн-анімації, On-chain результат

Блокчейн-слоти звичайно працюють так: результат (позиції барабанів) надходить від VRF, анімація обертання барабанів — офлайн у браузері/додатку. Користувач бачить обертання, потім остаточні символи відповідають on-chain результату. Інтеграція через подію смарт-контракту.

Затримка VRF (3-15 секунд) — проблема для UX. Розв'язання: оптимістична анімація (показуємо «обертання» поки чекаємо VRF), L2 деплой (Chainlink VRF дешевше та швидше на Arbitrum/Polygon), commit-reveal (швидше, але менш верифіковано).

Розробка повних Слотів (5 барабанів, 20 ліній, Free Spins, Wild) — 4-6 тижнів смарт-контракт + 4-8 тижнів фронтенд з анімаціями (Pixi.js/Three.js). Інтеграція Chainlink VRF включена в частину смарт-контракту.