środa, 22 marca 2017

Walka - typy jednostek i ataków

Cześć Wam!

Dzisiaj będzie o typach jednostek i obrażeń, które pojawią się w Przywoływaczach. Jak już wspomniałem wcześniej będzie ich piętnaście.

Poniżej lista typów z krótkim opisem:

  • Ogień - Wszystkie istoty czy ataki związane z żywiołem ognia, wysokimi temperaturami. Ten typ będą miały salamandry, ifryty czy płonące strzały.
  • Woda - Ten typ przypiszemy jednostkom i atakom związanym z wodą, wilgocią. Tu przypadną syreny czy przywołanie deszczu.
  • Ziemia - Wszystko związane z ziemią, skałami i metalami. Tu przypadną górskie trolle, krasnoludy czy ruchome piaski.
  • Powietrze - Tu znajdziemy istoty, które większość życia spędzają ponad ziemią - ptaki, wróżki czy tornada.
  • Zimno - Tu przypadną stwory związane z mrozem czy lodem, chociażby polarne zwierzęta, zamiecie śnieżne, może nawet Buka? ;)
  • Natura - Wszystkie istoty żyjące w symbiozie z przyrodą, przykładowo elfy, drzewce, centaury.
  • Energia - Tu pojawią się istoty i ataki związane z czystą energią. Gdyby pikaczu należał do tego uniwersum przypadałby właśnie tutaj ;)
  • Magia - Tu spotkamy stworzenia, których żywot jest nierozerwalnie związany z mocami nadprzyrodzonymi, przykładowo Najpotężniejsi czarodzieje czy magiczne konstrukty.
  • Światło - Wszystkie istoty niebiańskie, jak anioły czy dobre duchy, znajdą się właśnie tutaj. 
  • Mrok - Tu przypadną wszelkie istoty potępione - różnorakie demony czy diabły.
  • Technologia - Wszystkie przejawy zaawansowanej techniki znajdą się tutaj. Szukając golemów czy mechów wiecie gdzie szukać.
  • Konstrukty - Tutaj znajdziemy wszelkie konstrukty jak trebusze, balisty czy inna broń oblężnicza.
  • Nieumarli - Jak łatwo się domyślić są to martwe istoty utrzymane przy "życiu" za pomocą mrocznej magii - zombie, szkielety czy lisze.
  • Trucizna - Wszystkie istoty związane z jadem, zarazą, skażeniem znajdą tu swoje miejsce. 
  • Zwykły - typ standardowy. Tu przypadną ludzie, zwierzęta, ataki bronią fizyczną.
Uff, jest tego trochę. Na szczęście nie muszę wdrażać wszystkiego od razu ;)

Znajomość wszystkich typów była mi jednak potrzebna do opracowania zależności pomiędzy nimi, tak by system był możliwie zbalansowany. Efekty możecie zobaczyć na obrazkach:



(Kliknij obrazek aby powiększyć)

Opracowując system zależności do Przywoływaczy zacząłem od analizy podobnego systemu w grach z serii Pokemon. Szybko się okazało, że jest on daleki od doskonałości, przynajmniej pod względem balansu rozgrywki. Łatwo można było wskazać typ, który był wyraźnie silniejszy lub słabszy niż większość. Takie rozwiązanie w mojej grze nie miało prawa się pojawić ;)

Znalezienie złotego środka pomiędzy balansem rozgrywki, pożądanym poziomem złożoności, a zdrowym rozsądkiem nie było takie proste, jednak wydaje mi się, że trafiłem całkiem blisko dziesiątki ;)

Co sądzicie o powyższym systemie? Może ktoś z Was ma pomysł na usprawnienie? Chętnie poczytam.

Dzięki za lekturę! Trzymajcie się!

wtorek, 21 marca 2017

Walka - wstęp

Cześć Wam!

Wybaczcie, że od kilku dni nie pisałem. Mam jednak nadzieję, że kolejne wpisy zrekompensują Wam to z nawiązką. Zajmiemy się bowiem częścią, która dla wielu będzie zapewne najciekawsza - systemem walki.

Walka w Przywoływaczach ma stanowić wyzwanie taktyczne, sukces ma zależeć od doboru odpowiednich jednostek przed starciem i wykorzystania właściwych umiejętności, zarówno postaci gracza jak i dowodzonych przez niego jednostek, podczas samej bitwy. Przy takich założeniach tryb turowy powinien się sprawdzić idealnie.

Bezpośrednio w walce będzie brało udział po sześć jednostek po każdej ze stron konfliktu. Będą ustawione w dwóch rzędach po trzy jednostki. Jednostki z tyłu mogą atakować tylko z dystansu, chyba że przedni rząd został już pokonany. Atakować wręcz można tylko jednostkę znajdującą się przed sobą lub po skosie, a tylny rząd dopiero po pokonaniu przedniego.

Jednostki będą należały do jednego z piętnastu typów oraz jednej z pięciu klas. Każdy z typów ma swoje mocne i słabe strony w walce z innymi typami, podobnie klasy dostają bonusy w walce z określonymi klasami.

Kolejność akcji na początku walki będzie zależała od szybkości jednostek. Mogą na nią wpływać różne modyfikatory wynikające z sytuacji przed bitwą.

Aktywne jednostki mogą wybrać jedną z posiadanych umiejętności do wykorzystania. Każda z nich ma czas potrzebny na przygotowanie. Kolejna tura jednostki zostaje przesunięta w linii czasu o tę wartość. Tura zaczyna się użyciem uprzednio wybranej umiejętności.

Przygotowanie może zostać przerwane - w takim przypadku jednostka, które przerwano zaczyna turę natychmiast po kolejce jednostki przerywającej.

Podczas walki postać gracza może co jakiś czas korzystać z posiadanych zdolności, jednak nie bierze bezpośredniego udziału w walce.

W najbardziej ogólnym przypadku walka kończy się, gdy wszystkie jednostki jednej ze stron zostaną pokonane.

Co sądzicie o takim systemie? Z jakimi grami się Wam kojarzy?

W następnym wpisie zamieszczę tabelę z zależnościami pomiędzy typami jednostek. 

Dzięki za lekturę!

poniedziałek, 13 marca 2017

Efekty cząsteczkowe - ogień

Cześć Wam!

Tym razem krótko ;)

Dzisiaj poeksperymentowałem sobie trochę z efektami w stylu low poly. Zacząłem od ognia, zrobiłem testowy płomień ogólny i zapaloną świeczkę. Jak wyszło możecie zobaczyć poniżej:

Widok w edytorze:


Widok z perspektywy gracza:


Jak Wam się podobają efekty?

Trzymajcie się!

PS. Dopiero następnego dnia zauważyłem, że w tle filmów nagrała się piosenka ;)

Jakby ktoś chciał posłuchać całości - RASPUTIN


niedziela, 12 marca 2017

Eksploracja - interakcja z przedmiotami - schemat v. 1

Cześć Wam!

Tak jak obiecałem publikuję pierwszą wersję schematu dziedziczenia klas związanych z interakcją z przedmiotami.




Obiekt interaktywny - obiekt, który zostaje użyty w momencie, gdy postać gracza znajdzie się w odpowiednim miejscu. Najprostszym przykładem będą pułapki, które zadziałają, gdy tylko postać stanie na zapadni czy płycie naciskowej.
Obiekt wymagający użycia - obiekt wymagający od gracza naciśnięcia przycisku. Prostym przykładem jest łóżko - jak jakieś znajdziemy, to możemy sobie uciąć drzemkę.
"Zamknięty" obiekt interaktywny - słowo zamknięty umieściłem w cudzysłowie, gdyż jest to skrót myślowy od stwierdzenia "Wymagający posiadania jakiegoś przedmiotu i / lub spełnienia określonego warunku". Chociażby otwarcie drzwi może wymagać posiadania odpowiedniego klucza lub łomu i niezłej krzepy.
Pojemnik - każdy przedmiot mogący zawierać coś, co gracz chciałby sobie pożyczyć. Przykładem niech będzie kufer, który po otwarciu kluczem, ukazuje wspaniały skarb.
Przedmiot "wyłączony" - ponownie skrót myślowy - może to być zarówno zgaszona pochodnia, nieaktywny portal czy wyłączony starożytny konstrukt. 

Te kategorie powinny pokrywać przedmioty interaktywne, które pojawią się w grze w najbliższym czasie. Nie mam wątpliwości, że powyższy schemat ewoluuje w trakcie rozwoju Przywoływaczy, gdy na światło dzienne wyjdą rzeczy, które teraz nie przychodzą mi do głowy.

W tej chwili mam jedno ale - weźmy na przykład regał z książkami. Jest to pojemnik, w którym gracz może poprzeglądać sobie dzieła literackie. Sensowne by było, gdyby dziedziczył po klasie "Pojemnik". Załóżmy jednak, że nasze regały zawsze będą otwarte, nie pojawią się wymagania, które postać powinna spełniać, by do nich zajrzeć. W tym przypadku nasz obiekt jest bardziej skomplikowany, niż mógłby być. Moglibyśmy zrobić klasę pojemnika zawsze otwartego, dziedziczącą bezpośrednio po Obiekcie wymagającym użycia, jednak w ten sposób dublowalibyśmy kod odpowiedzialny za przeszukiwanie pojemnika. Które wyjście jest bardziej, jak to się mówi, zgodne ze sztuką? 

A może znacie lepsze rozwiązanie?

Dzięki za lekturę i zapraszam do dyskusji!

czwartek, 9 marca 2017

Eksploracja - interakcja z przedmiotami - część 1.

Cześć Wam!

Możemy już pospacerować naszym bohaterem po okolicy, nadszedł więc czas, by trochę to podróżowanie urozmaicić.

Przedmiotów, z którymi będziemy mogli wejść w interakcję w grze będzie multum - skrzynie ze skarbami, półki z książkami, dźwignie, drzwi, łóżka, ogniska, magiczne kręgi, portale, leżące luzem przedmioty, ciała, itd. łatwo można by ciągnąć tę listę przez kolejnych kilka postów, ale konia z rzędem temu, komu chciałoby się to wszystko czytać.



Podanych przykładów wystarczy jednak, by zauważyć, że interakcje mogą być bardzo różnorodne. Mogłoby się wręcz wydawać, że niektóre nie mają ze sobą nic wspólnego. To może zagadka? Co łączy przechodzenie przez magiczny portal z rozpalaniem ogniska? 

Zanim przejdziecie dalej, spróbujcie poszukać podobieństw samodzielnie. Może nawet pokusicie się o zapisanie ich w komentarzach? Chętnie poczytam Wasze pomysły! :)

No dobra, czas na moje rozwiązanie.
  1. Obie te interakcje wymagają podejścia do obiektu, którego będzie ona dotyczyć.
  2. Obie mogą wymagać posiadania odpowiednich przedmiotów, np. drewna i rozpałki w przypadku ogniska lub odpowiedniego kamienia runicznego przy portalu.
  3. Obie interakcje mogą mieć fazę przygotowywania - rozmiecenie ognia i inkantacja.
  4. No i na koniec użycie właściwe, pieczenie kiełbasek i przeniesienie się w czasie i / lub przestrzeni.
Teoretycznie dla każdego rodzaju interakcji moglibyśmy przygotować osobny skrypt, który by ją opisywał, jednak skończyłoby się to bardzo dużą ilością linijek kodu w projekcie. A jak wiadomo nie ilość się liczy, a jakość.

W tym momencie możemy wszyscy podziękować twórcom programowania obiektowego, za cudowny mechanizm nazywany dziedziczeniem. W tym opisywanym zagadnieniu będziemy obficie z niego czerpać.

W tej chwili w projekcie możecie zobaczyć zupełnie podstawową implementację opisanej idei. Mamy ogólny skrypt dla obiektów interaktywnych, który sprawdza, czy postać gracza znalazła się w odpowiednim miejscu i skrypt skrzyni, dziedziczący po powyższym i dodający jej otwarcie.

W następnej notce postaram się przedstawić pierwszą wersję schematu dziedziczenia przedmiotów interaktywnych. Będzie on tylko na tyle rozbudowany, ile wymaga tego obecny, mocno prototypowy, sposób pracy.

Dzięki za lekturę i ponownie zachęcam do publikowania swoich rozwiązań w komentarzach :)

sobota, 4 marca 2017

Eksploracja - poruszanie się - część 1.

Cześć Wam!

Po opisanym wcześniej kryzysie udało się wrócić na z projektem na właściwe tory. Na GitHubie możecie już zobaczyć pierwsze skrypty, a w tym poście napiszę co nie co o ich powstaniu.

Na początek warto byłoby zadbać, by gracz miał jakąś postać i mógł ją widzieć. 

Zacznijmy więc od kamery. Standardowo wykorzystuje się kamerę pierwszo- lub trzecioosobową (Trochę zbaczając z tematu - jak miałaby wyglądać kamera drugoosobowa? Tak teoretycznie? Może poteoretyzuję sobie i popuszczę wodze fantazji w innej notce ;) ) Tak więc, którą wybrać?

Głównymi aktywnościami, na których ma się skupić gracz w Przywoływaczach są taktyczne walki, kolekcjonowanie i rozwijanie jednostek oraz eksploracja stworzonego świata. Priorytetem nie jest możliwe maksymalne wczucie się w postać, zobaczenie wydarzeń jej oczami, co może nam zagwarantować kamera pierwszoosobowa. W tym przypadku widok z zewnątrz powinien się sprawdzić lepiej.

Na tym nie koniec decyzji. Gdzie powinna być ulokowana kamera? Czy powinna podążać za postacią gracza, czy być od niej niezależna? Czy możemy ją obracać, przybliżać itd?

Kolejna sprawa - dobrze by było dać graczom możliwość sterowania postacią. Na początek poruszanie się. Tu też należy zastanowić się nad kilkoma kwestiami.

Czy będziemy kontrolować postać bezpośrednio, np. WSADem lub gałką kontrolera, czy może wskazywać jej, gdzie ma się udać kliknięciem myszy na mapie? Czy te dwa rozwiązania się wykluczają? Czy powinien móc biegać, skakać, kucać?

I dalej - w przypadku sterowania bezpośredniego - czy "przód" jest tam, gdzie zwrócona jest postać, czy kamera? Czy powinna obracać się płynnie czy natychmiast? Czy powinna zatrzymywać się w miejscu?

Niby najprostsze rzeczy, zwyczajne chodzenie, a tu już tyle decyzji do podjęcia!

W Przywoływaczach, w chwili powstawania tej notki, wygląda to tak:


Kamera znajduje się w tym samym obiekcie co postać gracza, oddalona o dziesięć metrów, zawsze skierowana w jego stronę. Jest umieszczona na dwóch pustych obiektach, jednym odpowiedzialnym za obracanie jej w poziomie i drugim za obracanie w pionie. Pozwala to uniknąć dziwnych przekręceń świata podczas poruszania kamerą w różne strony - horyzont zawsze pozostanie poziomy. Kamera obraca się niezależnie od postaci gracza.

Postać gracza może poruszać się w dowolnym kierunku. Przód jest skierowany zgodnie z widokiem kamery. Postać obraca się płynnie, a zatrzymuje praktycznie w miejscu.

Co będzie się działo dalej z poruszaniem?

Chcę dodać możliwość obsługi kamery przy pomocy klawiatury i myszki -  w tej chwili obraca się ją przy pomocy prawej gałki pada. Chcę dodać ograniczenia do ruchu kamery, żeby nie wchodziła w ściany czy pod podłogę. Chcę też dodać możliwość przybliżania i oddalania kamery. 

Chcę dodać możliwość biegania, skakania, kucania i skradania dla postaci. Te elementy znacznie urozmaicą nam eksplorowanie świata i pozwolą na dodanie bardziej różnorodnych wyzwań do tego elementu rozgrywki.

Chcę też zrefaktoryzować kod, by był możliwie najbardziej prosty, czytelny i łatwy do dalszego rozwijania. 

To wszystko ważne rzeczy, jednak nie są konieczne na tym etapie powstawania gry. Teraz najcenniejszy będzie dla nas działający prototyp, dzięki któremu zdobędziemy nową wiedzę, a ta pozwoli nam lepiej podejmować bardziej szczegółowe decyzje. 

Może się okazać, że część z już istniejących rzeczy trzeba będzie wyrzucić do kosza i zrobić zupełnie inaczej. Gdybyśmy już na początku poświęcili dużo wysiłku na dopieszczenie wszystkich mechanizmów, to byłoby tej pracy znacznie bardziej szkoda i moglibyśmy chcieć ją, wbrew dobru rozgrywki, zostawić niezmienioną.

Dzięki za lekturę i proszę o feedback - czy taka forma opisu powstających funkcjonalności Wam pasuje? Czy może jest zbyt mało / za bardzo szczegółowa? Będę wdzięczny za wszelkie uwagi!

Trzymajcie się ciepło!

piątek, 3 marca 2017

Dobre praktyki - repozytorium - częste commity

Cześć Wam,

Dzisiejsza notka będzie raczej krótka i ku przestrodze - opowiem Wam bajkę o tym, jak musiałem od nowa zakładać repozytorium.

Zaczęło się niewinnie. Jak zwykle utworzyłem nowy projekt w unity i założyłem repozytorium na GitHubie i lokalnie. Ściągnąłem kilka paczek assetów, z których już kilkakrotnie korzystałem, dodałem tez kilka nowych, które ostatnio wpadły mi w oko i chciałem je wypróbować w nowym projekcie. Po tym scommitowałem wszystko jako założenie projektu. Jeszcze nic nie zwiastowało katastrofy.

Utworzyłem nową scenę, dodałem postać gracza, kamerę, napisałem skrypty odnośnie poruszania kamerą i bohaterem (o tym miał być ten wpis, a patrzcie do czego doszło). Wszystko śmigało tak jak chciałem, super. Uwinąłem się przed północą.

Zapisałem wszystko, wyłączyłem edytor, już miałem commitować, ale przypomniałem sobie o jeszcze jednym drobiazgu, który chciałem zrobić. Otwieram ponownie Unity i co widzę? Różowość. Wściekle różowego bohatera gracza - wszystkie materiały zniknęły nie wiadomo gdzie.

Po godzinie eksperymentowania i kombinowania doszedłem do wniosku, że to jeden z nowych assetów gryzie się z już oswojonym. Najprościej byłoby cofnąć dodanie tej paczki, ale... no właśnie, wrzuciłem wszystkie jako jeden duży commit. Szlag. 

Uznałem, że szybciej będzie odtworzyć projekt, zrobić nowe repo i tym razem poprowadzić je porządnie. 

Mam to szczęście, że do nieszczęścia doszło na samym początku i nie straciłem wiele pracy. Już dwa tygodnie później rwałbym sobie włosy z głowy na takie wydarzenie.

Posypuje głowę popiołem i obiecuję commitować często i ładnie wszystko opisywać. Jakbym się nie wywiązywał, nie krępujcie się mnie zganić. I dbajcie o swoje repozytoria, dobrze pielęgnowane pomogą Wam wykaraskać się z nie lada kłopotów.

Dzięki za lekturę i trzymajcie się!