CryptoBotWars или как да изградим демони и защо

Защо лайна? Защото харесвам самообезчестяването и играта не е близо до производството.

Токени, роботи, платежни канали и потоци на живо

Така че изградих CryptoBotWars, игра в Raiden Network.

Искате ли да го играете? Прочетете на ...

Вземете подъл поглед към играта, зад кулисите или проба на живо. И се присъединете към нашия Riot чат!

Защо? ... имах някои въпроси:

  1. Лесно ли е да се изгради нещо на върха на Raiden в момента? Липсва ли ни нещо, което е доста лесно да се промени?
  2. Как би работил Raiden в момента за плащания „много към много“ и „много към един“, случаи, често свързани с бизнеса
  3. Биха ли намерили бъгове в Raiden? Най-добрите тестери са безсмислените, наскоро вградени тестери.
  4. Дали Raiden ще се държи добре с висока пропускателна способност?
  5. Били ли са успешно опосредствани плащанията (различни места и настройки на системата)

Една игра, особено комбинирана с известна степен на забавление, има потенциал да стимулира нови хора да изпробват Raiden. Още повече, ако добавите малко награди отгоре.

Игра… или много сериозна услуга, която би приела плащания извън веригата , но нямах достатъчно време за последното, така че отидете:

Тъмно Вейдър и Синя Йода. Купа за супи и шапка за пинг-понг Santa Santa! Изглежда страхотно! … От 4м.

Този блогпост е частично посветен на тайландския ресторант, където получавам любимата си берлинска супа от кокосово-тофу-зеленчуци . Ето защо винаги разполагаме с куп купички за въртене, за да направим каски Vader & Santa Hats ats.

Как се роди идеята?

Един ден по време на обяда обсъждахме идеи за семинара на Devcon4 Raiden Network, опитвайки се да измислим забавно и просто приложение, което може да бъде изградено на върха на Raiden. По някакъв начин стигнахме до извода, че една игра може да стимулира повече хора да я изпробват.

Помислих малко повече след това и реших, че игра с неограничен брой потребители може да покаже Raiden по-добре, тъй като би тествала пропускателната способност.

Но какви игри можете да играете между безкраен брой играчи? Може би нещо, което изисква гласуване за резултат.

Спомних си модела на Дилема на затворника, при който двама играчи се опитват да намалят загубите си, без да могат да общуват един с друг, но не можаха да намерят подходящ вариант за играта по моя цел.

След това се върнах при чертожната дъска: гласувах за резултат.

Тогава разбрах, че най-простото нещо, което можете да направите, е ножица за рок хартия. Двама играчи, три хода, всеки потребител избира играч и ход, а мнозинството на играч решава последния ход. Тогава действителната игра може да се играе между двата хода, избрани от мнозинството.

В крайна сметка екипът показа забавно състезание между Дева и някои известни хора в космоса, съчетавайки встъпителната работилница с подходящи за Devcon меми и някои вълнения .

Но все пак исках да създам моята демонстрация на ножици за рок-хартия и ETHSingapore изглеждаше като подходящ момент да го направя! (Dark Vader и Blue Yoda посетиха Сингапур, но те не бяха включени в демонстрацията поради други различни технически проблеми, които трябваше да реша )

Роботите искат крипто

Имате игра, имате Raiden, защо да добавите друга променлива към уравнението?

И роботите причиняват много болка и аз не говоря за Рока Апокалипсис. Макар че виждате, вече известно време се подготвям да бъда един от толерантните хора: uRaiden Devcon3 Robo, Drones също искат криптовалута

  1. Аз и моят партньор, които всъщност изградихме Devcon3 RC Car, наистина харесваме роботи. И той вече е донесъл армия от тях в къщата ... това е дивата робобоста за хората, които не искат да растат.
  2. Роботите са забавни и сладки ( срещу мем дуел сега!)
  3. Пуснах гласа си на Йода да работи! (началото на поредната кариера ..)
  4. Но всъщност роботите ни дават представа какво може да бъде бъдещето .

Как започнах да строя?

~ 5,5 дни бяха достатъчни, за да направим първоначалните настройки за връзки и прототип на робот за ETHSingapore.

Тогава по време на зимната ваканция изградих настоящата игра на върха на първия прототип.

Първи неща първо: Тестване на робот SDK

Моят партньор вече знаеше, че Wonder Robots имат Python SDK и са тествали някои от командите. Това беше добър момент да запознаем Клавдиу, наш приятел в програмирането - какво може да бъде по-забавно от програмирането на роботи ?? Така го направи! Той добави команди за поведението победа / загуба, заедно с персонални саундтраци.

Игра поток

Вече бях написал някои идеи как може да изглежда играта. Така че, вместо всъщност да създам логическите диаграми на играта в този момент, преминах към фазата на внедряване. Това се оказа лош ход, защото „ми помогна“ да взема някои грешни решения поради това, че не видях цялата картина (състояния на рефакторирани игри и потребителски интерфейс, грешна логика на сървъра за игра при изчисляване на резултата, тази експлоатационна грешка.

В крайна сметка поправих нещата по-късно и създадох по-добра логическа последователност:

Крайни компоненти

  1. Dark Vader RobotServer & Blue Yoda RobotServer
  2. GameGuardianServer
  3. GameGuardianRaidenNode
  4. GameClient
  5. Предаване на живо по Twitch

2, 3, 4 са хоствани на VPS Digital Ocean VPS.

Роботните сървъри са хоствани на два домашни компютъра.

Един от тези компютри прави и поточното предаване на живо през уеб камерата. Опитахме много опции за поточно предаване на живо - от най-популярните до самостоятелно хоствани, дори гледахме децентрализирани решения, но всички те имаха недостатъци (латентност, разделителна способност, динамичен идентификатор на потока, отнема време за настройка и т.н.)

Потребителски интерфейс на GameClient

Всъщност първо започнах с потребителския интерфейс.

Моят партньор предложи да използвам същия плъзгач, който вече имах в Pipeline и да покажа всяко състояние на играта на индивидуален слайд. Мислех, че това е чудесна идея. Усещаше се като книга с истории.

експортиране const GameState = {
    null: 0, // Няма текуща игра
    отворен: 1, // По време на играта потребителите могат да правят движения
    затворен: 2, // По време на резолюцията на играта потребителите чакат резултати и плащания
    разрешено: 3, // Играта и разделителната способност приключиха.
}

Можете да видите кода на изгледите за състоянието на играта тук.

GameGuardianServer

След като имах представа за състоянията на играта, пристъпих към дефиниране на моделите за игра и преместване, които съответстват на колекциите от база данни MongoDB. Вижте текущата версия тук.

След това добавих GameGuardian Raiden API и внедрих логиката на резултатите от играта, за да изчисля победителите, да изпратя плащания извън веригата и да задействам движенията на робота. Задейства се от кода? направете PR, за да го подобрите!

move = изчакайте moveController.find ({където: {gameId: id}, order: ["_id ASC"]});
raidenPayments = изчакайте това.getRaidenPayments (TOKEN)
move.forEach (sentMove => {
    ако (
        sentMove.amount &&
        sentMove.move &&
        sentMove.amount> = game.move_amount
    ) {
        raidenPayment = raidenPayments [0] .find ((плащане) => {
            връщане pay.identifier === изпратенMove.paymentIdentifier;
        });
        ако (raidenPayment) {
            total_amount + = sentMove.amount;
            move_count [sentMove.playerId] [sentMove.move] + = 1;
            validMoves.push (sentMove);
        }
    }
});

sorted_moves_1 = Object.entries (move_count ['1']). sort ((a: произволен, b: произволен) => {return a [1] - b [1]});
sorted_moves_2 = Object.entries (move_count ['2']). sort ((a: произволен, b: произволен) => {return a [1] - b [1]});
move1 = sorted_moves_1 [2] [1]> 0? sorted_moves_1 [2] [0]: нула;
move2 = sorted_moves_2 [2] [1]> 0? sorted_moves_2 [2] [0]: RockPaperScissorsGetLoser [ход1];
// Ако имаме един играч, уверете се, че той печели
ако (! ход1) {
    ход1 = RockPaperScissorsGetLoser [ход2];
}
winMove = RockPaperScissorsGetLoser [ход1] === ход2? ход1: ход2;
validMoves.forEach ((ход) => {
    // Ние награждаваме и двамата играчи, ако техните финални ходове са еднакви
    ако (move.move === winMove) {
        winningMoves.push (ход);
    }
});
guardian_amount = total_amount / 10;
total_amount - = guardian_amount;
winner_amount = total_amount / winnerMoves.length;
gameUpdate = {
        winningMove,
        player1:  {
            брой: sorted_moves_1 [0] [1] + sorted_moves_1 [1] [1] + sorted_moves_1 [2] [1],
            ход: ход1,
            move_count: move_count ['1'],
        }
        player2:  {
            брой: sorted_moves_2 [0] [1] + sorted_moves_2 [1] [1] + sorted_moves_2 [2] [1],
            ход: ход2,
            move_count: move_count ['2'],
        }
        сума: победител-сума,
        iznosGuardian: guardian_amount,
        играчи: move.length,
};

this.updateById (id, gameUpdate);
// Извършване на Raiden плащания към победителите
winMoves.forEach ((ход) => {
    this.sendRaidenPayment (
        ЛЕКСЕМА,
        move.userAddress,
        winner_amount,
        move.paymentIdentifier
    );
});
this.sendRobotCommands (move1, move2, winMove);

Управление на времето: ключът към успеха

Или болката от прилагането на таймери в страната на клиента, които трябва да съответстват на сървъра.

Играта е присвоена и състоянията на играта също са присвоени. Тъй като избрах да имам безкраен брой едновременни потребители, трябваше да огранича поддръжката само до една игра в даден момент, за да поддържам лесното развитие.

И така, кой започва играта?

Настройването на работа със сървърен крон или подобно за създаване на игри редовно изглеждаше най-лошият подход, тъй като би попълнил базата данни по безполезен начин.

Избрах клиент задейства нов старт на играта. Накратко, ако няма текуща игра, която се изпълнява, тогава такава се създава от клиента. Ако има, данните за играта се изпращат на клиента.

Данните за играта съдържат също така startTime на играта, заедно с gameTime (колко време ще продължи отвореното състояние) и resolutionTime (колко дълго ще продължи резолюцията). Клиентът използва тези стойности, за да зададе таймерите тук и тук.

Таймерите се използват за задействане на някои от заявките към GameGuardianServer. Например, когато състоянието GameOpen приключи, GameClient изпраща суровите данни за движение. Или когато се достигне състоянието GameRessol, на сървъра се изпраща заявка за разрешаване на състоянието на играта или връщане на състоянието на разрешаване, ако тя вече е била разрешена, задействайки GameGuardianServer за изчисляване на победителите, изпращане на извън верижните плащания и задействане на движенията на робота ,

Роботи - финални щрихи

Роботните сървъри са хоствани на два домашни компютъра. Защо две? Тъй като и двамата робот Dash & Cue използват Bluetooth за свързване с компютъра. Настоящият SDK първо изключва всички свързани устройства и след това свързва подходящия робот.

Всеки робот има множество маршрути за: свързване с робота, задаване на външния вид, преместване на речеви команди, команди за победа / загуба. Избрах да използвам Gunicorn, защото трябва да поддържаме процеса на свързване жив във всички команди.

Обърнете внимание, че ние от време на време предаваме на живо роботите и това е превърнало дома ни в странно мимо студио.

Интернет връзката и домашния рутер не са улеснили работата.

Заключения

Разпали ли интереса ви? Изпробвайте играта: https://cryptoplayer.one

Разговаряйте с нас, за да дадете обратна връзка или да помолите за помощ при настройването на вашите Raiden канали или да ни ping да събудим роботите! Бунт чат

Част 2 идва скоро с още изводи и трикове с роботи ... но трябва да видя тук някои хлопки!

Прочетете: CryptoBotWars - Част 2: Заключения