Losowe wypowiedzi NPC [RPG Maker 95]

Jednym z łatwiejszych rozwiązań urozmaicających grę z RPG Makera jest wprowadzenie różnych, losowych wiadomości od NPC. Typowa implementacja w każdej wersji RM wygląda mniej więcej tak (przykład z RM2k):

Jak widać całość polega na wylosowaniu wartości w zmiennej, a później w zależności od wyniku wyświetlenia różnej wiadomości. Jest to na tyle proste i podstawowe, że zazwyczaj makerowcy uczą się tego przy okazji podstaw obsługi zmiennych i warunków.

Po co więc ten poradnik? Jak zapewne zauważyliście dotyczy on wersji 95 i to tutaj jest kluczowe. Albowiem w 95 nie mamy poleceń zmiennych i warunków. Więc podczas próby przeniesienia komend z powyższego zrzutu napotkamy na problem, bo jedynym poleceniem które znajdziemy jest samo wyświetlanie tekstu. Czy to więc oznacza, że tego typu interakcja z NPC jest niemożliwa do uzyskania w RM95? Wydaje się, że tak, no ale tylko się wydaje – po coś w końcu piszę ten tekst.

Zacznijmy od warunków

Jak ustaliliśmy brakuje nam dwóch składników: zmiennych (a dokładniej tu wąskiego zastosowania ich – losowej wartości) i warunków, rozgałęzień samego zdarzenia na ścieżki z różnym tekstem. Zacznijmy od tego drugiego. Jakie więc mamy możliwości? RM95 nie potrafi zrobić rozgałęzienia w ramach jednej strony zdarzenia (poza poleceniem Pokaż Wybór, ale to zostawmy), musimy więc rozbić nasz skrypt na kilka stron. A same strony posiadają przecież warunki ich startu, więc się im przyjrzyjmy:

Na wstępie możemy odrzucić warunek Member ponieważ nie chcemy zmieniać nic w naszej drużynie podczas każdej rozmowy z NPC. Zostają więc nam warunki Item, Gold i Switch. Najlepszy zawsze i preferowany w systemach w grze jest przeze mnie warunek Switch, ale niestety z użyciem tylko jego nie będziemy w stanie zrobić nic losowego, ponieważ przełączniki możemy tylko włączać i wyłączać. Nie mamy możliwości losowego ustawienia wartości przełącznika. Zostają jeszcze Item i Gold. Oba te elementy mogą przyjmować losowe wartości, dzięki temu, że większość poleceń modyfikujących ilości w RM95 mają opcję losowania wartości z zadanego przedziału. Mogę zdradzić, że wykorzystamy tu kombinację przełączników i dwóch przedmiotów, ale póki co przyjmijmy, że chcemy wykorzystać po prostu złoto. Jest to najbliższa zmiennej funkcja dostępna w RM95, więc kod z użyciem jej nie będzie skomplikowany.

Prototyp 1

Utwórzmy więc zdarzenie. Na pierwszej stronie zróbmy wszystko tak, jakbyśmy robili normalnego NPC tylko w samych poleceniach zdarzenia dajmy Zmień Złoto i ustawmy wartość losową od 1 do 3. Na kolejnych trzech stronach zdarzenia dajmy warunek startu Gold i wartości po kolei 1, 2 i 3. Same strony ustawmy też na Autostart, a w poleceniach dajmy na każdej inny tekst + resetowanie wartości pieniędzy na 0. Powinno to wyglądać mniej więcej tak:

Możemy przetestować i zobaczyć, że to faktycznie działa. Jednak ta wersja ma jedną ogromną wadę – używa złota, które zazwyczaj potrzebujemy po prostu dla pieniędzy naszych bohaterów w grze i nie możemy sobie pozwolić na jego użycie w tak błahym celu. Pomijając to pewnie zauważyliście jeszcze dwa problemy. Pierwszy – w RM95 zdarzenia mają tylko cztery strony, co ogranicza nas do tylko trzech losowych tekstów, oraz drugi – NPC nie odwraca się w stronę gracza podczas dialogu. Uspokoję jednak – oba te problemy rozwiążemy i naprawimy w ostatecznej wersji. Zresztą naprawa problemu braku obrotu jest na tyle prosta, że możemy to zrobić już teraz. Wystarczy, że na każdej z tych trzech stron z dialogami w Setup Movement damy komendę TrnOppPFace (Obróć w przeciwną stronę niż patrzy bohater) i zmienimy prędkość na 1. I tyle, NPC teraz będzie się obracał w naszą stronę.

Prototyp 2

Dobra, teraz po prostu pozbądźmy się złota, zostawiając póki co resztę bez zmian. Musimy więc wykorzystać ostatnią dostępną dla nas przy warunkach dającą się losować rzecz – czyli przedmioty. Jednak dość szybko natkniemy się tu na ścianę. Tak jak warunek złota pozwalał nam ustawić wartość, ile dokładnie tego złota potrzebujemy by odpalić stronę, tak przedmioty nie posiadają takiej opcji. Możemy tylko ustawić, czy dany przedmiot posiadamy, czy nie. Wciąż jednak możemy sprawić by samo posiadanie przedmiotu było losowe. Wystarczy dać polecenie zmień przedmiot i ustawić zakres od 0 do 1. Jednak ogranicza nas to do dwóch losowych tekstów, co nie jest zbyt satysfakcjonujące. Aby uzyskać trzy opcje jak w wersji powyżej dodamy losowanie jeszcze jednego przedmiotu. Warunki startu każdej z stron będą odpowiadać więc takim stanom: brak jakiegokolwiek przedmiotu, posiadamy 1 przedmiot, posiadamy 2 przedmiot. I nadal trzy te stany będą całkowicie losowe.

Usuńmy więc losowanie złota z pierwszej strony, a zamiast niego dajmy takie trzy polecenia: Zmień przełącznik na ON, Ustaw 1 przedmiot losowo 0-1, Ustaw 2 przedmiot losowo 0-1. Zastanawiacie się pewnie po co ten przełącznik. Jest on potrzebny aby jakoś wywołać stronę która ma się odpalać gdy nie posiadamy żadnego przedmiotu. Teraz wystarczy zmienić na następnych stronach warunki startu. Na pierwszym tekście dajemy warunek startu na przełącznik. Na kolejnym posiadanie pierwszego przedmiotu i na ostatniej drugiego. W samych poleceniach musimy też zmienić z powrotem przełącznik na OFF, i usunąć przedmioty. Druga wersja naszego skryptu wygląda więc tak:

Testując, albo nawet bez tego, można zauważyć, że ostatni tekst wypada częściej niż dwa pozostałe. Tak to błąd, ostatnia strona ma 50% szans na wystąpienie, podczas gdy dwa pozostałe tylko po 25%. Pierwotna wersja miała po równe 33,33% na każdą stronę. W sumie moglibyśmy tak to zostawić, ale po co skoro możemy to naprawić. Póki co naszą sytuacje losowości przedstawia taki diagram:

losowanie Unused 2

/        \

                      tak – tekst 3 (50%)          nie – losowanie Unused 1 (50%)

                                                         /        \

                                                        tak – tekst 2 (25%)       nie – tekst 1 (25%)

Musimy więc sprawić aby wynik z losowania Unused 2 był tak 33,33% do nie 66,66% – co naprawi naszą sytuację. Możemy to bardzo prosto zrobić ustawiając po prostu zakres losowości od -1 do 1. Ale gdy spróbujemy to zrobić zauważymy, że nie możemy zejść z wartością niżej niż 0. Jest to jednak ograniczenie przy ustawieniu Absolute, wystarczy przełączyć na Relative, co pozwoli nam wpisać wartości ujemne. Zamiast więc losować stałą wartość z przedziału 0-1, będziemy losować czy dodać 1 do przedmiotów których mamy 0. Da nam to trzy wartości, zamiast dwóch, i naprawienie problemu z nierównym prawdopodobieństwem. Strona pierwsza będzie wyglądać więc tak (reszta bez zmian):

Widać więc, że w razie potrzeby możemy ustawić różne prawdopodobieństwa dla wystąpienia poszczególnych zdarzeń po prostu ustawiając inne przedziały. Dodając więcej wartości ujemnych sprawiamy, że prawdopodobieństwo nam maleje, a więcej dodatnich, że rośnie. Na przykład dla prawdopodobieństwa wystąpienia tekstu 3 10% należy ustawić zakres od -8 do 1, a dla 90% od 0 do 9.

Ostateczny skrypt

W sumie to, co już mamy, jest na tyle kompletne, że na tym moglibyśmy poprzestać. Warto jeszcze byłoby to poprawić, aktywując warunek przełącznika również na pozostałych stronach z tekstami. Wtedy dla różnych NPC na tej samej mapie wystarczy, że zmienialibyśmy tylko numer przełącznika i wszyscy mogliby działać równolegle, niezależnie od siebie. Utrata wiec dwóch przedmiotów na rzecz tego skryptu byłaby jednorazowa na całą grę. Oczywiście na innych mapach możemy znów użyć tych samych przełączników, więc tak na prawdę dodanie takiego bajeru do gry nie jest dla nas bardzo zasobożerne.

Tylko że gdzieś tam wyżej wspomniałem, że uda nam się również zdjąć ograniczenie do trzech tekstów na zdarzenie. A więc do dzieła. Jak się zapewne domyślacie, aby to zrobić musimy rozbić nasze jedno zdarzenie na kilka. Przedstawię tu wersję z dziewięcioma opcjami, co będzie wymagało od nas dodania czterech zdarzeń.

Najpierw więc stwórzmy zdarzenie drugiego NPC (dodamy kolejnego), który na pierwszej stronie będzie miał przełączanie dwóch przełączników na ON (dajcie inne niż ten w tym pierwszym zdarzeniu) i zmianę przedmiotów dokładnie taką samą, jak we wcześniejszej wersji. Wykorzystajmy też ostatnią stronę, która będzie startować na jeden z ustawionych przełączników. Na niej dajemy tylko w Setup Movement komendę TrnOppPFace i prędkość 1, aby postać odwracała się do nas podczas dialogu. Nie musimy jej ustawiać na Autorun. Nasze zdarzenie NPC będzie więc wyglądać tak:

Teraz tworzymy kolejne zdarzenie, ale w takim miejscu żeby było ono widoczne zawsze gdy rozmawiamy z NPC. Pamiętajmy, że RM95 przetwarza tylko te zdarzenia, które mieszczą się w aktualnie wyświetlanym obszarze. Pierwszą stronę zostawiamy pustą, ustawmy tylko wyświetlanie na Usuń. Za to kolejne strony będą miały dokładnie takie same warunki, jak nasz drugi prototypowy skrypt. Czyli 2 strona sam przełącznik (ustawiamy ten drugi, nie ten sam co na ostatniej stronie NPC), 3 strona przełącznik i pierwszy przedmiot, a 4 strona przełącznik i drugi przedmiot. Start wszystkich trzech na autostart i wyświetlanie grafiki na transparent. Na samych stronach robimy kolejne losowanie tych samych przedmiotów tak samo (z tym że pamiętajmy, by wyzerować drugi przedmiot przed losowaniem na Relative) i zmieniamy na ON trzy kolejne różne przełączniki. Zaoffujmy również przełącznik który nam odpalił te strony w tym zdarzeniu. Samo to zdarzenie będzie więc wyglądać tak:

Teraz musimy utworzyć trzy kolejne zdarzenia, które będą podobne do tego wyżej. W sumie to możemy je skopiować. W warunkach startu zdarzenia musimy zmienić tylko przełącznik tak, aby każde z tych zdarzeń startowało na inny, który włączaliśmy na tych trzech stronach powyżej. A w samych poleceniach dajemy nasze teksty, po czym zerujemy przedmioty i wyłączamy przełączniki (ten, który startował nam dane zdarzenie, jak i również ten, który aktywował nam ostatnią stronę u naszego NPC by ten był zwrócony twarzą do nas). Ostatecznie więc mamy coś takiego (pokarzę tylko jedno zdarzenie, pozostałe dwa różnią się tylko przełącznikiem startu strony i jego wyłączeniem):

To by było na tyle, można przetestować i zobaczyć, czy wsio działa.

Wnioski i ulepszenia

Jak widać dwa powyższe zdarzenia są niemal identyczne, jeśli chodzi o strukturę. Oznacza to, że w razie potrzeby można dodać więcej losowych opcji powtarzając po prostu w kolejnych krokach znów zdarzenie losowania z ustawianiem następnych przełączników. Gdyby np. zamiast tych dziewięciu tekstów dać dziewięć kolejnych losowań, mielibyśmy dwadzieścia siedem wyników. Oczywiście wymagałoby to kolejnych dziewięciu przełączników i dziewięciu zdarzeń. W tej metodzie ograniczeniem jest po prostu miejsce na kolejne zdarzenia na ekranie.

W drugą stronę lekko modyfikując moglibyśmy też ograniczyć możliwości z dziewięciu do np. sześciu. Dziewięć możliwości wydaje się trochę za dużo, więc jest to pewnie bardziej przydatne niż dodawanie ich więcej. Można to zrobić prosto, nie losując na początku drugiego przedmiotu i ograniczyć się tylko do dwóch stron w kolejnym losowaniu. Również np. losując znów tylko jeden przedmiot w tym kolejnym losowaniu możemy zejść do czterech możliwości. Widać więc, że gdy trochę pomyślimy, to jesteśmy w stanie dać ich taką liczbę, jaka jest nam aktualnie potrzebna. Choć nie gwarantuję, że zawsze uda nam się uzyskać ich równe prawdopodobieństwo.

Należy też pamiętać, że im więcej możliwości, im więcej pięter warunków, tym dłużej będzie trwało wykonanie naszego kodu. RM95 jest tak zbudowany, że każdorazowe sprawdzenie warunków kosztuje nas jedną klatkę gry. W przykładzie z dziewięcioma możliwościami tekst pokazuje się więc o dwie klatki później, niż standardowy tekst NPC bez żadnego losowania. Jest to więc tu pomijalne, ale należy pamiętać, że każde kolejne losowanie doda nam klatkę opóźnienia. W skrajnych przypadkach warto więc zablokować ruch bohatera na początku i odblokować na końcu. Tu tego nie robiłem, bo uznałem to za zbędne, ale można to dodać, nie zaszkodzi. Zresztą mocno testując możecie obrócić bohatera zanim tekst się wyświetli. Więc gdyby trzeba na ten tekst czekać powyżej czterech klatek, to warto go zablokować, bo w takim przypadku wyświetli się on w połowie kroku. Z tego też powodu przedmioty, które losujemy, musimy ustawić na rodzaj Specjal, tak aby gracz nie mógł ich zużyć, jeśli wejdzie do menu między losowaniem, a wykonaniem się wyników. Poza samym skryptem przedmioty nie będą widoczne w plecaku, więc jest to też metoda niewpływająca na odczucia z gry przez zaśmiecanie plecaka pustymi systemowymi przedmiotami.

Warto też zauważyć, że w ostatecznej wersji u naszego NPC na mapie wciąż mamy do dyspozycji dwie strony. Specjalnie umieściłem stronę, która naprawia obrót, na samym końcu, bo umożliwia nam to jej wykorzystanie z innymi dialogami, które będą startować na np. drugiej stronie, gdy fabularnie gra zmusi NPC do wypowiadania innych kwestii. Dlatego rozbicie skryptu na kilka zdarzeń poza większą ilością losowań ma również i ten plus. Warto to też robić, gdy nawet mieścimy się w tych trzech opcjach. Jedynym problemem jest to, że, gdy zdarzenie będzie mogło się poruszać po większej mapie, to będziemy musieli utworzyć siatkę ze zdarzeń, które do niego się odwołują, aby zawsze dokładnie jedno z nich było widoczne na ekranie.

Słowo na koniec

Tym razem to by było na tyle. Poniżej jest demo skryptu do pobrania, jak ktoś chce podejrzeć go w samym programie.

Jak widać, da się w RM95 dość prosto zrobić losowanie, które w grze nie wymaga jakichś specjalnych operacji od strony gracza. Skrypt co prawda pokazuje tu przykład z tekstami NPC, ale taki sam można wykorzystać na inne losowe sytuacje w grze – jak np. zepsuta kula teleportacji, która przenosi nas w losowe miejsce, czy losowe postacie w drużynie. Może też posłużyć jako część większego skryptu wymagającego losowania, jak własny system walki. Ogólnie dużo możliwości, których na pierwszy rzut oka RM95 zdawał się być pozbawiony.

W razie problemów i sugestii komentarze są Wasze.

Dragon Kamillo

– Download przykładowego projektu –

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

Ta strona używa Akismet do redukcji spamu. Dowiedz się, w jaki sposób przetwarzane są dane Twoich komentarzy.