Anastasia Salter, Stuart Moulthrop

Karuzela

Twining - ćwiczenia

Do wykonania zadania potrzebny jest program Twine dostępny na stronach twinery.org. Komplet ćwiczeń oraz działających plików omówionych w książce Twining (w oryginale) znajduje się na stronach Gitbuba i zachęcamy do ich ściągnięcia. Niniejsze ćwiczenie znajduje się w folderze "One" i składają się na nie pliki "Twining1.3.html" oraz "Twining1.3.txt" Polska wersja ćwiczenia w formacie Twine Harlow jest do ściągnięcia poniżej.

W ćwiczeniu raz jeszcze korzystamy z silnika Harlowe, który oprócz makra (either:) używa innego smacznego makra o nazwie (live:). Podobnie jak odpowiadająca mu struktura w Chapbooku, modyfikator [afer], (live:) definiuje przedział czasowy między otwarciem fragmentu a dalszymi transformacjami. W Chapbooku jesteśmy ograniczeni do wyświetlania tekstu. Harlowe oferuje znacznie więcej, pozwalając na uruchomienie dowolnego innego makra po pewnym opóźnieniu czasowym. To samo dotyczy intrygującego makra (go-to:), którego odpowiednik w Chapbooku nie jest ani udokumentowany, ani też oficjalnie wspierany. Makro (go-to:) pozwala na kodowo zdefiniowane przejście z jednego pasażu do drugiego bez udziału gracza. W słodkim, precyzyjnie opartym na turach świecie Chapbooka byłoby to skandaliczne.

◊ Ten projekt składa się z pięciu małych części. Po rozpoczęciu nowej historii i ustawieniu jej formatu na Harlowe, możemy chcieć utworzyć wszystkie pięć fragmentów. Można je nazwać numerycznie, od “01" do "05". (Zera są tylko na pokaz, tak naprawdę zachęcamy nazywania swoich fragmentów jak nam się żywo podoba, pod warunkiem, że używamy prawidłowych, a zatem tych samych, nazw w swoich makrach (go-to:). Otwórzmy "01" i wprowadźmy, co następuje:

Pokój 01

Oko Imusa (kliknij: "Eye") [(set: $hasAmulet to false)]
(live: 2s)[
(if: $hasAmulet is false)[(go-to: "02")]
] (stop:)

Wszystkie nasze pokoje będą przestrzegać tego samego schematu. Będą zawierać przedmiot - w tym przypadku Oko Imusa. (Nie warto wgłębiać się, czym ono jest). W przypadku każdego z tych przedmiotów, jego główny rzeczownik będzie tematem makra (click:), które osadza specjalne hiperłącze na podanym słowie lub wyrażeniu. Po aktywacji link taki ustawia wartość zmiennej. Mówimy to z naciskiem, ponieważ jest to coś, czego nie można zrobić w Chapbooku, przynajmniej nie w tak bezpośredni sposób. Harlowe pozwala autorom na ustawianie i resetowanie wartości zmiennych w obrębie pjedynczego pasażu, niezależnie od przejść między pasażami. Oznacza to, że doświadczenie historia oparta na Harlowe - na przykład With Those We Love Alive Porpentine - potrafi zaprezentować większą ilość dynamicznych zdarzeń niż oferują to podstawowe funkcje Chapbooka. Jest tu więcej możliwości.

Ciekawostką jest, że działanie, które tu projektujemy ustawia wartość zmiennej typu Boolean, $hasAmulet, na false. (W Harlowe nazwy zmiennych zaczynają się od znaku dolara.) Można by oczekiwać, że kliknięcie na nazwę magicznego przedmiotu aktywuje ten przedmiot lub doda go do naszego inwentarza. Moglibyśmy to tak właśnie zaprojektować, ale tutaj interesuje nas sam amulet. Inne cztery przedmioty to MacGuffny.

Zwróćmy uwagę na makro (live:) poniżej linii "Amulet". Argument "2s" oznacza dwie sekundy. To jest czas, jaki dajemy graczowi w każdym z pasaży zawierającym wariant tego makra. Po dwóch sekundach wykonujemy test na $hasAmulet i jeśli jest on fałszywy, wykonujemy makro (go-to:) i przechodzimy do kolejnego o fragmentu (lub pokoju). W linijce końcowej widzimy makro (stop:). Kończy ono poprzedzające je makro (live:).

◊ Fragmenty 02, 04 i 05 są prawie identyczne z 01, więc napiszmy je za jednym zamachem. Następnie wrócimy do kluczowego fragmentu 03. Proszę otworzyć każdy fragment po kolei i wpisać poniższe fragmenty tekstu. Jedynymi zmianami w pasażach będą nazwy tajemniczych przedmiotów i fragmentów docelowych w makrach (go-to:).


Dla fragmentu 02

Pokój 02

Kamień z Blarney (click: "Kamień") [(set:
$hasAmulet to false)]
{(live: 2s)[
(if: $hasAmulet is false)[(go-to: "03")]
]
(stop:) }

Dla fragmentu 04

Pokój 04

Kielich Złości (click: "Kielich") [(set:
$hasAmulet to false)]
{
(live: 2s)[
(if: $hasAmulet is false)[(go-to: "05")]
]
(stop:) }

Dla fragmentu 05

Pokój 05

Urok Bransoletek (click: "Urok") [(set:
$hasAmulet to false)]
{
(live: 2s)[
(if: $hasAmulet is false)[(go-to: "01")]

Zdążyliśmy już wyjaśnić powyżej kod zawarty w tych fragmentach. Jak pewnie widać, tworzą one rodzaj pętli lub karuzeli, przemieszczając gracza z pokoju do pokoju na dwie sekundy w każdym miejscu docelowym. Więcej o tym wątpliwym zaprojektowaniu nieco później, a na początek odniesiemy się do technicznych uwag zgłoszonych przez dra Wardrip-Fruina, który – co warto podkreślić – posiada także stopień magistra informatyki. Otóż zastanawia się on: "Co się stanie, jeśli słowo 'Oko' (z pierwszego pasażu) nie zostanie kliknięte w ciągu pierwszych dwóch sekund? Czy będziemy testowali niezdefiniowaną zmienną?" (Wardrip-Fruin). To pytanie wyraźnie demonstruje różnice między umysłem ścisłym a tym, co dzieje się w naszych humanistycznych głowach. Pokazuje również sposób, w jaki Twine i Harlowe ułatwiają życie nieostrożnym eksperymentatorom. Okazuje się bowiem, że – a potwierdza to widoku debugowania dostępny w Harlowe – zmienna $hasAmulet nie istnieje dla Twine, dopóki coś nie zostanie kliknięte, w którym to momencie wartość zmiennej staje się dopiero prawdziwa albo fałszywa. W rzeczy samej testujemy te wartości w kolejnych fragmentach, ale dzięki zakorzenieniu Harlowe w języku JavaScript, nieistnyijąca zmienna nie stanowi dla programu żadnego problemu. Program najwyżej wzruszyć ramionami, ale idzie dalej.

Nie oczekujmy jednak tak pobłażliwego traktowania od większości programów, w tym od formatu Chapbooka, który w przypadku podania nie zdefiniowanej uprzednio zmiennej najpewniej wyświetli komunikat “unexpected error”. Wróćmy teraz do naszego niezwykłego projektu. Dlaczego ustawiamy tylko 2 sekundy na każdy fragment? Wybraliśmy taką długość arbitralnie w celach demonstracyjnych. Prawdopodobnie jest to czas zbyt krótki, a budzi niepokojące pytania w kwestiach dostępności, może wręcz wydać się dyskryminujący. Wiele osób ma przecież trudności z czytaniem krótkich fragmentów tekstu w kilka sekund i może potrzebować więcej czasu na odpowiedź. Można nawet zadać pytanie, czy naprawdę potrzebujemy więcej tego typu gier, nawet jeśli są to parodie? Podajemy jednak taki przykład z głupią – być może – nadzieją, że mechanizm automatycznych przeskoków może zostać przez kogoś użyty do bardziej ludzkich celów. Spójrzmy na przykład na Queers in Love at the End of the World Anny Anthropy – utworze, o którym mówimy w części teoretycznej.

◊ Cokolwiek jest to warte, zakończmy Karuzelę Opowieści wprowadzając następujący tekst do fragmentu 03:


Pokój 03

Amulet Nieporuszenia (click: "Amulet")
[(set: $hasAmulet to true)]
{
(live: 2s)[
(if: $hasAmulet is false)[(go-to: "04")]
(else:) [Gratulacje, zatrzymałeś
Karuzelę.]
] (stop:) }

W porównaniu do poprzednich segmentów, wprowadziliśmy tutaj tylko dwie niewielkie zmiany. Kliknięcie na "Amulet" ustawia $hasAmulet na true, a to deaktywuje mechanizm ciągłego przemieszczania się. W uznaniu tego zdarzenia, ustawiamy tuż poniżej (if:) makro (else:) , wychwytując pomyślne warunek i raportując takiż.

I tak oto zrobiliśmy pełen obrót od Chapbooka do Harlowe’a i od prostych hipertekstów do dynamicznych gier.