Якою мовою працює renpy




Якою мовою працює renpy



Якою мовою працює renpy?

Ліричний відступ: цей гайд буде зосереджений на функціях та їх застосуванні в контексті Ren'Py та визновелл. Загальні принципи програмування торкнуться мінімально необхідних рамках.

Дисклеймер: всі конкретні факти та твердження про роботу Ren'Py актуальні на момент публікації та для версії 7.0. Надалі все може застаріти та відпасти через непотрібність. Смуток.

Для чого мені функції?

Уявіть, що ви, у складі молодої команди, що подає надії, пишете звичайнісіньку рпг-новелу з блекджеком і статами. І у головного героя, як і належить герою рпг, є сила, спритність та інтелект. І харизма ще й кожного на старті по десять очок. Заведемо їх зберігання словник.


Припустимо, ми вирішили не робити повноцінну бойовку, а замінити її текстовими енкаунтерами (перестрибнути яр, відтягнути повалене дерево з дороги, посваритися з торговцем), які відбуватимуться за певною схемою. У кожен енкаунтер ми кидаємо кубик, викидаємо на ньому випадкове значення та порівнюємо його з відповідною характеристикою героя. Якщо у героя більше, він переміг і отримує невелику надбавку до цього стату:

"Герой потрапив у магічну пастку."
$stat_id = "int"
$ random_roll = random.randint(stats[stat_id] - 5, stats[stat_id] + 5)

if stats[stat_id] > random_roll:
$ random_bonus = random.randint(1, 3)
$stats[stat_id] += random_bonus
". і завдяки потужності свого розуму зміг звільнитися! І отримав +[random_bonus] до інтелекту."

else:
". застряг і просидів у ній, поки бродячий маг не визволив його."

Від сутички до сутички (залежно від того, який показник проходить перевірку) змінюється stat_id, Решта код, за вирахуванням фраз-реакцій, абсолютно однаковий. П'ять рядків коду, нічого. Припустимо, таких сутичок у грі буде сто.Сто блоків однотипного/повторюваного коду не проблема.

Окей, каже гейм-дизайнер, а що якщо додати штрафи? Ну, якщо провалив перевірку – нехай ловить випадковий дебафф до відповідної характеристики!

Окей, кажете ви. Це всього пару рядків виправити.
У ста входженнях коду.

if stats[stat_id] > random_roll:
$ random_bonus = random.randint(5, 10)
$stats[stat_id] += random_bonus
". і завдяки потужності свого розуму зміг звільнитися! І отримав +[random_bonus] до інтелекту."

else:
$ random_bonus = random.randint(1, 3)
$stats[stat_id] -= random_bonus
". застряг і просидів у ній, поки бродячий маг не визволив його, і отримав -[random_bonus] до інтелекту."

На дев'яносто п'ятому блоці до вас приходить гейм-дизайнер і, сяючи, повідомляє, що дописав ще п'ятдесят сутичок. Ах так, надбавки до статей якісь кінські, зроби їх якнайменше на пару одиниць.

Ви з тугою дивіться на сто старих блоків, що вимагають виправлень, і п'ятдесят нових на гейм-дизайнера. А можна якось ці дії зібрати в одному місці, щоб не виправляти щоразу триста входжень?

Ага. Ось для цього (зокрема) і потрібні функції.

tldr: функції об'єднують набір команд в один контейнер, спрощуючи редагування, роботу, виклик і скорочуючи обсяги коду.

Ліричний відступ: Взагалі, прагнення вкоротити код і позбутися фрагментів, що повторюються, — одна з ознак того, що ви вже хапнули сумного досвіду в кодерстві. Щиро раджу весь повторюваний і параметризований код прибирати у відповідні контейнери: у стилі, екрани, ATL-конструкції та функції.

Чому не лейбли, а функції? Закономірне питання, яке може виникнути: навіщо мені писати функцію, якщо я можу запхати повторюваний код у лейбл, а потім робити call label у потрібних місцях? Все просто: великі масиви текстових реплік, що повторюються, або операторів йдуть в лейбли. Пітонівський код - у функції.Все на місцях, не змішувати.

Що таке функція? Який вигляд має стандартна функція?

Функція – це окремий шматок коду, який можна викликати з (умовно) будь-якого місця програми. Звалюєш величезну купу команд, що багато разів повторюються, в одне спеціально обгороджене місце, і щоразу, коли потрібно їх виконати, не пишеш всі команди заново, а кажеш "виконай он ту купу команд".

У Ren'Py (а насправді в Python, батьку Ren'Py) функції можуть бути анонімними (безіменними), але нас поки що цікавлять іменні.

Щоб користуватися функцією, насамперед потрібно оголосити та визначити її. Для іменних функцій це робиться за допомогою команди def. Оскільки це все пітонівський код, його потрібно вкласти в блок init python.

init python: — оператор, який каже, що далі йде пітонівський код (python), і що виконувати цей блок потрібно при старті гри (init). Обов'язковий для оголошення функцій. В одному init python блоці може бути скільки завгодно функцій.

def(): - обов'язкова конструкція-заголовок, яка має бути у будь-якої іменної функції. Функція може мати параметрів, у разі у дужках нічого не потрібно писати.

Тіло функції — має бути порожнім, тобто. містити хоча б одну команду (наприклад, return-конструкцію).

return - цей рядок не обов'язковий. Якщо її немає, компілятор за промовчанням вважає, що функція повертає None. Рядок, що складається тільки з оператора return, без значення, еквівалентна return None. Замість можна підставити будь-яке значення - змінну, число, рядок, вираз, скорочену форму умовного оператора. Детальніше про значення, що повертаються — трохи нижче.


Оголошена функція може бути викликана з різних ділянок коду. Коли ми викликаємо функцію, це змушує відпрацьовувати весь код усередині неї.


Чудово! Тепер ми зможемо написати свою функцію, яка описує результат сутички!
init python:
def Encounter():
random_roll = random.randint(stats[stat_id] - 5, stats[stat_id] + 5)
.

. Так, ні, стоп. Звідки ми візьмемо stat_id? Воно ж щоразу має бути різним! Як сказати функції, яку саме характеристику ми збираємося тестувати під час кожного конкретного виклику?

Параметри (аргументи) функції.

Аргументи функції - це дані, які вона приймає із зовнішнього коду, для того, щоб використовувати їх у собі.

Параметри і аргументи з погляду користувача — та сама сутність. З точки зору функції, параметри - це те, що описує значення, що приймаються ззовні, а аргументи - це ці значення і є. Якщо зовсім спрощувати, то в оголошенні функції в дужках параметри, а у викликі аргументи.

Аргументи при виклику поділяються комами і бувають позиційні та іменовані. Позиційні — це ті, для яких важлива їхня черговість у дужках під час виклику. Це єдиний спосіб зрозуміти, який параметр ви передаєте цей аргумент. Іменовані — це ті, у яких для ідентифікації є ім'я, і ​​стояти у своїй групі вони можуть у будь-якому порядку (як у списках та словниках: одним важливий порядок, інші зберігаються упереміш).

Параметри також можуть бути позначеніяк строго-позиційні або строго-іменовані. За замовчуванням у пітонівській функції всі параметри – позиційно-іменовані. Це означає, що при виклику можна дотримуватися черговості, передаючи аргументи, так і вказувати ім'я параметра, в який передаєш аргумент.

Якщо ви бачите в оголошенні функції параметр, попереджений зірочкою, наприклад *args, тобто перед вами змінно-позиційний параметр.

Якщо ви бачите в оголошенні функції параметр, попередній двома зірочками, наприклад **kwargs, тобто перед вами змінно-іменований параметр.

Змінні параметри використовуються тоді, коли точне число аргументів у виклику функції невідоме та/або занадто велике, щоб не описувати кожен можливий параметр, оголошуючи функцію.

Параметри можуть бути обов'язковими або необов'язковими, якщо ви оголошує функцію для параметра значення за замовчуванням, інакше — він обов'язковий. чи не бути невизначеною кількістю.

Невідповідність кількості аргументів кількості параметрів.

Функція завжди чекає від вас деяку кількість аргументів (від нуля до нескінченності).

Аргументів у виклику функції не повинно бути менше ніж обов'язкових параметрів, інакше отримаємо помилку виду:

так їсти X argument (Y given)

Аргументів у виклику не повинно бути більше, ніж усіх параметрів, інакше отримаємо помилку:

так at most X argument (Y given)

Виняток: якщо, див. вище, при оголошенні функції було вказано змінні параметри, тобто куди збирати зайві аргументи.

Порядок передачі аргументів під час виклику.

Порядок позиційних аргументів під час виклику строгий, і задається в оголошенні функції.

Порядок груп параметрів у оголошенні функції:

- Група звичайних (позиційно-іменованих) параметрів, для яких не вказано значення за замовчуванням (якщо такі є)
- група звичайних параметрів, для яких встановлено значення за замовчуванням (якщо такі є)
- Група змінно-позиційних параметрів (якщо такі є)
- Група змінно-іменованих параметрів (якщо такі є)

Порядок параметрів усередині кожної групи не має значення.

Порядок груп аргументів у виклик функції:

tl;dr: спочатку безіменні в строгому порядку, потім - іменовані, як завгодно.

- Група позиційних аргументів (без імен) (якщо такі є). Порядок аргументів у цій групі має відповідати порядку відповідних параметрів у оголошенні функції
- група іменованих аргументів (якщо такі є), порядок усередині групи не є важливим
- аргументи у вигляді *кортеж або список значень без імен через кому (якщо такі є), порядок усередині групи не важливий
- аргументи у вигляді **словник або список пар виду ім'я = значення через кому (якщо такі є), порядок усередині групи не важливий

При цьому важливо! Будь-які іменовані аргументи мають стояти строго після всіх позиційних.

(Крім того, існують окремі випадки, коли у виклику функції можна переставляти групи місцями та змішувати аргументи різних груп. Наприклад, змінно-іменовані з іменованими, якщо у виклику в принципі немає позиційних. Але правило "спочатку безіменні, потім з іменами" залишається. )

Окей, гугл, ми викликали функцію і передали їй усередину якісь значення із зовнішнього коду. Що з ними робити далі? Як функція їх бачить?

Робота з переданими значеннями

Отримані значення функція розподіляє локальними змінними відповідно до імен параметрів і позицій. Якщо для якогось параметра було встановлено значення за промовчанням, то передане значення для саме цього дзвінка його перепише.

Змінно-позиційні параметри *args приймають дані як кортежу. Ці дані поміщаються в локальну змінну з тим самим ім'ям, без зірочки. Тобто. дані, передані в параметр *something будуть поміщені у змінну something.

Аналогічно – із змінно-іменованими. Дані, передані у параметр **anything будуть поміщені у вигляді словника в локальну змінну anything.

Готовими локальними змінними всередині тіла функції можна користуватися так само, як і зазвичай. Чому я постійно додаю "локальні"? Тому що.

Область видимості

. ще одне поняття, якого варто торкнутися, говорячи про функції - область видимості змінних (scope).

У контексті обговорюваного питання області видимості (і змінні) поділяються на локальні та глобальні. Локальних областей видимості може бути кілька, глобальна одна. Оголошені дані доступні для читання з будь-якого місця програми. Тобто. якщо ви оголосили змінну в глобальній області видимості, ця змінна буде глобальною, і звертатися до її вмісту можна з будь-якої точки коду.

Змінні, оголошені в локальній області видимості, будуть доступні тільки всередині цієї конкретної локальної області, а за її межами не існуватимуть або будуть мати зовсім інші значення. Ми не можемо ні зчитувати, ні записувати в них інформацію ззовні області їхньої видимості.

У Ren'Py всі змінні всередині проекту за промовчанням є глобальними. Так, якщо в одному файлі проекту ви оголосили всередині скрипта змінну my_variable, то вона буде доступна за цим ім'ям у всіх інших файлах.

Винятки, коли змінна буде локальною:

1. Якщо назва змінної починається з подвійного нижнього підкреслення. У цьому випадку змінна стане локальною для конкретного файлу в якому була оголошена, і буде доступна тільки в ньому та у файлах з тим же ім'ям (але розташованих у різних каталогах).

2. Якщо ім'я змінної оголошено у блоці python hide.

У цьому випадку областю дії змінної стане область дії блоку python, В якому вона оголошена, і буде доступна тільки в ньому.

3. Змінні, оголошені всередині функцій, класів та інших локальних об'єктів є локальними.

Останній пункт та функції цікавить нас найбільше. Всередині функції ми можемо спробувати звернутися до певної змінної, яку ми всередині цієї функції не оголошували. Функція вигляне назовні та перевірить, чи є у глобальній області змінна з таким ім'ям. Якщо вона є, ми зможемо рахувати її поточне значення (а якщо її немає, випаде помилка).Але навіть якщо вона є, коли ми спробуємо щось у неї записати, то (за замовчуванням) перша ж операція присвоєння всередині функції створить локальну змінну з такою ж назвою. І всі операції з цією змінною залишаться в локальній області дії функції, і не збережуться "зовні".


З одного боку, це корисно, тому що в десятці функцій ми можемо спокійно працювати зі змінними з однаковими іменами, не боячись, що одна перетретя дані в іншій. Але що, якщо нам потрібно змінити значення глобальної змінної функції зсередини? Для цього потрібно явно оголосити, що ми збираємося працювати із глобальною змінною. Синтаксично є кілька способів зробити це, але найзручніший і найпростіший — скористатися ключовим словом global.

def YetAnotherFunction():
global global_one, global_two, global_three

Після ключового слова через кому перераховуються імена змінних, що у глобальній області видимості. Тепер усі зміни, виконані з ними всередині функції, збережуться і поза нею.


Інший спосіб звертатися до глобальної змінної всередині функції через словник globals(), В якому зберігаються за ключами всі існуючі глобальні змінні. Ось так:

Так, запис такий і має бути, прямо з круглими дужками після globals.

Цей та попередній способи характерні для Python. Ren'Py має ще один, свій. Працює він за рахунок того, що всі глобальні змінні за умовчанням Ren'Py кидають у місце під назвою store. Це не словник, а об'єкт, і до змінних усередині store звертатися треба трохи інакше:

Значення, що повертається

Функція вміє отримувати дані ззовні і щось із нею робити. Крім цього, функція вміє повертати якісь дані назад у зовнішній код за допомогою оператора return. Якщо return всередині функції відсутня, вона все одно неявно повертає None.

У загальному випадку, якщо просто викликати функцію, то її значення, що повертається, провалиться в нікуди, тому що не буде контейнера, який би його прийняв.Щоб покласти значення, що повертається в якусь змінну, достатньо викликати функцію з операції присвоєння.

init python:
def CustomFunc1():
return 20

def CustomFunc2():
pass

hero "Я тут щось говорю."
$ val1 = CustomFunc1()
$ val2 = CustomFunc2()
hero "Повернені значення: [val1] та [val2]"

В результаті val1 дорівнюватиме 20, val2None.

У нашому конкретному прикладі з героєм та перевіркою статів ми можемо повертати результат перевірки (True для успішної та False для проваленої), а також розмір збільшення/штрафу. Застосуємо всю отриману інформацію на практиці і побудуємо код цілком.

Нутрощі функції в загальному вигляді виглядають однаково: роль "перешкода", порівнюємо його з показником героя, робимо збільшення / штраф в залежності від результату порівняння, повертаємо результат у зовнішній код. Як єдиний аргумент нам необхідно передати ідентифікатор характеристики (ключ у словнику stats). Не забуваймо вказати, що словник stats - глобальна змінна (функція повинна змінювати значення всередині неї).

init python:
def Encounter(stat_id):
global stats

random_roll = random.randint(stats[stat_id] - 5, stats[stat_id] + 5)

if stats[stat_id] > random_roll:
random_bonus = random.randint(2, 4)
stats[stat_id] += random_bonus

return (True, random_bonus)

else:
random_debuff = random.randint(1, 3)
stats[stat_id] -= random_debuff

return (False, random_debuff)


Після того, як зовнішній код отримає результат сутички, ми вже за допомогою операторів Ren'Py і цього результату розрулимо ситуацію із фразами-реакціями:

"Герой потрапив у магічну пастку."
$ victory, stat_change = Encounter("int") # стара-добра розпакування кортежу, який повернуло return'ом

if victory:
". і завдяки потужності свого розуму зміг звільнитися! І отримав +[stat_change] до інтелекту."

else:
". застряг і просидів у ній, поки бродячий маг не визволив його, і отримав - [stat_change] до інтелекту."

Виклик функцій не будь-де коду.

У Ren'Py у нас є послідовний, покроковий код скрипта, виконанням якого ми можемо усвідомлено керувати, і є некерована машина у вигляді екранів. Код екранів може бути виконаний в зовсім несподівані для вас моменти (є всякі predict'и, є перемальовка екранів у момент взаємодії.). Якщо ви навіщось помістили в код екрану пітонівський код (у тому числі й виклик функції), то будьте готові, що цей код виконуватиметься не лише за очевидною командою show screen.

Є однак моменти, коли нам потрібно прив'язати виконання функцій і маніпуляцію з даними саме до екранів.

Екшени в Ren'Py або "Хочу, щоб після натискання кнопки виконувалася функція!"

Екшен у Ren'Py - це дія, яка виконується при натисканні, наведенні курсору на кнопку і відведенні курсору з кнопки (і ще в деяких випадках, на кшталт закінчення часу в таймері). У Ren'Py з коробки доступні різні екшени для різних цілей, з параметрами і без.

Ліричний відступ: перекладений список всіх описаних у документації екшенів тут.

Виклик екрану, стрибок на мітку, присвоєння змінної деякого значення - все це охоплено стандартним функціоналом, і перед тим, як писати кастомну функцію. перевірте, може бути вже є готовий екшен для цього. А якщо немає одного, то, можливо, можна використати список із кількох:

# натисканням на кнопку: додаємо до значення всередині my_var одиницю, ховаємо екран my_screen, стрибаємо на мітку my_label
textbutton "Кнопка" action [ SetVariable("my_var", my_var + 1), Hide("my_screen"), Jump("my_label") ]

Крім цього, якщо вам потрібно обмежити виконання екшенів якоюсь умовою, на допомогу прийде спеціальний екшен If(). Скажімо, ви хочете в якийсь момент заборонити користувачеві натискати кнопку, але не ховати її зовсім, а зробити неактивною:

default number_of_times_to_press = 5

screen conditional_btn():
текстbutton "Кнопка" action If(
number_of_times_to_press > 0,
true = SetVariable("number_of_times_to_press", number_of_times_to_press - 1)
)

У цьому прикладі змінна number_of_times_to_press керує активністю кнопки. Кожне натискання віднімає від її значення одиницю, і коли це значення дорівнюватиме нулю, кнопку більше не можна буде натиснути.

Загальний вигляд екшену If() виглядає так:

If тут пишеться з великої літери, а true і false — навпаки, з маленькою, бо в цьому випадку If - це екшен, а true і false - Його параметри.

На вигляд екшени з коробки підозріло нагадують функції: той самий вигляд, самі параметри. Насправді, це різні сутності. Екшен — це НЕ те саме, що й функція.

Гучно, хором: ЕКШЕН — НЕ ФУНКЦІЯ, ФУНКЦІЯ — НЕ ЕКШЕН.

Функція може виступати у ролі екшену за однієї умови: якщо її можна викликати без аргументів. Тобто:
- якщо ваша функція в принципі не має параметрів
- якщо у вашої функції є параметри, але жоден з них не є обов'язковим

Дуже важливий момент: якщо ми використовуємо функцію в ролі екшену, то пишемо її без дужок.

init python:
def CustomFunc():
# якийсь код

textbutton "Кнопка" action CustomFunc

Зі дужками (навіть порожніми) — це виклик функції. Без дужок – це ім'я. Ми не викликаємо функцію в екшен, ми говоримо "як екшен використовуй функцію на ім'я X"

Екшен не знає, які аргументи слід передати функції під час його (екшену) виконання. Якби ми спробували в екшені викликати функцію з аргументом, наприклад:

- то сталося б таке: під час виконання коду екрану, в якому знаходиться кнопка (а код екрану може виконуватися в найнесподіваніші для користувача моменти, нагадую):
- викликається та виконується функція CustomFunc(0);
- CustomFunc(0) повертає деяке значення (у нашому випадку None);
- це значення екран намагається трактувати як екшені якщо це не екшен, випадає помилка компіляції.

Але що робити, якщо після натискання кнопки має відпрацювати функція, викликана з певними аргументами?

Для цього є два способи: екшен Function() і curried-функції. Перший легше у зверненні та розумінні, другий має більш звичний вигляд суто зовні.

Тут все досить просто: у Ren'Py з коробки є спеціальний екшен, який приймає як свої аргументи ім'я функції, яку потрібно викликати по екшену, і набір аргументів, який потрібно передати цю функцію в момент виклику.

Function(callable, args, kwargs)

Він може приймати три параметри:

- callable: обов'язковий параметр. У нього ми кладемо ім'я (тільки ім'я, без дужок і решти!) функції, яку потрібно викликати.
- args: необов'язковий параметр, змінно-позиційний, ми вже бачили такі. Сюди скидаються всі позиційні аргументи, які мають бути передані функції під час виклику.
- kwargs: необов'язковий параметр, змінно іменований, аналогічно. Сюди скидаються всі іменовані аргументи, які мають бути передані функції під час виклику.

Коротенький проект для прикладу того, як працює цей екшен:

default gid = 0
default gname = ""

init python:
def someFunction(id, name = "Ім'я"):
global gid, gname

screen test():
vbox:
text "id: [gid]"
text "name: [gname]"

textbutton "Заповнити раз!" action Function(someFunction, "123", random_name)
textbutton "Заповнити два!" action Function(someFunction, , name = "Сіндзі")

label start:
scene black
show screen test

$random_name = "Випадкове ім'я"

У Ren'Py є спеціальна функція renpy.curry(). Вона:
- приймає як параметр callable-об'єкт (функцію)
- Повертає щось, яке:
- будучи викликаним, повертає дещо, яке:
- будучи викликаним, викликає функцію (З п.1).

Іншими словами, об'єкт, який повертає renpy.curry() від деякої функції, якщо його викликати двічі, робить те саме, що одного разу викликана функція.

Те саме, у вигляді картинки:

У рядку c = b() викликається функція MyFunction. При цьому передача аргументів відбулася рядком вище, b = a(5). Значить, у c = b() аргументи непотрібні. Отже, ми можемо викликати b без аргументів, а отже, використовувати b у ролі екшену. А b = a(5) за своєю суттю, тож якщо ми поставимо a(5) в екшен кнопки, і якщо при цьому a буде curried-формою функції MyFunction, то при виконанні екшену буде викликано функцію MyFunction із потрібними нам аргументами.

(Якщо вам і зараз нічерта не зрозуміло, не турбуйтеся, це нормально.)

init python:
def MyFunction(num):
renpy.notify("MyFunction викликали з аргументом %d!"%num)

screen MyScreen:
textbutton "Кнопка" action MyCurriedFunction(5)

У прикладі вище MyCurriedFunction(5) буде виконано під час виведення екрану MyScreenале замість того, щоб запустити функцію MyFunction, вона поверне нову функцію (явно її немає, назвемо її X). Яка, коли її викличуть, виконається так, як би виконалася MyFunction(5). Функція X стає екшеном, і це вирішує нашу проблему.

Насамкінець скажу, що функції в Ren'Py можуть бути використані не тільки для виконання будь-яких обчислень і установки прапорів. У наших проектах вони, наприклад, відповідають ще й за виведення екранів, перемикання фонів та сцен та іншу дрібну візуальну роботу. Це дуже зручно.

# функція winLight використовується для генерації кольорового вогника за заданим шаблоном

init python:
def winLight(color):
return Fixed(
AlphaMask(Solid(color), "animations/aroom/aroom-winlight.webp"),
Transform("animations/aroom/aroom-winlight.webp", zoom = .45, offset = (8, 8)),
xysize = (27, 27)
)

# кольорові вогники з лого вінди

image winlr = winLight("#d84035")
image winlg = winLight("#adc23d")
image winly = winLight("#d0ac26")
image winlb = winLight("#4474cf")

Особлива подяка користувачам Asceai за корисний пост про curried-функції і TheSHAD0W за пост про тонкощі роботи двигуна на лемі.Частина інформації звідти в перекладеному вигляді зараз пішла у написання цього гайда, а до цього надала неоціненну допомогу у розумінні роботи renpy.curry().

Ще раз залишаю посилання на список всіх екшенів Ren'Py російською (переклад документації): посилання

Ця сторінка є поза межами часу

Ви знайдете сторінку на Ren'Py wiki. Завжди масивний spam, wiki не буде бути updated в понад 5 років, і багато інформації, що є дуже довжиною . Вже ось-ось це може бути історичним інтересом, але всі відомості, пов'язані з сучасними версіями Ren'Py, буде бути переміщений усюди.

Some places to look are:

Двигун візуальних новел Ren'Py

Ласкаво просимо на російську сторінку Ren'Py - двигун для створення візуальних новел і симуляторів побачень, засобів оповідання за допомогою комп'ютера. Двигун використовує сценаріоподібний синтаксис скрипта, що перетворює свідомість простих ігор на нескладну справу, залишаючись гнучким і надаючи широкі можливості досвідченим авторам. Без будь-яких додаткових зусиль з боку творців ігор він надає можливості, очікувані в кожній візуальній новелі, наприклад, збереження-завантаження, доступ до налаштування різних параметрів гри та відмотування назад. Ren'Py підтримує Windows, Mac OS X і Linux x86, а також може бути запущений і на інших платформах. Ren'Py є програмою з відкритим вихідним кодом і може бути вільно використаний як для некомерційних, так і комерційних цілей. Створеним на ньому ігор бути з відкритими вихідними джерелами не обов'язково. За додатковою інформацією слід звернутися до ліцензійної угоди Ren'py. За допомогою Ren'Py вже було створено понад 180 ігор!.
Найкращим способом побачити Ren'Py у дії завантажитиме парочку з них (серед них навіть є російськомовні!).

Завантажити двигун Ren'Py

  • Завантажити свіжу англійську версію - www.renpy.org/latest.html.
  • Завантажити русифікацію для версії 6.16 - Ukrainian_translation_for_renpy_6_16.rar.
  • Завантажити застарілу русифіковану версію - Ren'Py 6.9.3 "Road to Recovery"
  • Завантажити інші версії можна на сторінці www.renpy.org/release_list.html.

Довідки, уроки та посібники з Ren'py

Російською мовою є:

  • Керівництво для початківців
  • Гра-приклад (Win/Linux/Mac)
  • Стаття "Анімація та трансформація об'єктів"
  • Переклад документації для Галереї зображень та Музичної кімнати

Англійською мовою на даному сайті можна знайти :

  • Документацію роботи з Ren'Py.
  • Стародавню Книгу Рецептів, що містить різні хитрі приймачі, розроблені членами Співтовариства Ren'Py для вирішення особливих завдань.
  • Сучасну Книгу Рецептів, що містить безліч прикладів налаштування інтерфейсу гри, використання ATL та Screen Language.
  • Трохи застарілі Посібники, які пояснюють основи роботи у Ren'Py, та Довідкове Посібник, що більш повно пояснює аспекти роботи Ren'Py.

Зворотній зв'язок

Кращого місця, щоб поставити своє питання про Ren'Py, ніж секція Ren'Py на форумах Lemma Soft, не знайти (якщо ви достатньо володієте англійською). Також можна зв'язатися з Творцем движка - паном PyTomом - безпосередньо, відвідавши сторінку з контактною інформацією.

Російські сайти про Ren'py

Також можна спробувати зв'язатися з 000 (він же Zero), автором локалізації та Посібника з Швидкого Старту, по e-mail'y nz000yandex.ru

What is Ren'Py?

Ren'Py is a visual novel engine – використаний для тисячі творців від навколишнього світу – що використовуються слова, зображення, і звуки до тих звичайних сторіях, які йдуть на комп'ютерах і мобільних пристроях. Вони можуть бути як visual novels and life simulation games. Досить до літературного script language allows anyone to efficiently write large visual novels, while its Python scripting is enough for complex simulation games.

Ren'Py є відкритим джерелом і безкоштовно для комерційного використання.

Where does it run?

Where do I get it?

Останній офіційний спосіб Ren'Py 8 є 8.3.4 "Second Star to the Right", виконаний на December 8, 2024.Ren'Py 8 є спільним для всіх проектів.

Nightly fix version з Ren'Py є побудовано every night, і позначки fixes до останніх старих версій. Це не буде випробувано як добре, як офіційний випадок, але має бути fixes, що не буде зроблено це шляхом виконання процесів.

Ren'Py 7 є legacy version of Ren'Py, щоб підтримувати ongoing projects що буде завершено в 2024 році.

Where do I start?

Quickstart walks you через process creating a simple game.

Якщо ви хотіли б розробити Ren'Py розробку, можна запустити нашу GitHub проектну сторінку.

How do I keep in touch?

Найбільші площі до всіх питань про Ren'Py є Lemma Soft Forums, Ren'Py Discord, і #renpy IRC канал.

We make news about Ren'Py можна отримати на номері соціальних платформ:

Twitter: Ви можете доповнити Ren'Py's lead developer @renpytom for release announcements, розробка новин, і загальний коментар на життя.

Facebook: We announce нові releases на нашій Facebook page.

Who is it sponsored by?

Для цих думок, що не підходить для громадського форуму, або проходитиме співрозмовник для вашого слов'яного знайомого конференція або con, contact us us email.

Featured Games

Ren'Py має бути використаний для створення понад 4,000 visual novels, games, та інших робіт. Ви можете побачити Ren'Py visual novels на Visual Novel Database, і грати з Ren'Py on Itch.io and Steam.

Тут є всього кілька гравців, що створені з Ren'Py.

The Still Dancer tells the story of a family heirloom trying to regain her memory. Highway Blossoms, thele of two girls' epic road trip через American Southwest. Bad End Theater (Itch, Steam) використовує Ren'Py для того, щоб бути його protagonistaм до щаблів з тероричних лих. King of the Cul-De-Sac робить великі прийоми з Ren'Py's animation language and interactivity. Дошці версії Докі Докі літературні клуби використовуються для Ren'Py для того, щоб бути знайдений.

Схожі статті

  • Якою мовою роблять браузерні ігри
  • Якою мовою написаний Фнаф 2
  • Якою мовою буддійські мантри
  • Якою мовою розмовляють з туристами в Чорногорії
  • Якою мовою був створений Скайрім
  • Якою мовою написані послання апостола Павла
  • Якою мовою написано Мортал Комбат
  • Якою мовою написано Скетчап
  • Недавні статті

  • Як бродить зернова брага
  • Що робити якщо не засмагаєш на сонці чому засмага погано лягає на шкіру або перестає прилипати
  • Як швидко зняти гель лак без апарату
  • Як робиться Каті голови
  • Яка гребінець краще для об'єму
  • Чим роблять м'яку покрівлю
  • Чи можна залишати крем для обличчя на ніч
  • Де знаходиться датчик селектора
  • географія нашої діяльності
    вулиця Драгоманова, 27
    вул. Курчатова 1Б
    вул. Міцкевича 130
    вул. Лабунського, 1
    вул. Макарова-Пржевальського
    вул. Толстого 10
    вул. Грушевського 28
    вул. Перший промінь (Черняхівського)
    напишіть нам

    сообщение успешно отправлено
    x