[PNS] Jak stworzyć własną, interaktywną stację pasażerską?

W poprzednim poradniku z serii opisałem, jak korzystać z gotowego zestawu Polskich niewidzialnych stacji. Wiemy stamtąd, że z jednej strony warto umieszczać wielotorowe interaktywne stacje pasażerskie na naszych trasach, a z drugiej, że nie da się stworzyć jednego, uniwersalnego dodatku, który dałby radę obsłużyć wszystkie możliwe układy torowe i kombinacje peronów spotykane na kolei. Dlatego w tym poradniku pokażę, jak zbudować własną niewidzialną stację pasażerską korzystającą z gotowej biblioteki skryptów “Universal Invisible Station scripting library”.

Co będzie potrzebne?

Do stworzenia własnego dodatku będziemy potrzebować następujących narzędzi:

Dodatkowo, przyda się nam podstawowa znajomość kilku narzędzi:

  • podstawy korzystania z Blendera (poruszanie się w programie, umieszczanie punktów oraz prostokątów)
  • podstawy tworzenia dodatków do Trainz – struktura katalogów, instalowanie dodatku oraz o co chodzi z plikiem config.txt

Normalnie stworzenie interaktywnej stacji pasażerskiej wymaga jeszcze znajomości programowania oraz języka programowania TrainzScript, jednak tutaj skorzystamy ze wspomnianej wyżej biblioteki. Dzięki temu nie musimy umieć programować, bo cała skryptologia jest już gotowa.

Anatomia interaktywnej stacji w Trainz

Interaktywna stacja pasażerska w Trainz to dodatek typu “Scenery”, w którym – oprócz standardowego modelu 3D – umieszczone są specjalne punkty zaczepienia do torów oraz punkty, w których gra wyświetlać będzie oczekujących pasażerów. Dodatkowe skrypty zajmują się obsługą zatrzymywania pociągów, wsiadania i wysiadania pasażerów itd.

Do wyboru mamy dwie drogi: albo tworzymy pełny model 3D ze wszystkimi peronami, infrastrukturą, teksturami itd., albo tzw. “niewidzialną stację” zawierającą wyłącznie punkty zaczepienia torów i pasażerów. W tym drugim podejściu wszelką infrastrukturę peronową będziemy składać z innych dodatków już w Geodecie. W tym poradniku skupimy się na tym drugim podejściu.

Oto, jak taka interaktywna stacja wygląda w Blenderze:

Wszystko sprowadza się do umieszczenia mnóstwa punkcików, nazwania ich w odpowiedni sposób i… wpisania informacji o nich do pliku config.txt.

Kilka decyzji na początek

Na start musimy określić, co chcemy stworzyć:

  • ile torów ma mieć nasza stacja,
  • ile peronów,
  • jakiej długości, jakie odstępy między torami,
  • czy będą łuki i o jakich parametrach,
  • jaka ma być wysokość peronów?

Jeśli odwzorowujemy rzeczywistą stację, spróbujmy zmierzyć te wartości np. w Geoportalu albo Google Earth Pro i rozrysujmy sobie najpierw wszystko na kartce. Ułatwi to nam późniejsze prace.

Od strony technicznej musimy również podjąć decyzję, jak gęsto w naszym modelu mają być rozmieszczone punkty zatrzymania pociągów. Są to specjalne miejsca używane przez skrypt do zatrzymania pociągu. Gdy pociąg wjeżdża na stację, skrypt oblicza jego długość i na tej podstawie stara się wybrać, na którym punkcie powinna zatrzymać się lokomotywa. Ja stosuję odległość co 50 metrów.

Ważne: skrypt uniwersalnych stacji wymaga, aby odległości między punktami zatrzymania na danym torze były jednakowe.

Model 3D: punkty zaczepienia torów

Zacznijmy od stworzenia punktów zaczepienia torów. W Blenderze są to obiekty typu “Empty”, które znajdziemy w menu Object mode > Add > Empty > Arrows.

Najlepiej zorientować stację tak, aby tory biegły wzdłuż osi X, która w Blenderze ma kolor czerwony. Pozwoli to nam później dodać możliwość przechylania stacji w klasycznym Geodecie, która wymaga tam specjalnej konfiguracji (nadchodzący Geodeta 2.0 nie ma tego ograniczenia).

Jeśli chodzi o samo rozmieszczenie punktów, to Trainz rozróżnia między punktami zaczepienia torów, służącymi wyłącznie do rysowania torowiska, oraz tzw. “wyzwalaczami” (ang. trigger), które wykrywają przyjazd pociągu i powiadamiają o tym skrypt. To od nas zależy czy ustawimy sobie w Blenderze oddzielne punkty dla obu tych ról, czy też wykorzystamy jeden punkt do dwóch rzeczy. Poniżej przedstawię teraz kilka zasad ich stawiania:

Punkty zaczepienia torów

Nie mają one znaczenia dla skryptu niewidzialnych stacji – muszą jedynie być w modelu i oraz być skonfigurowane w config.txt (o tym dalej) tak, aby na naszej stacji pojawił się jakiś tor :). Umieszczamy po prostu kilka punktów (minimum 3) w osi toru i nazywamy wg konwencji a.trackCOŚTAM – ważne, żebyśmy się sami połapali w naszym systemie. Jeśli punkty zostaną ułożone wzdłuż jednej prostej, gra narysuje nam prosty odcinek. Jeśli nie – zacznie rysować łuki. Mechanizm osadzania torów w dodatkach scenerii nosi nazwę “FixedTrack”.

Uwaga: w Geodecie mamy narzędzie do prostowania odcinka toru, które pozwala robić ładne proste przechodzące w łuki. W mechaniźmie “FixedTrack” czegoś takiego nie ma. Jeśli na stacji chcemy mieć odcinek prosty przechodzący w łuk, musimy niestety w miejscu przejścia ustawić sporo dodatkowych punktów aby “mniej więcej” wyglądało to w grze poprawnie. Sensownie wyglądająca kombinacja to:

  • na prostym odcinku toru, 5 metrów za punktem przejścia prostej w łuk stawiamy punkt pomocniczy,
  • na łuku stawiamy punkty w regularnych odstępach np. co 10, 15 lub 20 metrów

Punkty w Blenderze można obracać. Dla Trainza znaczenie ma tylko kierunek obrotu dwóch skrajnych punktów, których oś “Y” musi wskazywać “na zewnątrz” toru. Punktów wewnętrznych nie musimy obracać.

Punkty wyzwalaczy

Te punkty są istotne dla skryptu niewidzialnych stacji, który używa ich do wyznaczenia miejsca zatrzymania pociągu. Dlatego musimy przestrzegać kilku zasad przy ich wstawianiu:

  • każdy tor musi mieć swój unikalny numer ID (nie chodzi tu o numery stosowane na kolei, tylko o numer, po którym skrypt odróżni od siebie poszczególne tory),
  • punkt umieszczony centralnie w środku toru musi zawsze nazywać się a.trigger_track_IDTORU_mid , gdzie IDTORU zastępujemy numerem ID toru,
  • punkty rozchodzące się w obu kierunkach muszą mieć nazwy:
    • dla kierunku A: a.trigger_track_IDTORU_e1_NRPUNKTU
    • dla kierunku B: a.trigger_track_IDTORU_e2_NRPUNKTU
  • ważne: tak trochę nieintuicyjnie, numery punktów muszą rosnąć od krańców stacji ku środkowi! Czyli to skrajne punkty będą mieć zawsze numer 1 i rosnąć aż do punktu mid.
  • tak jak wspomnieliśmy wcześniej, musimy zachować jednakową odległość między wszystkimi wyzwalaczami (np. 50 metrów). Nie chodzi o odległość w linii prostej, tylko po osi przebiegu toru, co jest ważne na łukach.

Przykład nazewnictwa wyzwalaczy dla pojedynczego toru na stacji:

  • a.trigger_track_1_e1_1
  • a.trigger_track_1_e1_2
  • a.trigger_track_1_mid
  • a.trigger_track_1_e2_2
  • a.trigger_track_1_e2_1

Jako wyzwalacze możemy wykorzystać te same punkty, których użyjemy do zaczepienia torów. Polecam to rozwiązanie, kiedy nasz tor jest idealnie prosty. Jeśli mamy łuki, lepiej dla wyzwalaczy zrobić oddzielne punkty, aby wymóg umieszczania ich w równych odstępach nie psuł geometrii toru. W takim wypadku punkt musimy umieścić blisko osi toru, który narysuje Trainz. Dopuszczalna domyślna tolerancja błędu wynosi 10 cm (można ją zmieniać w config.txt, ale niekoniecznie warto), inaczej Trainz nie będzie w stanie prawidłowo połączyć wyzwalacza z torem.

Model 3D: pasażerowie

Przed nami najbardziej żmudna część, czyli wstawianie pasażerów. Analogicznie, jak powyżej, tworzymy obiekty “Empty”, które ustawiamy w miejscach, gdzie gra ma wyświetlać pasażerów. Niestety musimy ich nawstawiać setki dla każdego toru! Potrzebujemy dwie grupy obiektów nazwane wg poniższego wzoru:

  • a.passonXX_tY – pasażer XX przy torze Y oczekujący na pociąg
  • a.passoffXX_tY – pasażer YY przy torze Y wysiadający z pociągu

Pierwszy rodzaj punktów powinien być obrócony w kierunku toru (czekanie na pociąg), drugi “plecami” do toru. Punkty ustawiamy na wysokości, na jakiej znajduje się peron i najlepiej tak, by pasażerowie nie stali w “strefie bezpieczeństwa” toru. Jeśli chcemy, by nasz tor (pojedynczy tor, nie cała stacja) wspierał np. do 100 pasażerów, musimy umieścić po 100 punktów obu rodzajów przesuniętych jakoś względem siebie, aby pasażerowie nie przenikali się.

Model 3D: numery torów/peronów

Kolejny krok to ustawienie punktów zaczepienia na wyświetlenie numerów peronów oraz torów – oryginalne skrypty Trainz tego nie wymagają, ale skrypt “Universal invisible station” już tak.

Tutaj dla każdego peronu musimy zrobić trzy punkty:

  • a.platformshield_IDPERONU – wyświetlenie “tarczy”
  • a.platformshield_fr_IDPERONU – wyświetlenie numeru w kierunku A
  • a.platformshield_rev_IDPERONU – wyświetlenie numeru w kierunku B

Analogicznie, dla torów robimy:

  • a.trackshield_IDTORU – wyświetlenie “tarczy”
  • a.trackshield_fr_IDTORU – wyświetlenie numeru w kierunku A
  • a.trackshield_rev_IDTORU – wyświetlenie numeru w kierunku B

Tutaj ważne jest, aby tym razem to oś Y wskazywała do góry oraz by punkty “fr” i “rev” były skierowane w odwrotnych kierunkach. Inaczej tarcze i napisy wyświetlą się np. bokiem, do góry lub tylko po jednej stronie tarczy.

Model 3D: prostokąty pod torami

Warto też wstawić pod każdym z torów zwykły prostokąt obniżony o jakieś 30 cm w stosunku do punktów zaczepienia torów, widoczny na wcześniejszym screenie. Dlaczego? Jeśli nasz model będzie składać się z samych punktów, Trainz będzie mieć problem z wyliczeniem rozmiarów naszej stacji, a tam samym wyświetlania jej z większej odległości. Bez przynajmniej jednego “widzialnego” prostokąta gra uzna, że stacja ma wymiary 0 na 0 metrów i np. pasażerowie pojawią się w polu widzenia dopiero gdy nasz pociąg będzie 5 metrów od peronu :). Te prostokąty i tak schowają się pod terenem, więc wizualnie na nic nie wpływają, ale ich obecność ma kolosalne znaczenie dla renderera grafiki w Trainz.

Prostokątowi ustawiamy materiał, który nazywamy sobie “track.m.notex” (ta nazwa jest ważna) i w ustawieniach domyślnego shadera Principled BSDF wybieramy jakiś fajny kolor :). Reszta opcji nas nie interesuje.

Model 3D: inne dodatki

Jeśli nie zmęczyło nas ustawianie punktów, możemy dodać ich jeszcze więcej :). Nie są one potrzebne do działania skryptu, ale pozwolą dodać nieco “pomocy naukowych”, np. rogi peronów, punkty zatrzymania pociągu, czy zrobić linijki. Robimy je tak samo, jak wyżej: po prostu wstawiamy obiekty typu Empty do naszego modelu w odpowiednich miejscach, odpowiednio obrócone i jakoś je sobie nazywamy. Tu nazwa nie ma znaczenia, ważne byśmy pamiętali, co jak się nazywa, byśmy sami się w tym nie pogubili. Pamiętajmy, aby wszelkim pomocom naukowym ustawić opcję surveyor-only na 1 tak, aby wyświetlały się one tylko w trybie Geodety.

Eksportowanie modelu 3D

Teraz kluczowa rzecz: eksport modelu do formatu FBX. Czeka nas tutaj przy okazji jeszcze jedna decyzja, mianowicie czy chcemy mieć regulację wysokości peronu czy nie. Jeśli tak, musimy wyeksportować punkty do dwóch plików FBX:

  • station.fbx – punkty, których wysokość ma się nie zmieniać (punkty zaczepienia torów, wyzwalacze, tarcze z numerami peronów)
  • platform.fbx – punkty podlegające regulacji wysokości (pasażerowie, znaczniki peronu itd.)

Jeśli nie chcemy mieć regulacji wysokości, wszystkie stworzone punkty eksportujemy do station.fbx i zapominamy o drugim pliku.

Sam eksport jest prosty. Zaznaczamy punkty i inne obiekty, które chcemy wyeksportować, po czym wchodzimy do menu File > Export > FBX. W oknie dialogowym ustawiamy wszystkie opcje wg poniższego wzoru i zapisujemy plik:

Plik config.txt

Ostatnim krokiem jest przygotowanie pliku config.txt. Nie będę tu omawiać wszystkich możliwych opcji, lecz tylko te, które są konieczne do działania naszej stacji, bo jest ich trochę. Wszystko sprowadza się do tego, że umieściliśmy w modelu 3D mnóstwo punkcików, a teraz musimy powiedzieć Trainzowi, do czego każdy z nich służy.

 Zaczynamy od dodania zależności do naszej biblioteki:

script-include-table {

    invisible_station_lib    <kuid2:160530:31900:3>

}

script            „station.gs”

class             „ActualStation”

Następnie ustawiamy kilka opcji, które pozwolą podnosić i przechylać całą stację w klasycznym Geodecie. Właśnie z uwagi na to pochylanie warto, aby tory na stacji ułożyć wzdłuż osi X, ponieważ klasyczny Geodeta wykorzystuje wyłącznie oś Y do przechylania dodatków i inaczej moglibyśmy jedynie kołysać naszą stacją na boki, zamiast zrobić nachylony tor. Nadchodzący Geodeta 2.0 likwiduje to ograniczenie. Tam można wszystkie obiekty dowolnie obracać i przesuwać wzdłuż wszystkich osi. Jednak do pojawienia się nowego Geodety w “pudełkowej” wersji gry upłynie jeszcze trochę czasu, dlatego warto zadbać o względny komfort pracy w dotychczasowym narzędziu. Oto te opcje:

height-range      -10,10

rotate-yz-range   -3,3

rollstep          0.1

Dodajmy teraz konfigurację torów i peronów, z której będzie korzystać biblioteka skryptów. Oto przykład dla stacji dwutorowej z jednym peronem:

extensions {

  universal-invisible-station-160530 {

    beta           0

    debug          0

    adjust-height  1

    rulers-present 1

    platforms {

      0 {

        id              1

        length-info     200

        height-info     „760mm”

        width-info      „6,2m”

        tracks {

          0 {

            id              1

            orientation     „R”

            length          200

            stop-distances  50

          }

          1 {

            id              2

            orientation     „L”

            length          200

            stop-distances  50

          }

        }

      }

    }

  }

}

Objaśnienie opcji:

  • beta – używamy “1” tylko dla dodatków w fazie testów, aby wyświetlić ostrzeżenie, że jest to wersja beta. Dla ukończonych dodatków zmieniamy wartość na 0.
  • debug – służy do wyświetlania dodatkowych komunikatów diagnostycznych w logach i usuwania błędów. Ukończone dodatki powinny mieć tu zawsze wartość 0, aby nie spamować użytkowników.
  • adjust-height – ustawiamy na “1”, jeśli chcemy regulację peronów i mamy dodatkowy model platform.fbx
  • rulers-present – ustawiamy na “1”, jeśli nasz dodatek wykorzystuje linijkę odstępu do torów. Opcja ta powoduje wyświetlenie dodatkowego tekstu pomocy dotyczącego linijki we właściwościach obiektu.
  • platforms – wymieniamy wszystkie perony,
  • platforms.id – unikalny numer ID peronu; ten sam, którego używamy w modelu 3D,
  • platforms.length-info, width-info oraz height-info – pomocnicze informacje dla użytkownika wyświetlane we właściwościach obiektu, które informują go o tym, jaka jest długość, szerokość i wysokość danego peronu.
  • platforms.tracks – jeden lub dwa tory znajdujące się przy danym peronie.
  • platforms.tracks.id – unikalny numer ID toru; ten sam, którego używamy w modelu 3D,
  • platforms.tracks.orientation – wartość “L” lub “R” określa, po której stronie mają otwierać się drzwi wagonów,
  • platforms.tracks.length – długość toru w metrach, używana do obliczania miejsca zatrzymania pociągu
  • platforms.tracks.stop-distances – odległość między punktami zatrzymania (naszymi wyzwalaczami) w metrach, używana do obliczania miejsca zatrzymania pociągu.

Następnie przychodzi kolej na podpięcie naszego modelu 3D. Tu też mówimy, co ma się wyświetlić w części naszych punktów zaczepienia.

mesh-table {

  default {

    mesh              „station.trainzmesh”

    auto-create       1

    lod-level         0

    effects {

      trackshield_1 {

        kind            „attachment”

        att             „a.trackshield_1”

        default-mesh    <kuid2:160530:31904:3>

      }

      trackshield_name_fr_1 {

        kind            „name”

        name            „trackshield_name_fr_1”

        att             „a.trackshield_fr_1”

        fontsize        0.2

        fontcolor       255,255,255

      }

      trackshield_name_rev_1 {

        kind            „name”

        name            „trackshield_name_rev_1”

        att             „a.trackshield_rev_1”

        fontsize        0.2

        fontcolor       255,255,255

      }

      platformshield_1 {

        kind            „attachment”

        att             „a.platformshield_1”

        default-mesh    <kuid2:160530:31905:3>

      }

      platformshield_name_fr_1 {

        kind            „name”

        name            „platformshield_name_fr_1”

        att             „a.platformshield_fr_1”

        fontsize        0.2

        fontcolor       255,255,255

      }

      platformshield_name_rev_1 {

        kind            „name”

        name            „platformshield_name_rev_1”

        att             „a.platformshield_rev_1”

        fontsize        0.2

        fontcolor       255,255,255

      }

  }

  platform {

    mesh              „platform.trainzmesh”

    auto-create       1

    lod-level         0

    effects {

    }

  }

}

Na powyższym przykładzie widzimy, w jaki sposób podpiąć tarcze z numerami peronów. Każdy wpis w sekcji “effects” to jeden punkt zaczepienia. Sekcję “platform” usuwamy, jeśli nie korzystamy z regulacji wysokości peronów. Jeżeli mamy jakieś dodatkowe punkty pomocnicze typu linijka, rogi peronów, to także wpisujemy je w sekcji “effects” i podpinamy dodatki:

  • <kuid2:160530:31901:3> – znak “stop” wskazujący na miejsce zatrzymania składu
  • <kuid2:160530:31902:3> – róg peronu
  • <kuid2:160530:31903:3> – linijka

Kolejnym krokiem jest ustawienie maksymalnej odległości rysowania (np. na 1000 metrów) oraz podpięcie torów pod punkty ich zaczepienia:

mesh-table-lod-transition-distances      1000

attached-track {

  track_1 {

    track                 <kuid:-1:15>

    vertices {

      0                   „a.trigger_track_1_e1_1”

      1                   „a.trigger_track_1_e1_2”

      2                   „a.trigger_track_1_mid”

      3                   „a.trigger_track_1_e2_2”

      4                   „a.trigger_track_1_e2_1”

    }

  }

  track_2 {

    track                 <kuid:-1:15>

    vertices {

      0                   „a.trigger_track_2_e1_1”

      1                   „a.trigger_track_2_e1_2”

      2                   „a.trigger_track_2_mid”

      3                   „a.trigger_track_2_e2_2”

      4                   „a.trigger_track_2_e2_1”

    }

  }

}

W powyższym przykładzie moje punkty zaczepienia są równocześnie wyzwalaczami. Jeśli zastosowaliśmy oddzielny zestaw punktów dla wyznaczenia geometrii toru, wpisujemy tutaj oczywiście nazwy tamtych punktów.

Wszystkie wyzwalacze podłączamy w sekcji attached-trigger wg poniższego schematu:

attached-trigger {

  trigger_track_1_e1_1 {

    att                   „a.trigger_track_1_e1_1”

    radius                30

    track                 „track_1”

  }

  trigger_track_1_e1_2 {

    att                   „a.trigger_track_1_e1_2”

    radius                25

    track                 „track_1”

  }

}

W polu track wpisujemy nazwę naszego toru z poprzedniej sekcji attached-track. Pole radius to promień okręgu, w obrębie którego wyzwalacz będzie wykrywać nadjeżdżający pociąg i powiadomi nasz skrypt. Zalecam, aby promienie wyzwalaczy nie pokrywały się, a jednocześnie nie były zbyt małe. Pociąg rozpocznie bowiem hamowanie dopiero w momencie jego wykrycia i dostania sygnału ze skryptu, że “już można”. Jeśli wpiszemy zbyt mały promień, hamowanie rozpocznie się zbyt późno i pociąg przestrzeli punkt. W att natomiast podajemy nazwę punktu z modelu 3D.

Wypełnianie pliku config.txt dobiega powoli końca. Przed nami dwie ostatnie kluczowe sekcje: queues oraz processes, których gra używa do sterowania procesem wymiany pasażerów. Dla każdego toru musimy zdefiniować dwie tzw. kolejki w sekcji queues: passengers_on_NR oraz passengers_off_NR, gdzie “NR” to numery kolejnych torów zaczynając od zera. Nazwa jest ważna, dlatego trzymamy się wzoru. A tak to wygląda:

queues {

  passengers_on_0 {

    passenger-queue            „1”

    size                       200

    initial-count              3

    product-kuid               <kuid:-3:10060>

    attachment-points {

      0           „a.passon0_t1”

      1           „a.passon1_t1”

      2           „a.passon2_t1”

      …

    }

  }

  passengers_off_0 {

    passenger-queue            „1”

    size                       200

    initial-count              3

    product-kuid               <kuid:-3:10060>

    attachment-points {

      0           „a.passoff0_t1”

      1           „a.passoff1_t1”

      2           „a.passoff2_t1”

      …

    }

  }

}

W miejsce trzech kropek wpisujemy absolutnie wszystkie punkty pasażerów, jakie zdefiniowaliśmy w modelu 3D dla danego toru! Przypominam: jak masz jeden tor, potrzebujesz dwóch kolejek. Jak dwa tory, to czterech. Jak cztery tory, to ośmiu itd. I w każdej z nich wpisujesz wszystkie attachment-points dla tego toru. Jest to żmudne, ale nie do pominięcia. Wypełniamy też pole size, gdzie wpisujemy, ile tych punktów w każdej kolejce jest.

Musimy też podpiąć w/w kolejki do procesów, co robimy w sekcji processes:

processes {

  passenger_spawn_0 {

    start-enabled               1

    duration                    20

    outputs {

      0 {

        amount                  1

        queue                   „passengers_on_0”

      }

    }

  }

  passenger_delete_0 {

    start-enabled               1

    duration                    3

    outputs {

      0 {

        amount                  1

        queue                   „passengers_off_0”

      }

    }

  }

}

Analogicznie jak wcześniej – dla każdego toru w sekcji processes umieszczamy po dwa wpisy: passenger_spawn_NR oraz passenger_delete_NR.

I to już prawie koniec. Pamiętamy o dodaniu wszystkich standardowych opcji takich, jak opisy, licencja, miniaturka (“thumbnails”) itd., a także o wypisaniu wszystkich zależności w sekcji kuid-table:

kuid-table {

  passenger              <kuid:-3:10060>

  1_track_wood           <kuid:-1:15>

  invisible_station_lib  <kuid2:160530:31900:3>

  helper_stop            <kuid2:160530:31901:3>

  helper_corner          <kuid2:160530:31902:3>

  helper_ruler           <kuid2:160530:31903:3>

  helper_track_shield    <kuid2:160530:31904:3>

  helper_platform_shield <kuid2:160530:31905:3>

}

Uff… i gotowe!

Coś jeszcze?

Tak, ale na szczęście już niewiele i bez kombinowania. Musimy dodać do katalogu z dodatkiem pliczek station.gs o następującej treści:

include „universalinvisiblestation.gs”

class ActualStation isclass UniversalInvisibleStation {

};

I to wszystko. Jest to konieczne, aby skrypt zaczął działać, natomiast nie trzeba nic tutaj zmieniać. Wklejamy kod tak-jak-jest.

Końcowe testy

Mając wszystkie pliki w jednym katalogu, możemy przeciągnąć katalog do “Content Managera” w Trainz. Spowoduje to zainstalowanie naszego dodatku, a my będziemy mogli przetestować go w grze. Pamiętaj by sprawdzić czy wszystko dobrze się wyświetla, a także czy pociągi AI prawidłowo zatrzymują się przy peronie.

Gdyby przy imporcie pojawiły się jakieś błędy, należy zapoznać się z numerem błędu i treścią komunikatu w dokumentacji Trainza i poprawić dany błąd. Kilka najczęstszych problemów:

  • błędne nazewnictwo punktów/modeli/materiałów wewnątrz modelu 3D,
  • zapomnieliśmy zaznaczyć punkty i obiekty przed eksportem i w efekcie stworzyliśmy pusty model 3D,
  • odwołanie do nieistniejącego punktu modelu w config.txt
  • niewłaściwe wartości opcji w config.txt

Błędy w sekcji extensions.universal-invisible-station-160530 wykryjemy niestety dopiero po wstawieniu dodatku na trasę. Warto w launcherze gry włączyć sobie opcję Developer > Show logs, aby widzieć komunikaty ze skryptu. Upewnij się, że wszystkie wartości masz wpisane poprawnie i że mają one odpowiednie typy. Jeśli skrypt spodziewa się w opcji wartości liczbowej, musi być tam liczba. Jeśli tekst, to tekst. Po raz kolejny podkreślam, że nazewnictwo elementów musi się dokładnie zgadzać z tym, czego oczekuje skrypt.

Podsumowanie

Jak widać, stworzenie dodatku interaktywnej stacji polega na umieszczeniu punktów w modelu 3D, nazwaniu ich w odpowiedni sposób i powiedzeniu Trainzowi w pliku config.txt, do czego one służą. Żmudnym elementem jest oczywiście dodawanie wszystkich pasażerów, ale i to da się obejść, np. poprzez postawienie punktów na małym fragmencie, a potem ich powielanie poprzez kopiuj-wklej. Biblioteka niewidzialnych stacji eliminuje całkowicie konieczność programowania, które wcześniej było niezbędne do stworzenia własnego skryptu obsługi stacji. W efekcie zyskujesz dobrze oprogramowany dodatek dostosowany do Twoich własnych potrzeb.

Niektórzy mogą zapytać, jak wygląda kwestia licencyjna w sytuacji, gdy skorzystaliśmy z w/w biblioteki. Sprawa jest prosta – Twój dodatek to Twój dodatek, możesz z nim robić, co zechcesz i rozpowszechniać tak, jak chcesz. Jedyne ograniczenie dotyczy samej biblioteki. Nie możesz jej zapakować razem z Twoim dodatkiem, ani rozpowszechniać np. poprzez własną stronę internetową – biblioteka oraz potrzebne dodatki pomocnicze (tarcze, linijki itd.) musi być pobierana z DLS-a. Jej rozmiar jest niewielki i nie powinien sprawić problemu nikomu nawet bez wykupionego First Class Ticket. Wyjątek jest zrobiony dla tras freeware (i tylko dla nich) – w tym wypadku bibliotekę w niezmienionej formie można dodać do paczki wsporczej. W każdym innym przypadku należy ściągać ją z DLS. Osobiście fanem paczek wsporczych nie jestem, ale nie zamierzam blokować tej drogi, jeśli ktoś bardzo chce taką paczkę dla swojej trasy freeware stworzyć. Szczegóły znajdziemy w sekcji “license” w samej bibliotece i tam odsyłam po dokładne warunki korzystania. W katalogu z biblioteką znajduje się też dokument readme.txt w języku polskim i angielskim opisujący wiele aspektów przedstawionych w tym artykule.

Mam nadzieję, że artykuł ten rozjaśnił Wam tajniki tworzenia własnych interaktywnych stacji. Życzę Wam wielu nowych, wspaniałych tras i mam nadzieję, że dedykowane interaktywne stacje to krok w tym kierunku.

Tutorial autorstwa zyxist’a (DLS: ZyxwvU)


One Response

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *