Долго размышлял, но всё таки взял себе игру Adventure Land — The Code MMORPG — игра, в которой, кроме всего прочего можно и нужно программировать поведение персонажа. Да ещё и не одного, а целых трёх боевых и одного торговца. А ведь игра появилась ещё где-то в 2017 году, вроде как…
Игра для программистов и как результат — я не мог пройти мимо неё.
В качестве языка программирования используется язык на основе JAVA. Что, в принципе, является и вариацией обучения программированию.
Из основных минусов — исключительно англофицированное сообщество и минимальная документация.
Из странных плюсов — возможность запуска клиента практически на любой технике (даже на вишенках). Так как клиент работает и в браузерах с поддержкой JAVA. Вот, например, в данный момент у меня запущен воин из STEAM библиотеки, а маг и хиллер из Google Chrome. Но тут же есть и минусы:
- При запуске из STEAM — клиент отжирает довольно не плохо ресурсы ПК
- При запуске из браузера — клиенты «тормозят», т.к. выделяет им ресурсы браузер из собственных соображений
Ещё один плюс, можно входить с разных устройств одновременно одним и тем же героем. Тогда все «новые» подключения становятся наблюдателями.
Первое впечатление — весьма положительное. И даже за пару ночей сумел сделать нечто похожее на автоматизированный фарм голды с ближних монстриков.
Естественно, команда из троих — воин, маг и хиллер. Всё в лучших традициях MMO RPG.
Относительно рабочий код прикладываю (в данный момент он и занимается фармом):
// true - будет атаковать // false - не будет воевать var attack_mode=true; var myOwner = character.owner; //": "5728172030558208", var TANK var DAMAGER var HEALER var myType function isType(character){ switch (character.type){ case "priest": mType = "Healer"; break; case "warrior": case "paladin": mType = "Tank"; break; case "merchant": // ??? mType = "Merch"; break; default: mType = "Damager"; break; } return mType; } //game_log(get_characters()); //game_log(get_active_characters()); setInterval(function(){ // ДЛЯ ВСЕХ ПЕРСОНАЖЕЙ - НАЧАЛО // перебор всех персонажей //show_json(get_characters()); let obj = get_characters(); for(key in obj){ //log(key); if(obj[key].online != 0){ tmp = isType(obj[key]); if (obj[key].name == character.name){ myType = tmp; } if (tmp == "Tank"){ TANK = obj[key].name; } if (tmp == "Damager"){ DAMAGER = obj[key].name; } if (tmp == "Healer"){ HEALER = obj[key].name; } //show_json(obj[key]); //log(obj[key].name + " is " + tmp); } } //log("My type: " + myType); // использовать зелья, когда нужно if(character.hp<character.max_hp/3 || character.mp<character.max_mp/3){ use_hp_or_mp(); //game_log(character.name + " use POTION..."); } // подобрать лут loot(); // ДЛЯ КАЖДОГО ТИПА switch (myType){ case "Tank": // принять party от хиллера x = get_party() if (!x[HEALER]){ log("NOT IN PARTY"); accept_party_request(HEALER) send_party_request(HEALER); // show_json(get_party()); } // выйти если не атакую или мёртв или двигается if(!attack_mode || character.rip || is_moving(character)) return; var target=get_targeted_monster(); if(!target) { target=get_nearest_monster({min_xp:100,max_att:120}); if(target){ change_target(target); //log(get_target()); } else { set_message("No Monsters"); return; } } if(!is_in_range(target)) // вне дистанции атаки { move( // сокращение дистанции на половину character.x+(target.x-character.x)/2, character.y+(target.y-character.y)/2 ); } else if(can_attack(target)) // могу атаковать? { set_message("Attacking"); attack(target); } break; case "Damager": // принять party от хиллера x = get_party() if (!x[HEALER]){ log("NOT IN PARTY"); //accept_party_request(HEALER); accept_party_request(HEALER) send_party_request(HEALER); // show_json(get_party()); } // выйти если не атакую или мёртв или двигается if(!attack_mode || character.rip || is_moving(character)) return; if(character.max_hp - character.hp > 200 || character.max_mp - character.mp > 300) use_hp_or_mp(); // Party leader var leader = get_player(TANK); // Current target and target of leader. var currentTarget = get_targeted_monster(); var leaderTarget = get_target_of(leader) // Change the target. if (!currentTarget || currentTarget != leaderTarget){ // Current target is empty or other than the leader's. change_target(leaderTarget); currentTarget = get_targeted_monster(); } // Attack the target. targetTarget = get_target_of(currentTarget) if(currentTarget && can_attack(currentTarget) && targetTarget == leader){ // Current target isn't empty and attackable. attack(currentTarget); } //Move to leader. if(!character.moving){ if(!is_in_range(leader)) // вне дистанции атаки { move( // сокращение дистанции на половину character.x+(leader.real_x-character.x)/2, character.y+( leader.real_y-character.y)/2 ); } } break; case "Healer": // проверить у напарников здоровье и вылечить их /* if (TANK){ targ = get_player(TANK) if(!targ.rip && targ.hp < targ.max_hp / 2){ heal(targ); }; }; if (DAMAGER){ targ = get_player(DAMAGER) if(!targ.rip && targ.hp < targ.max_hp / 2){ heal(targ); }; }; */ let ob = get_party(); for(key in ob){ //log(key); targ = get_player(key) hp = targ.hp mhp = targ.max_hp if (hp< mhp/2){ heal(targ); log("Heal: " + key + " " + hp + "/" + mhp) } } //Move to leader. // Party leader var leader = get_player(TANK); if(!character.moving){ if(!is_in_range(leader)) // вне дистанции атаки { move( // сокращение дистанции на половину character.x+(leader.real_x-character.x)/2, character.y+( leader.real_y-character.y)/2 ); } } // хиллер собирает команду let obj = get_party(); //log (obj); if( !obj[TANK] ) { log("==TANK====================") //log(obj[TANK]) send_party_request(TANK); accept_party_request(TANK) } if( !obj[DAMAGER] ) { log("==DAMAG===================") //log(obj[DAMAGER]) send_party_request(DAMAGER); accept_party_request(DAMAGER) } break; default: // Healer log("No logic for type: " + MyType); break; } },1000/4); // повторяем каждые 1/4 секунды. // событие после смерти function handle_death() { setTimeout(respawn,25000); return true; // This ensures you keep on farming, yet, to retain your XP, do enhance the logic for defense } // Learn Javascript: https://www.codecademy.com/learn/introduction-to-javascript // Write your own CODE: https://github.com/kaansoral/adventureland
Ну вот, как то такое моё первое знакомство с игрой.
Ссылочки:
Список функций — почти с описанием