Раньше меня тоже вела дорога приключений. Так, когда-то давно я был разработчиком игры про динозавров. Пожалуй, первой на территории РФ и до сих пор не получившей полноценного, завершённого аналога, ввиду чего наша команда недавно приступила к разработке второй части. Речь, конечно, о многострадальной Cretaceous Runner, которая во время разработки была порезана и переделана. Некоторый функционал был возвращён в патчах, но об этом позже.
Автор сообщества Фанерозой: инженер, главный разработчик игры Cretaceous Runner, Макар Дромкин. Редактор: руководитель сообщества Фанерозой, Ефимов Самир
▍ История
В детстве, наверное, многие из нас любили динозавриков, ведь мультики, сериалы и фильмы, а также различные игрушки, раскраски и первые детские энциклопедии, посвящённые этим величественным животным успешно выполняли роль купидонов. Ведь, согласитесь, трудно было не восхититься рычащим аллозавром из прогулок с динозаврами, или тирексом из первого парка. Даже сейчас, будучи взрослыми, мы всё равно не всегда можем пройти мимо «ужасных ящеров». Об этом свидетельствуют, например, наши статьи, которые читатели с восторгом встречают. Однако, если мы окунёмся в прошлое, в наше детство и юность, чтобы обнаружить хорошие игры про динозавров, то много ли интересных примеров мы с вами найдём?
Конечно, компьютерные игры с участием динозавров стали покорять рынок ещё с 90х годов (например, потрясающая игра с доктором Грантом на сеге), но почти все из них были либо шутерами, либо просто файтингами с участием динозавров.
▍ А как же полноценные игры, где можно прожить жизнь в шкуре динозавра, где повествуется какая-нибудь сюжетная история?
На самом деле таких полноценных игр в то время не было. Да и сейчас, если подумать, таковых, вышедших из стадии беты нет, а те, что имеются, в основном мультиплеерные игры, которые, по сути, не привносят ничего нового. И если честно, мне с детства не хватало игр про жизнь динозавров с сюжетом. Именно поэтому уже в более сознательном возрасте, я подумал: а почему бы мне не сделать игру самому со своей Пангеей и динозаврами?
Так, в 2007 году я стал пробовать играться с разными 3D программами по моделированию и немного освоившись в 3D-MAX примерно к 2010 году, я сделал свою первую, пусть и кривую модельку дромеозавра. Примерно в это же время я стал искать подходящий для моих целей движок. Поскольку я был «наивен и глуп», мечтая быстро налепить кучу моделей и освоить всякие сложные движки, то после многочисленных неудачных попыток, я быстро пришёл к выводу, что начинать нужно с малого, тем более помощи инди-разработчику ждать было неоткуда. Это связано с тем, что в то время российский геймдев был относительно небольшим. Он тогда, конечно, существовал, но больше в зачаточном состоянии.
Кидаться на рожон я всё же не хотел, и поэтому, помимо своих моделек, я нашёл модельки других динозавров из старых игр и поставил относительно осуществимую цель в создании игры без лишних сложностей: каких-либо автомобилей, оружия и прочего… Просто игра про динозавров на относительно простом движке. Да и выбирать в те годы ещё мало, из чего можно было. Если сейчас существует тонна утилит для Unity или UE, то тогда приходилось пользоваться глючными камовскими скриптами, самодельными утилитами и программами для движка RenderWare. Собственно, с последним движком я и решил работать и делать для него свою карту.
▍ Но прежде чем начинать рассказывать всю драму событий, давайте расставим все точки над «Ё» и опишем, чем же является этот проект?
Итак, за мою попытку оправдаться, вероятно в меня могут полететь тапки, но всё же я не думаю, что для кого-то будет секретом то, что раньше применялась практика делать игру на базе другой. На примере тех же GTA – в San Andreas можно найти остатки от Vice City, а то, что VCS (Vice City Stories) сделана на основе VC, итак, понятно. То же самое касается LCS и GTA3.
Поэтому да, технически Cretaceous Runner распространяется как игра, разработанная на базе Gta San Andreas, а, стало быть, она не затрагивает оригинальную SA при её наличии. Но с правовой точки зрения, разумеется, это лишь глобальная модификация. Конечно, кто-то может возразить, что глобальная модификация сейчас вне закона, ибо в последнее время одна большая акула стала пожирать разработчиков и их творения, но в моей игре она добычи, видимо, не увидела. Может быть потому, что по качеству моя игра не уступала последнему великолепному переизданию GTA. Это шутка, конечно, но если взглянуть в прошлое, то в моём создании багов было много, которые правда постепенно устранялись. К слову, мой проект коммерческим так и не был, всё делалось чисто по фану, в попытках заполнить пустующую нишу.
Движок тоже был очень ограничен по функционалу, поэтому была использована смекалка, множество интересных костылей и технических решений, о которых я сегодня вам и расскажу. Разумеется, я не настолько псих, чтобы писать всё на CLEO или DYOM, да и хоть немного уважать потребителя ведь надо, поэтому написано всё было чисто на мэине. Да, это сложнее, да, по встроенной инструкции, да на языке из смеси бейсика и си (язык у движка свой и на хабре такого нет, поэтому цвет кода будет отличаться от оригинала), при этом параллельно изучая опкоды и уже существующий код. Зато, хотя бы, оно работало. Чего только стоит «котопес» из самолётов, пилота и с нуля написанных анимаций на движке! При этом сам же «котопес» был превращен в птерозавра вполне себе неплохо выглядящего.
Итак, немного о том, как я реализовывал геймплей.
▍ Полёты
Вручную была написана тысяча страниц кода, и один из интересных костылей – полёт на птерозавре. Делалась механика с оглядкой на игру Turok:Evolution, и её приблизительно удалось повторить. Основано конечно всё, на невидимом самолёте с пилотом, заменённым на птерозавра с приклеенным к нему Скилларом – главным героем– дромеозавром. Немного визуальных эффектов, опять же вручную написанной анимации и кода – и всё работает. Прошу простить, что я не вставляю всю тысячу страниц написанного мной кода, но мне кажется в качестве примера можно показать и небольшой кусок проделанной мной работы.
:MISSION44_1407
wait 0
if
01F3: car $PTERO1 in_air
else_jump @MISSION44_3031
wait 0
if
82BF: not car $PTERO1 sunk
else_jump @MISSION44_2938
wait 0
if and
80EC: not actor $PLAYER_ACTOR sphere 0 near_point -1999.781 -2134.288 radius 10.0 10.0
844B: not actor $PLAYER_ACTOR on_foot
else_jump @MISSION44_1625
wait 0
if
-8.0 > $ZZ1
else_jump @MISSION44_1571
wait 00605: actor $PLAYER_ACTOR perform_animation "BARSERVE_IN" IFP "BAR" framedelta 4.0 loop 0 lockX 0 lockY 90 lockF 0 time 60000000
jump @MISSION44_1229
:MISSION44_1571
wait 0
0605: actor $PLAYER_ACTOR perform_animation "BARSERVE_LOOP" IFP "BAR" framedelta 4.0 loop 0 lockX 0 lockY 90 lockF 0 time 60000000
jump @MISSION44_1229
В миссии «Возвращение зла» из-за горящих сроков я так и не успел сделать полноценное приземление после полёта по каньону, однако оно было задействовано в мини-миссии полётов в свободном режиме. Если замедлить скорость и спуститься к земле, то модель персонажа заменяется на обычного дромеозавра и оставляется на поверхности, а на несколько секунд в воздухе появляется уже другой персонаж-птерозавр, улетающий прочь. Подмена даже получилась почти незаметной. При этом подмена происходит не из воздуха. Т.е. пока продолжается полёт, нужный персонаж ждёт своего часа на горе. Как говорится костыли творят иллюзию, а видео ниже заставляет её лицезреть!
В самой сложной миссии с полётами «Царь горы» был вообще использован запрещённый инструкцией опкод полёта вокруг точки. Возможно, именно это сказалось на поимке врага, которая зависит в полёте на прямой от кадров в секунду. Если FPS сильно завысить, то он догоняется гораздо легче.
Микрораптор же получил механику от самолётика RC Baron, которого заставили махать крыльями, а птерозавры, атакующие его в «Иноземье», просто читают его координаты и летят туда же с небольшой задержкой, чтобы была возможность увернуться.
Конечно, каждый летающий зверь защищён от взрывов и повреждений, чтобы ни у кого случайно не бомбануло. Но, каков итог! Это вам не простой реплейсер, а потому нужны настоящие животины! Кстати, в видео выше вы видели прыжок с башни, что в миссии в Торонто. Там Скиллар цепляется за кусок обшивки и планирует на ней вниз. Дело в том, что город сделан в качестве интерьера высоко в небе, выше самолётного потолка, наподобие Либерти-Сити в SA. А когда самолёт выше потолка, он летит просто вниз до тех пор, пока не вернётся в своё воздушное пространство. Таким образом и получилось сделать плавное планирование с башни без возможности активного полёта. Ниже представлен код реализации.
00BC: show_text_highpriority GXT 'MIS_681' time 5000 flag 1 // Use piece of sheating to plan back to airport!
wait 4500
fade 0 1000
wait 1000
Model.Load(#RCBARON)
Model.Load(#TORONCITY22)
038B: load_requested_models
:MISSION40_7594
wait 0
if and
Model.Available(#RCBARON)
Model.Available(#TORONCITY22)
else_jump @MISSION40_7594
fade 1 2000
02A3: enable_widescreen 0
$WIDE = 0
Player.CanMove($PLAYER_CHAR) = True
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
$MICRO1 = Car.Create(#RCBARON, -2330.825, -158.238, 4300.9)
Car.Angle($MICRO1) = 180.0
$FLYTHING = Object.Create(#TORONCITY22, -2330.825, -154.238, 4310.9)
Object.Angle($FLYTHING) = 180.0
0681: attach_object $FLYTHING to_car $MICRO1 with_offset 0.0 0.0 -0.27 rotation 0.0 0.0 90.0
03F5: set_car $MICRO1 apply_damage_rules 0
036A: put_actor $PLAYER_ACTOR in_car $MICRO1
084E: flying_vehicle $MICRO1 use_primary_gun 1
0841: flying_vehicle $MICRO1 use_secondary_gun 1
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 0
0605: actor $PLAYER_ACTOR perform_animation "BARCUSTOM_GET" IFP "BAR" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 0 time 60000000
wait 100
Car.PutAt($MICRO1, -2330.831, -158.532, 4300.9)
Car.SetSpeedInstantly($MICRO1, 30.0)
018A: $CHECK1_1 = create_checkpoint_at -2323.499 -465.0377 4064.577
06D5: $CHECK1_2 = create_racing_checkpoint_at -2323.499 -465.0377 4064.577 point_to -2330.825 -155.238 4300.9 type 3 radius 15.0
▍ Бег
В самой первой версии было очень много неспешной ходьбы. Но не стоит забывать, что игра с задержкой вышла весной 2013 года, когда никто вообще ничего подобного предложить не мог. Все эти ислы и прочие бермуды были анонсированы либо позже, либо сильно позже. А в те годы все сходили с ума по самой идее – тут же можно играть за динозавра! Да ещё и пернатого! Ничего себе, у нас есть родители, и надо за ними идти!
На самом деле тут сыграла роль ещё и техническая составляющая. Ну не существует опкода просто бежать к точке. Только идти. В пропатченной версии неспешная ходьба уже была заменена на бег, но пришлось идти опять на ухищрения. Когда кто-то из персонажей куда-то бежит, он бежит к рыбе, спрятанной под землей. Из-за этого во второй миссии появился баг, когда наши родители внезапно идут к реке топиться. Рыбы там оказалось слишком много, родители пихаются между рыб, пытаются подойти поближе к нужной, в итоге багуют и просто уходят куда глаза глядят, а миссия зависает. Давайте же глянем на реализацию в виде частички кода:
00BC: show_text_highpriority GXT 'MISS_18' time 6000 flag 1 // Now you need some food. Follow your parents all the way to the lake.
wait 5400
02A3: enable_widescreen 0
$WIDE = 0
Player.CanMove($PLAYER_CHAR) = True
wait 0
$FISH1 = Object.Create(#DRUG_BLUE, -933.8073, -806.0117, 9.445)
Object.Angle($FISH1) = 0.0
062F: $GROUP1_1 = create_group_type 0
06F0: set_group $GROUP1_1 distance_limit_to 3000.0
0630: put_actor $MOTHER in_group $GROUP1_1 as_leader
0631: put_actor $FATHER in_group $GROUP1_1
0631: put_actor $BRO1 in_group $GROUP1_1
0631: put_actor $BRO2 in_group $GROUP1_1
0631: put_actor $BRO3 in_group $GROUP1_1
06E2: AS_actor $MOTHER run_to_object $FISH1 timelimit -1 stop_within_radius 4.0
wait 0
$MMAR = Marker.CreateAboveActor($MOTHER)
Marker.SetColor($MMAR, 1)
$FMAR = Marker.CreateAboveActor($FATHER)
Marker.SetColor($FMAR, 1)
▍ Взрывы
Очередной багоюз – это анкилозавр. Как бы понатуральнее сделать его атаку хвостом? Анимация – это полбеды, надо еще, чтобы герой получал большое количество урона, при этом крича от боли. Был задействован неиспользуемый невидимый беззвучный взрыв – анкилозавр получил защиту от взрыва, и во время удара хвостом на его месте появляется импровизированный взрыв, наносящий урон.
▍ Стелс
Была полностью написана миссия с простым, но стелсом. Там лишь удалось сделать «чистые» зоны, по которым можно пройти незамеченным, при этом только ползком. Если подняться, то даётся примерно 2 секунды, пока троодоны нас не заметят. К сожалению, эта миссия хоть и была готова, но появилась только в бета-доступе версии 1.3. К тому же, миссию можно пройти тремя способами – полным стелсом пробраться до вожака троодонов и также незаметно убраться, пробраться до него и просто убежать, спалившись, или же пойти сразу напролом через тучу троодонов, попытавшись догнать и убить вожака. Так или иначе, стелс работал, хоть и был максимально прост и уныл.
▍ Танцы
Миссия с брачным танцем была написана с нуля лишь с помощью своих идей и возможностей. Скрипт из SA весь состоит из переменных, просто взять и выдернуть его невозможно. Поэтому опять достаём костыли и пишем. Используется прорисовка текстур и их движение по экрану. При ошибках выполнения танца стрелки немного съезжают и иногда даже наплывают друг на друга, но миссия, в целом, осталась проходимой даже без особых сложностей. Она стала так же самой крупной по размеру занимаемого кода, так как действие каждой из стрелок было прописано вручную. Всё получилось, кстати, абсолютно рабочим, ничего не зависит от количества кадров в секунду или разрешения экрана. Ниже приведён код начала миссии, а также механика первой из стрелок.
01E3: show_text_1number_styled GXT 'MIS_750' number 0 time 5000 style 1 // ~b~Mating dance
wait 6000
02A3: enable_widescreen 0
$WIDE = 0
00BC: show_text_highpriority GXT 'MIS_751' time 4200 flag 1 // Use arrow keys to perform the dance.
wait 4500
00BC: show_text_highpriority GXT 'MIS_752' time 5200 flag 1 // Press the desired button when the arrow will be in the circle.
wait 5500
00BC: show_text_highpriority GXT 'MIS_753' time 4500 flag 1 // Score 1500 points to impress the female.
03C4: set_status_text $DANCE_SCORE type 0 GXT 'DNC_001' // global_variable // Score:
0605: actor $PLAYER_ACTOR perform_animation "DAN_LOOP_A" IFP "DANCING" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 0 time 120000
wait 5000
0390: load_txd_dictionary 'LD_TATT'
038F: load_texture "UP" as 7 // Load dictionary with 0390 first
038F: load_texture "DOWN" as 8 // Load dictionary with 0390 first
038F: load_texture "RIGHT" as 9 // Load dictionary with 0390 first
038F: load_texture "LEFT" as 10 // Load dictionary with 0390 first
038F: load_texture "CIRCLE" as 6 // Load dictionary with 0390 first
03E3: set_texture_to_be_drawn_antialiased 1
$DANCE_SCORE = 0
$UP = 304477
$DOWN = 304478
$RIGHT = 304479
$LEFT = 304478
$TEXT = 380.0
$TEXT_1 = 550.0
$TEXT_2 = 650.0
$TEXT_3 = 750.0
$TEXT_4 = 850.0
$TEXT_5 = 700.0
$TEXT_6 = 700.0
$TEXT_7 = 700.0
:MISSION37_1_607
wait 0
038D: draw_texture 6 position 310.0 380.0 size 60.0 60.0 RGBA 255 255 255 255
038D: draw_texture 7 position $TEXT_1 $TEXT size 40.0 40.0 RGBA 255 255 255 255
038D: draw_texture 8 position $TEXT_2 $TEXT size 40.0 40.0 RGBA 255 255 255 255
038D: draw_texture 9 position $TEXT_3 $TEXT size 40.0 40.0 RGBA 255 255 255 255
038D: draw_texture 10 position $TEXT_4 $TEXT size 40.0 40.0 RGBA 255 255 255 255
$TEXT_1 -= 3.0
$TEXT_2 -= 3.0
$TEXT_3 -= 3.0
$TEXT_4 -= 3.0
if
330.0 > $TEXT_1
else_jump @MISSION37_1_607
if and
not &0($DOWN,1i) == 255
not &0($RIGHT,1i) == 255
not &0($LEFT,1i) == 16711680
$TEXT_1 > 300.0
else_jump @MISSION37_1_1018
if and
320.0 > $TEXT_1
&0($UP,1i) == 16711680
else_jump @MISSION37_1_607
038D: draw_texture 7 position $TEXT_1 $TEXT size 40.0 40.0 RGBA 0 170 0 255
0605: actor $PLAYER_ACTOR perform_animation "DAN_LEFT_A" IFP "DANCING" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 0 time 120000
$DANCE_SCORE += 25
jump @MISSION37_1_1057
:MISSION37_1_1018
038D: draw_texture 7 position $TEXT_1 $TEXT size 40.0 40.0 RGBA 220 0 0 255
jump @MISSION37_1_1057
end_thread
▍ Музыка
Интересный момент также с саундтреком. Когда игра была пропатчена, в неё добавили то, чего так хотелось изначально – саундтрек. Как известно, в GTA серии 3D саундтрека не существует, кроме того, что играет на радио в машинах. На самом деле есть, насколько помню, целых два саундтрека выполненной миссии и ещё несколько для других целей – для танцев лоурайдеров, например. Но зато у нас есть аудиозоны – это шум холодильников в магазинах, фоновые шумы в брокерской конторе и многое-многое другое. Поэтому «саундтрек» использовался в тех случаях, где надо проиграть музыку именно с начала – как в миссии «Некуда бежать», например. В других же случаях использовалось большое количество аудиозон, ведь они могут работать не только в интерьерах. В них, однако, музыка просто зациклена по кругу и начинаться будет чаще всего с хаотичной точки. Аудиозона также действует на определённой, собственно, зоне, поэтому в некоторых миссиях для пробы ниже нуля зона заканчивалась, благодаря чему не было музыки под водой. Если уплыть за границы карты, там музыка тоже закончится. Только из-за переходов от звуков воды к музыке тоже иногда появляются баги, потому что вода, как и гром – это лишь замедленный звук взрыва. Из-за резкого перехода скорость воспроизведения иногда не возвращалась к нормальной, и музыка либо замедлялась, либо вообще становилась настолько медленной, что превращалась лишь в криповые звуки.
▍ Группировки и стаи
Группы «банд» ограничены были только восемью членами, поэтому снова вставляем костыли в колёса – одного из членов нашей стаи делаем вожаком другой стаи, в которой состоит тоже вожак следующей стаи, и так до бесконечности. Это было необходимо для предпоследней миссии, однако это тоже вызывало некоторые трудности – при попадании в воду стаи уже перестают слушаться, и некоторые персонажи просто застревают в воде, не желая никуда плыть.
▍ Здоровье и интерфейс
В последней же миссии, которую никак не получалось адекватно сделать из-за больших размеров тирекса, тоже есть хитрость. В самом конце нам надо кинуть факел в пещеру с газом. Хоть вроде бы и существует опкод на проверку наличия огня на нужной площади, работает он так себе. Поэтому ровно за стеной стоит ти-рекс с 10% здоровья. Это можно проверить даже на джет-паке. При попадании факела возле него он сразу умирает, отчего проверка и срабатывает.
00BC: show_text_highpriority GXT 'MIS_478' time 5000 flag 1 // Burn up the cave gas.
018A: $RADAR_MISS_50_5 = create_checkpoint_at -1916.297 -1854.666 47.6738
03BC: $RADAR_SPHERE_50_5 = create_sphere_at -1916.297 -1854.666 47.6738 radius 1.5
Actor.GiveWeaponAndAmmo($PLAYER_ACTOR, Molotov, 10)
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 18
$TREX_50_7 = Actor.Create(CivMale, #VWMYBOX, -1918.56, -1857.228, 42.0)
Actor.Angle($TREX_50_7) = 10.0
Actor.Health($TREX_50_7) = 10
jump @MISSION50_11431
:MISSION50_11431
wait 0
if and
not Actor.Dead($DROMEO_50_1)
not Actor.Dead($DROMEO_50_2)
not Actor.Dead($DROMEO_50_3)
not Actor.Dead($DROMEO_50_4)
not Actor.Dead($DROMEO_50_15)
not Actor.Dead($DROMEO_50_16)
not Actor.Dead($PLAYER_ACTOR)
else_jump @MISSION50_12417
if
Actor.Dead($TREX_50_7)
else_jump @MISSION50_11431
wait 0
Marker.Disable($RADAR_MISS_50_5)
03BD: destroy_sphere $RADAR_SPHERE_50_5
00BC: show_text_highpriority GXT 'MIS_479' time 2000 flag 1 // Run away!
Подобным образом созданы и падающие метеоры в Грейхиллсе. Это просто самолёты с 1% здоровья, они уже дымятся и обязательно взорвутся при падении на землю. Позже они удаляются и спавнятся снова, и так до бесконечности.
Реализация:
wait 100
$METEOR9 = Car.Create(#STUNT, 2333.89, 1813.307, 159.8879)
Car.Angle($METEOR9) = 154.3845
099A: set_car $METEOR9 collision_detection 1
Car.Health($METEOR9) = 1
$METEOR19 = Car.Create(#STUNT, 2233.89, 1813.307, 199.8879)
Car.Angle($METEOR19) = 154.3845
099A: set_car $METEOR19 collision_detection 1
Car.Health($METEOR19) = 1
0948: create_explosion_at 2218.385 1826.519 41.4688 type 6 camera_shake 1
Camera.Shake(100)
wait 10
0948: create_explosion_at 2251.674 1800.366 37.8775 type 6 camera_shake 1
Camera.Shake(100)
wait 100
$METEOR10 = Car.Create(#STUNT, 2404.49, 1873.452, 166.5147)
Car.Angle($METEOR10) = 154.3845
099A: set_car $METEOR10 collision_detection 1
Car.Health($METEOR10) = 1
$METEOR20 = Car.Create(#STUNT, 2304.49, 1773.452, 196.5147)
Car.Angle($METEOR20) = 154.3845
099A: set_car $METEOR20 collision_detection 1
Car.Health($METEOR20) = 1
Интерфейс тоже был переделан. От самого движка остался только радар, немного изменённый внешне, а всё остальное также написано на мэине. Постоянно идёт отслеживание оружия в руках, в результате чего прорисовывается соответствующая текстура, шкала здоровья просто является софтверным прямоугольником с использованием эффекта альфы, названия территорий также читает и пишет мэин, а при получении урона опять же идёт отслеживание по падению уровня здоровья, в результате чего появляется текстура, скриптово переведённая в красную. В редких случаях на слабых компьютерах я видел, как текстура не успевала прорисовываться, тогда экран просто быстро мигал красным светом. А вот прочитать выносливость или объём воздуха в лёгких никак не удавалось, поэтому эти сведения так и не были выведены на экран.
▍ И что теперь?
Годы идут, Cretaceous Runner давно устарел, а до сих пор нам не предложили ни одной полноценной, сюжетной игры за жизнь динозавров. На самом деле, разумеется, это просто невыгодно. Конечно, разные команды уже пробовали подобное разрабатывать, но дальше сырых демок до сих пор дело не зашло. Хотя из всех игр, вроде как подходит к финалу замечательная THE SAURIAN, разрабатываемая большой командой людей, но без как такового сюжета… Ну и выпущена была также JWE, но это не совсем то, это лишь парк, да и динозавры там под большим вопросом, ведь игра делает упор именно на мутантов/гибридов. А так… сколько ни шло, ни одна сюжетная игра именно про динозавров так и не появилась, в результате чего я решил делать вторую часть Cretaceous Runner на UE4. У меня уже есть небольшая команда и идёт работа с модельками. Так что кто знает, кто знает… Глядишь, может в этот раз и получится!
Благодарю за прочтение! Скачать первую часть бесплатно вы можете здесь. С вами был Макар Дромкин, до новых встреч!
Автор: Фанерозой