Як створити текстову гру
wikiHow працює за принципом вікі, а це означає, що багато наших статей написано кількома авторами. При створенні цієї статті над її редагуванням та покращенням працювали, у тому числі анонімно, 24 особи.
Кількість джерел, використаних у цій статті: 8. Ви знайдете їх список унизу сторінки.
Кількість переглядів цієї статті: 44 323.
Текстова адвенчура або інтерактивна белетристика (interactive fiction, для стислості – IF) є найстарішим жанром комп'ютерних ігор, що має в наші дні відносно невелику, але віддану фанатську базу. Вони, як правило, знаходяться у вільному доступі, використовують незначний обсяг обчислювальної потужності, а краще те, що ви можете створити таку гру, без необхідності освоювати навички програмування.
Вибір програмного забезпечення
Спробуйте Inform 7. Inform 7 – популярний та багатофункціональний інструмент для створення текстових ігор (частіше званих інтерактивною белетристикою). Його мова програмування виконана у вигляді звичайних пропозицій англійською, одночасно надаючи повну функціональність. Inform 7 безкоштовний та доступний для систем Windows, Mac та Linux.
Використовуйте Adrift для створення гри на Windows. Adrift – чергова популярна, проста мови та компілятор інтерактивної белетристики. Оскільки він покладається на графічний інтерфейс, а не на кодуванні, в ньому легко можуть працювати люди, не знайомі з програмуванням. Adrift розповсюджується безкоштовно і доступний тільки для систем Windows, хоча створені за його допомогою ігри можна запустити на будь-якій операційній системі або навіть у браузері.
- Версія TADS 3 для Windows (і тільки вона) йде разом з доповненням «Workbench», завдяки якій програма стала ще доступнішою для людей, які не знають програмування, і в цілому більш зручна для використання. [2] X Джерело інформації
- Програмістів може зацікавити це детальне порівняння Inform 7 та TADS 3.
Пишемо текстову гру на Python/Ren'Py
Як зробити текстову гру? Та як завгодно. Як зробити кросплатформенну текстову гру російською з ілюстраціями, звуком, працюючими збереженнями, без проблем з кирилицею, і з якимось геймплеєм? Та ще й у вільний час, не відриваючись від основної роботи? Ось це вже цікавіше і насправді досить нескладно. Тих, хто зацікавився, прошу під кат.
Приблизно рік тому ми з товаришем задумали зробити невелику текстову гру приблизно на кшталт Sunless Sea і 80 days: про мореплавання, торгівлю, дослідження дивних поселень та спілкування з дивними особистостями. Там мала фігурувати релігія, а краще кілька, головного героя хотілося бачити не рятівником, героєм країни і прославленим мореплавцем, а помірковано невдалим підприємцем/авантюристом, до якого й справи нікому немає, а модний вибір між меншим і більшим злом замінити на вибір між добром. і добром: ніякого гримдарка, що набив оскому, заради гримдарка. Досить швидко придумалися основні фракції і персонажі, великі порти, політична обстановка і купа симпатичних дрібниць на кшталт підводного полювання на восьминогів (зображена на КДПВ) і геніальної ідеї дати майже всім персонажам угорські імена, які звучать екзотичніше за звичні європейські. Загалом, дерев'яних будиночків понабігало чимало.
У команді у нас на той момент був один письменник та один програміст (тобто я). Вимоги в попередньому абзаці ставляться скоріше до сетінгу та духу гри, так що виконувати їх мав мій товариш, а переді мною постали питання геймдизайну та функціональності двигуна. По-перше, більшу частину часу гравець витрачатиме, читаючи текст і обираючи дії головного героя. Для цього потрібна лише стерпна друкарня та можливість писати сценарій з меню, опціями та змінними. Незабаром підключилася художниця, тож треба було думати ще й про ілюстрації. По-друге, гра про дослідження та торгівлю, тому потрібно десь у доступному гравцеві вигляді зберігати інформацію про зібрані чутки та куплені товари (а також всіляко її обробляти). І, нарешті, у грі про мореплавство потрібна карта та можливість по ній переміщатися; просто команда “плисти до тартарів і послухати казки морських коней” явно відповідає духу проекту. Значить, двигун повинен ще й підтримувати хоча б нескладні міні-ігри, а не обмежуватися лише показом тексту та обліком ігрових змінних.
Чому Ren'Py
Відразу скажу, що писати двигун з нуля ми навіть не намагалися: велосипедобудування цікаве саме по собі, але малоефективно, якщо стоїть мета все-таки випустити гру до виходу на пенсію. Також ми не розглядали парсерну Interactive Fiction: у неї і англійською дуже невелика аудиторія, а російською наш проект, якби він був парсерним, міг би зацікавити в кращому випадку кілька сотень людей. А хочеться якщо не заробити грошей, то хоча б пройти грінлайт і набрати якусь репутацію.На щастя, більшість нинішніх англомовних розробників текстових ігор перейшла від некомерційних хобі-проектів до професійного геймдева буквально кілька років тому. Тому основні двигуни або опенсорні, або, у разі, безкоштовні. Погляньмо, що нам пропонують.
Перший варіант, що прийшов мені на думку – Storynexus від Failbetter games, розробників Fallen London та Sunless Sea. Проекти на ньому редагуються через браузер, хостяться Failbetter і через браузер доступні гравцям. Можливості для монетизації з минулого року видалили. Головний мінус, однак, не в цьому, а в тому, що в Fallen London більша частина подій представлена картами, що випадають із колоди, і зробити на Storynexus гру, яка не використовує цю метафору – завдання нетривіальне. Та й взагалі намертво прив'язувати свій проект до стороннього сервера із закритим кодом, який теоретично може взагалі припинити роботу будь-якої миті, досить ризиковано.
Є ще два хороші пропрієтарні движки для Choose Your Own Adventure, тобто ігор приблизно нашого типу: ChoiceScript і Inklewriter. Обидва обіцяють прекрасну друкарню, простоту розробки (браузерний редактор Inklewriter, скриптова мова ChoiceScript) і можливість комерційної публікації. На жаль, обидва дозволяють робити тільки чисте CYOA: немає можливості додавати в гру щось крім власне тексту, меню та ілюстрацій. Уважний читач вигукне: “Але як так? У 80 days був досить складний інвентар та інтерфейс подорожей, так? А в Sorcery! я точно бачив бойовку!” На жаль, ці системи розроблялися Inkle Studios під конкретні ігри і в редакторі немає ні їх, ні будь-якої можливості зробити собі такі самі.З тієї ж причини (а також тому, що він, ем, своєрідний) ми відмовилися від Twine.
Єдиним варіантом, що влаштовує нас, виявився Ren'Py. /Mac/Linux – питання натискання однієї кнопки, причому навіть не треба мати під рукою цільову ОС. Android та iOS також заявлені і Ren'Py-релізи під мобільні осі існують, але ми самі поки що на мобільний ринок не цілимося і про розробку для нього розповісти не можемо. живе співтовариство російською та англійською.
Найпростіший сценарій на Ren'Py
Ren'Py написаний на Python 2.7 + Pygame і має власний DSL. nyasha1” в імперативному стилі пишеться власне сценарій. По-друге, підмножиною цієї мови є Screen Language, на якій можна в декларативному стилі збирати з обмеженого набору Displayables (тобто віджетів: кнопок, зображень, текстових полів тощо) екрани та налаштовувати їхню функціональність. допомогою Python можна додавати власні. розберемося зі сценарієм.
Сценарій у Ren'Py складається з послідовності реплік, дій з екранами та введення гравця. Про екрани та введення трохи нижче, а для початку ми розберемося з персонажами.
define m = Character('Me', color="#c8c8ff") define s = Character('Sylvie', color="#c8ffc8") image sylvie smile = "sylvie_smile.png" label start m "Um. will you. " m "Ви будете мої артисти для visual novel?" show sylvie smile s "Sure, але what is a "visual novel?""
Створено два персонажі: протагоніст та Сільві, обидва пишуть блідо-синім кольором у стандартне віконце внизу екрану. У Сільві є портрет, який з'явиться на екрані перед тим, як вона почне говорити. Виглядає це так:
Якби ми створювали візуальну новелу, то продовжували б так само, але ми не збираємося показувати портрети персонажів, та й ілюстрацій пара десятків на всю гру. Більшість тексту також є прямою промовою персонажів, отже нелогічно було б прив'язувати її до комусь із них. Краще створимо віртуального персонажа-оповідача:
define narrator = Character(None, kind = nvl, what_color="#000000", size = 12)
Його звуть narrator; це спеціальне ім'я, яке віддає йому весь текст, явно не атрибутований іншим персонажам (строго кажучи, його звуть None, а narrator, як і m і s у попередньому прикладі – змінна, в яку міститься об'єкт персонажа і з якої викликаються його методи, наприклад , say) Аргумент kind приймає два значення: adv та nvl. Перше – це дефолтне поведінка, описане вище, а друге включає nvl-режим, у якому портрети не показуються, а текстове поле займає більшу частину екрана. Саме те, що нам було потрібно. Цей режим описується екраном nvl_screen у файлі screens.rpy та групою стилів styles.nvl* (файли screens.rpy та options.rpy відповідно), у яких ми задамо шрифт, фон текстового поля, колір меню та все інше.
label start: image bg monet_palace_image = Image('images/1129_monet_palace.jpg', align=(0 .5, 0.5)) nvl clear hide screen nvl scene bg monet_palace_image твої пісеньки - лайно, Люсьєне, і я не розумію, де ти тільки знаходиш музикантів, згодних це виконувати!
Розберемо рядково: спочатку оголошується ярлик start, з якого розпочнеться гра. Ця назва зарезервована і двигун завжди буде переходити на неї після натискання кнопки "Нова гра", де б у сценарії він не знаходився. Все, що слідує за ярликом, логічно знаходиться "всередині" цього ярлика, тому виділяється індентацією: вона в Ren'Py працює так само, як і в чистому пітоні. Ініціалізація картинки досить очевидна, а ось наступний рядок робить важливу річ: прибирає весь текст з екрану nvl_screen. Автоматично це не робиться, тому, якщо не розставляти nvl clear наприкінці кожної сторінки, текст спокійно заповзе за межі екрана і буде виводитися туди, доки екран не буде нарешті очищений. Наче дрібниця, але на налагодження пропущених nvl clear я витратив набагато більше часу, ніж готовий визнати. Свіжовитий екран ми тимчасово приберемо, щоб дозволити гравцеві помилуватися фоном, покажемо фон, включимо нескінченну паузу (тобто дочекаємося кліку) і почнемо історію. Як тільки на nvl_screen почне виводитись текст, екран сам повернеться на місце.
Рядок з паузою, до речі, вже на пітоні: для включення одиничного рядка її достатньо почати з $, а більш довгі шматки коду потрібно писати всередині блоку python:. Будь-який код, що виконується грою, бачить модулі самого Ren'Py і явно імпортувати їх не потрібно.
Додаємо розгалуження та змінні
До цього моменту гра є читалкою, яка показує текст, змінюючи при необхідності фони. Збереження, перемотування, головне меню та налаштування вже працюють із коробки. Однак якби ми хотіли написати ілюстровану повість, то ми б її й написали, чи не так? Додамо перед текстом невелике меню:
label start: menu: "Зайти в меню різноманітного дебагу": $ debug_mode = True jump debug_menu "Пропустити вступ": jump the_very_start_lazlo_nooptions "Почати вступ": label the_very_start: #show screen nvl nvl Ren'Py.pause(None) " - Я завжди казав: твої пісеньки - лайно, Люсьєне, і я не розумію, де ти тільки знаходиш музикантів, згодних це виконувати!"
Тепер після включення гри користувач (або, швидше за все, розробник) зможе за бажання увійти в режим дебагу або пропустити вже готовий шматок вступу і почати тестувати відразу шматок з останнього комміту. Рядок show screen nvl закоментований за непотрібністю - як я вже згадував вище, екран з'явиться сам собою, коли на ньому оновиться текст. Коментарі, як бачите, працюють абсолютно очевидним чином.
Ярлики, меню та інші індентовані блоки можуть бути вкладені до довільної глибини, але практично ми намагаємося дробити текст на епізоди в десяток сторінок. Кожен такий епізод описаний всередині окремого ярлика з нульовою індентацією (він вже не повинен бути всередині ярлика start або навіть в одному з ним файлі), а переходи з одного епізоду до іншого здійснюються стрибками.Так ми не тільки боремося з десятками рівнів індентації, але й забезпечуємо модульність коду: кожен епізод може тестуватися окремо і досить нескладно перевірити, які він читає, в які пише і куди дозволяє перейти.
Внутрішньоігрові меню та змінні влаштовані абсолютно так само. Оскільки і змінних, і ярликів навіть у невеликому епізоді на десять хвилин гри розлучається неймовірна кількість, ми прийняли нескладний варіант угорської нотації: ім'я ярлика 'the_very_start_lazlo_nooptions' складається з трьох частин: назви локації the_very_start (тобто період початку гри ), назви епізоду lazlo (тобто п'янка у Лазло, на якій можна найняти молодих ледарів у матроси) та імені власне ярлика. При такому підході імена виходять досить громіздкими, але краще так, ніж виявити при тестуванні, що три місяці тому хтось вже створив змінну ship_listing, виставив True бозна де і тепер крен з однієї випадкової події впливає на результат іншої випадкової події на іншому кінці моря.
Замість ув'язнення
До цього моменту ми вже відтворили на Ren'Py функціонал згаданих вище Choicescript та inklewriter. Начебто наш кораблик готовий до відплиття. У наступній статті я покажу, як можна створювати складніший інтерфейс із використанням екранної мови RenPy і ще складніший — на чистому пітоні.