Diskuze o textových hrách

Tvorba Textových her => Programování => Téma založeno: gaspoda 17. Září 2015 - 10:34

Název: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 17. Září 2015 - 10:34
Někteří asi víte, že Základna na asteroidu je naprogramovaná trochu jinak, než je u českých textových her zvykem. Vznikla v systému TADS 3, který jsem přeložil do českého jazyka. TADS je jeden ze dvou nejpropracovanějších systémů pro tvorbu interaktivní fikce ovládané příkazovým řádkem a jeho historie sahá až do roku 1988, kdy se objevila první verze, trojka je však zcela přepracovaná a slouží od roku 2006.

Když už jsem se do tak rozsáhlého projektu pustil, měl jsem od počátku v plánu víc, než jen naprogramovat textovou hru. Rád bych českým autorům přiblížil svět novodobé interaktivní fikce, která se na anglicky hovořící scéně rozvinula, a protože jsem především programátor, snažím se především pootevřít dveře k modernějšímu způsobu programování. Na serveru textovy.cz dnes začal vycházet seriál o programování textových her v TADS 3, který vás provede tím nejdůležitějším, s čím se při tvorbě her budete setkávat. V jeho sedmi dílech vydávaných zhruba po čtrnácti dnech se postupně podíváme na jednotlivé problémy, jako tvorba místností, předmětů, zpracování akcí a programování postav ve hře.

Seriál si určitě neklade za cíl stát se dokonale podrobnou učebnicí, na to máme k dispozici řadu knih, ale určitě získáte poměrně dobrou představu, jak se věci v TADSu řeší. V diskusi rád odpovím na jakékoliv dotazy, které by vás mohly napadnout, budete-li chtít vědět o některém tématu více, můžeme na něj navázat podrobnějším vysvětlením nebo dalšími příklady. Na konci seriálu pak dojde na (snad) největší lákadlo, chystám se vydat kompletní zdrojové kódy své hry pro zájemce, kteří by do nich chtěli nahlédnout a prozkoumat, jak je hra udělaná.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: pedromagician 17. Září 2015 - 15:58
ty ma chces silou mocou dokopat k zverejneniu svojho enginu :-D

super už sa teším, večer si prečítam. klobúk dole pred takým projektom a ešte k tomu aj úspešne dotiahnutým do konca :-)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 17. Září 2015 - 23:48
Chci cokoliv, o co bude zájem.

Chci ukázat problematiku z malinko jiného úhlu pohledu, možná trochu inspirovat nebo třeba i jen vyvolat zajímavou diskusi. Zkrátka chci trochu rozvířit stojaté vody! A když Pavel Tišnovský nezvedl hozenou rukavici a psal na rootu jen o Informu, tak jako kontrast chci ukázat ten druhý velký systém, který je úplně jiný, než Inform, a přitom se v obou tvoří velice podobně fungující hry.

Možná někde ve skrytu duše chci i trochu zaprovokovat, ale to spíš v reakci na adentův článek, který tu před časem odkazoval. Přišlo mi škoda, že je tak povrchní, že mluví jen o tom nejjednodušším způsobu programování, a ještě ho ani neukáže konkrétně, takže těm, kterým byl určený, asi moc nepomohl. A diskuse, zda předmět mimo mapu označovat -1 nebo 255, je o ničem. Přitom by se dalo diskutovat o spoustě zajímavých problémů, o programování parseru, o konverzačních systémech, o odvíjení příběhu atp.

Hlavně ale chci dát větší přidanou hodnotu zdrojovým kódům Základny a dopředu trochu vysvětlit, co v nich lidé uvidí, aby to pro ně bylo pak více přínosné, než kdyby do nich nakoukli bez jakékoliv předchozí znalosti.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 19. Září 2015 - 08:31
Tak to sa tesim aj ja. Dufam ze ta nalada na pisanie clankov neopusti a dokoncis to cim skor tym lepsie :).

Jedna zvedava otazka k tomu TADS3. To je IDE kde sa pise cisto len kod a kompiluje alebo sa tam daju naklikavat jednotlive objekty, miestnosti, akcie a k nim sa riesi kod? Nemal som este cas sa do toho poriadne pozriet tak aspon informativne pre moju predstavu. Dik.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 19. Září 2015 - 10:11
Nemusíš se bát, já ve skutečnosti mám už připravených pět dílů ze sedmi (asi z 95 %), musím jen dopsat výživný díl o NPC postavách a závěr, ty jsem ještě nezačal. Chci to ale pouštět ven postupně, protože přeci jen je to poměrně dlouhé a náročné čtení, a pokud vzniknou otázky, tak bude lepší si nechat časový prostor a nemíchat jednotlivá témata dohromady, aby se udrželo soustředění. A pak to zajistí textovkám.cz trošku živosti po celý podzim.

TADS přistupuje k programování textových her (na rozdíl třeba od Inform 7) opravdu z čistě programátorského pohledu, takže i jeho vývojové prostředí se velice podobá vývojovým prostředím pro profesionální programátory. Základem je tedy textový editor, který zvýrazňuje syntaxi a má spoustu různých vymožností (záložky, hledání, skládání kódu, automatické odsazování atp.), debugger umožňující krokovat kód, vkládat breakpointy a prohlížet aktuální stav proměnných, objektů atp., správce a navigátor v projektu a také obsahuje integrovanou veškerou dokumentaci. Pár obrázků, jak prostředí vypadá, je na http://tads.org/ov_tools.htm (http://tads.org/ov_tools.htm).

Opravdu se tedy nejedná o naklikávání objektů, žádné vyplňování dialogů či průvodců, je to čistokrevné programování, kde výsledkem je zdrojový kód v textové podobě, jak bys ho vytvořil i bez jakéhokoliv vývojového prostředí. Já sám pracuji na Linuxu, takže Workbench používám jen zřídka, když potřebuji debugger, a celou Základnu jsem napsal ve svém olíbeném IDE pro C++ (v Qt Creatoru).

V prvním dílu jsem si zatím jen připravoval půdu pod nohami, ale už v příštím článku uvidíš reálné příklady, jak se vytvářejí místnosti ve hře a jak se spojují do mapy, a uvidíš, že to není zase až tak strašidelné. Vlastně možná budete překvapeni, že s barvičkami a hezkým odsazením zdrojáku to je i docela přehledné a hlavně hodně stručné, prim hraje skutečný obsah hry, tedy texty k zobrazení.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 19. Září 2015 - 20:08
Parada, je sa teda na co tesit. Zima je uz coskoro pred dverami tak bude aj viac casu straveneho u PC.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 21. Září 2015 - 20:31
Uz lamem TADS3 cez koleno. Objavuju sa prve zaciatocnicke problemy. Trebars tento kus kodu ukazuje chybu aj ked by mal byt spravny (sudim podla manualu a podla ineho tutorialu kde je to presne rovnake len iny nazov objektu)

Kód: [Vybrat]
pants: Wearable
    vocabWords = 'brown pants*pants clothes'
    name = 'brown pants'
    desc = "Pair of brown pants with pockets on the sides."
    location = room03
    dobjFor(Doff)
    {
        check()
        { // - tu hlasi chybu ze vyzaduje ; ale preco by tu mala byt?
            failCheck('You decided to leave them on yourself for now.');
        }
    }
;

Citace
Expected a semicolon ';' but found "{".  Please add the required semicolon.  If
a semicolon is already present, check for unbalanced parentheses or other
expression errors.

PS:Zapis sa da skratit ja viem. Tento sposob sa mi ale paci viac. Tu dobjFor cast nechce skompilovat IDE, je to divne. V com by mohol byt problem?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 21. Září 2015 - 20:45
Ten kousek kódu, co jsi přiložil, je naprosto v pořádku (za předpokladu, že existuje někde room03, pokud by neexistovala, napsalo by to jiné varování). Myslím, že problém bude někde jinde ve zdrojáku, třeba někde ještě dříve. Zkontroloval bych, zda složené závorky jdou všude do páru atp.

Kdybys na to jó nemohl přijít, tak mi pošli mailem celý zdroják, já se ti na něj podívám. Můj mail je na úvodní stránce tads.cz dole.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 21. Září 2015 - 20:52
Vsetko ostatne ale funguje akonahle tu cast kodu zakomentujem

Kód: [Vybrat]
dobjFor(Doff)
    {
        check()
        { // - tu hlasi chybu ze vyzaduje ; ale preco by tu mala byt?
            failCheck('You decided to leave them on yourself for now.');
        }
    }

Ak tam v src toto nieje tak normalne spusti hru. Som v miestnosti. Mozem sa hybat do inej miestnosti. A vidim na zemi svoje 2 predmety s ktorymi mozem manipulovat. Tam fakt ine zatvorky navyse niesu. :-/
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 21. Září 2015 - 21:01
Já jsem si celý ten tvůj kousek hodil do svého zdrojáku a fungoval úplně v pořádku, takže kdo ví. Člověk pak podezírá, zda sis tam třeba nezkopíroval nějakou neviditelnou typografickou značku, pokud jsi základ bral z nějakého tutoriálu, či něco takového, co pak já ve fóru nevidím. Proto jsem nabízel, že mi můžeš poslat celý ten zdroják mailem (nejlépe v zipu), samotný úryvek je v pořádku. A nebo je opravdu něco nad tím.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 22. Září 2015 - 09:39
Uz som prisiel na problem. Je to tym ze som si rozdelil subory na viacero casti. Chcel som to tak ze v main subore su len definicie ohladom hry, pociatocnej pozicii, intro atd. A v ostatnych suboroch by bola mapa rozdelena na mensie kusy koli prehladnosti.

Problem sa vyriesil ked som do dalsieho suboru kde bola hlasena chyba vlozil riadok na zaciatok pre kniznicu #include <adv3.h>, pre istotu tam necham aj #include <en_us.h>

Code completition to IDE nema ze? To by sa zislo ako sol :-/.

Dalsi problem na ktory som narazil je ako obliect hlavnej postave nohavice hned od zaciatku. Ak definujem u nohavic vlastnost wornBy = me (je to vsade v manuali takto) tak engine sa sprava divne. Ako keby to bolo oblecene na postave ale zaroven to pri zobrazeni inventara nevidno zeby som to mal oblecene. Najlepsie mozno pochopit celu situaciu z logu kde mam dva predmety. Nohavice su wearable a wornBy = me, tricko je wearable a je len v miestnosti na zemi.

Citace
You see a brown pants (being worn) and a green shirt here.

>i
You are empty-handed.

>wear shirt
(first taking the green shirt)
Okay, you’re now wearing the green shirt.

>i
You are carrying nothing, and are wearing a green shirt.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 22. Září 2015 - 10:23
No vida! Já věděl, že je problém někde jinde, než v tom kousku, který jsi posílal.

Rozdělení projektu na více souborů je naprosto v pořádku, já mám dokonce každou místnost a každou postavu v samostatném souboru, aby se mi v tom lépe hledalo. Na začátku každého soubou vždy uveď definici kódové stránky (#charset "windows-1250" apod.) i oba #include, bez nich by to nemohlo fungovat, každý soubor se totiž kompiluje zvlášť a potřebuje všechny definice všech maker, které se v souboru pak používají.

Konkrétně v tomto případě byla chyba nahlášena v daném místě proto, že hlavičkový soubor zavádí takzvané "propertyset", to je právě ta vymoženost zápisu dobjFor(Doff) { check() { ... }}. Interně se to totiž transformuje na méně přehledné, ale pro kompilátor stravitelnější definice samostatných funkcí, v tomto případě checkDobjDoff { ... }.

A teď ke tvé otázce s oblečením. Trochu předbíháš, ve čtvrtém dílu budu podrobně mluvit o kontejnerové hierarchii, takže nyní jen stručně. U objektu, který chceš, aby postava nesla, nastav location = me. Pokud je to oblečení (Wearable) a má ho mít postava obléknuté, nastav kromě location i wornBy = me, tedy obě(!) vlastnosti. Zkrátka oblečené olečení musí být také v inventáři postavy.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: SoulSoft 22. Září 2015 - 13:24
Dik to je ono. Este ma napada jedna vec ci si to neriesil nahodou. Mas rozne objekty napr postel a tricko. Napisem prikaz wear all a logicky tym myslim len tie objekty ktore sa daju obliect. Hra ale zacne prechadzat aj postel a vypisovat "That isn’t something you can wear". Nejde tam prepnut aby tieto objekty proste ignorovalo a nevypisovalo? Obdobne je to u prikazov take, open, close, lock, unlock.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 22. Září 2015 - 13:37
Ano, jde to, ale dá to trochu práci, takže se to vyplatí dělat jen tam a jen s těmi akcemi, kde to hráč nejpravděpodobněji bude zkoušet. Třeba v mé hře bylo několik kousků oblečení v úvodní lokaci, tak v ní (a ne jinde) jsem měl u ostatních objektů, jako třeba u dveří přidanou metodu hideFromAll, která právě řeší, zda se ten konkrétní objekt má ukrýt před kvantifikátorem "vše" v příkazu:

Kód: [Vybrat]
    hideFromAll(action)
    {
        return action.ofKind(WearAction)
            || action.ofKind(DoffAction)
            || inherited(action);
    }

Metoda má vrátit true, pokud má být objekt vynechán z "vše". Tedy v tomto případě jsem ukrýval dveře před "oblékni vše" a "svlékni vše". U jiných typů akcí se pak použilo výchozí zacházení, proto to inherited(action).
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 30. Září 2015 - 23:14
Zítra ráno vyjde druhý díl na téma programování lokací, tj. místností ve hře, jejich spojování do mapy ať už přímo nebo prostřednictvím dveří či jiných konektorů, programování bariér zabraňujících pohybu postavy konektorem a tvorbě atmosférických hlášek, které oživují hru.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: pedromagician 12. Říjen 2015 - 21:32
zaujímavé poučné, už sa neviem dočkať ďalšej časti :-)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 12. Říjen 2015 - 23:03
Jasně, zase ve čtvrtek ráno, konkrétně v 6.00 (to je takové to klasické Technoplanetí ráno ;-)) Tentokrát zaplníme místnosti spoustou nejrůznějších objektů, ať už přenosných předmětů či nepřenosných dekorací. Vysvětlíme si pojmenování objektu a zadání jeho slovníku i spoustu dalších užitečných vlastností. A nakonec v poslední pokročilé kapitolce dojde i na objekt "chrápání".
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 29. Říjen 2015 - 08:02
Tak dnes vyšel další díl o kontejnerech a jejich hierarchii. Na příště mám nachystaný díl o akcích, čímž se uzavře kolečo znalostí, které je potřeba znát pro každou hru. Poctivě však už chystám díl o NPC postavách, mám popsaný skoro celý mechanismus rozhovorů, akorát jsem narazil na malý zádrhel, že už teď je tak dlouhý, jako ostatní články, a potřebuji do něj ještě dostat samotné postavy, jejich stavy a agendu. Tak doufám, že to alespoň ti nejodvážnější z vás přečtou. Jo a najde se dobrovolník, který napíše Syrečky? :-)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 01:24
Narazil jsem v knihovně na takovou skrytou podivnost u standardních odpovědi na CutWithAction ve VerbRule(CutWithWhat) - když napíšu uřízni strom - napíše mi zprávu(špatně) Co jím chceš uříznout, zatímco přeřízni strom napíše(správně) Čím ho chceš uříznout

Dost divné, tipuju na nějaký konflikt s VerbRule(CutWith), tam to dělá také - když zadám
uřízni nožem liánu - nožem nic nepřeřízneš - to je dobře
přeřízni nožem liánu - Čím chceš uříznout? - tohle ne

Také mě zaujalo, že existuje CutAction, ale nepoužívá jí žádné VerbRule a místo toho je zřejmě ono CutWithWhat, které prakticky pouze upozorňuje na absenci iobj
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 6. Listopad 2015 - 09:46
Ano, vidím chybu, že synonymum přezízni na rozdíl od uřízni bylo jen u akce CutWithWhat a ne u CutWith. Tím pádem došlo k tomu, že přeřízni nožem liánu bylo vyhodnoceno jako:

Kód: [Vybrat]
VerbRule(CutWithWhat)
    [badness 500] ('uřízni' | 'uříznout' | 'přeřízni' | 'přeříznout') singleDobj
    : CutWithAction
;

tedy "nožem liánu" bylo bráno jako singleDobj, tedy jako jediný objekt a to vedlo ke zmatku. Chceš-li si to opravit, přidej chybějící synonyma i do CutWith, které je hned pod tím v souboru cs_cz.t.

Nicméně na tomto místě je potřeba vysvětlit ještě jednu ošklivou záludnost českého jazyka, se kterou je potřeba pomoci parseru. Totiž akce CutWith je jedna z několika akcí, které nemají předložkami určenou roli objektů, jako v jiných příkazech (dej hrnek na stůl vs. dej na stůl hrnek). Hráč může stejně dobře napsat "uřízni liánu nožem" jako "uřízni nožem liánu" a TADS to neumí dost dobře odlišit, co je přímý objekt manipulace (liána) a co nepřímý (nůž). Tyhle případy je potřeba ve zdrojovém kódu pořešit a pomoci TADSu se rozhodnou, který objekt je iobj. Stačí noži přidat třídu PreferredIobj pomocí vícenásobné dědičnosti. Tím si pojistíte, že parser se nesplete a nebude si myslet, že chce hráč liánou uříznout nůž.

Pomohla tato odpověď, nebo ještě zbyl nějaký problém?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 14:13
ještě jsem to nezkoušel, ale myslím, že přidání synonym by to zmatení parseru mohlo vyřešit.

To jsem si právě říkal, jak to funguje, když parser v podobném případě neví jestli jsem použil dobj iobj nebo iobj dobj, když příkaz akceptuje obojí. Vyzkouším to udělat dle tvého doporučení a přidám noži třídu PreferredIobj

Zatím si také nejsem jistý do jakého objektu dát akci, když se jedná o akci zahrnující přímý a nepřímý objekt.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 6. Listopad 2015 - 14:22
Zatím si také nejsem jistý do jakého objektu dát akci, když se jedná o akci zahrnující přímý a nepřímý objekt.
V podstatě si můžeš vybrat. Obvykle je potřeba se buď řídit tím, jak je akce naprogramována v knihovně, pokud se snažíš upravit či změnit výchozí chování knihovny, nebo si vybereš ten objekt, kde je výsledek akce specifičtější. Tím myslím, že když máš pět provazů a přeříznout jdou jedním jediným objektem, tak akci naprogramuješ u něj. Když máš jeden provaz a přeříznout jde pěti různými objekty, naprogramuješ akci u provazu apod.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 15:01
Jasně, to dává smysl. Takže v tomto případě by byl nejlepší nůž, i kdyby ve hře reálně fungoval příkaz jen na jeden objekt, protože by mohly existovat další situace, ve kterých by dávalo smysl, že chci něco uříznout, i kdyby to mělo hodit jen odezvu, že to nejde.

Sladění synonym u CutWithWhat a CutWith pomohlo. Jen odezva na uřízni lianu odpoví - Co jí chceš uříznout.

Ještě jsem přemýšlel, o takové vychytávce, že by ta akce pouze s přímým objektem automaticky vybrala vhodný objekt. Zjistilo by to např. jestli mám objekt odpovídající třídy a akci provedl s ním, případně by se zeptal, který pokud by jich bylo více. No, to už je taková pomalu zbytečnost.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 18:50
Ještě pro úplnost k třídě PreferredIobj. Ještě by se mělo do VerbRule(CutWith) přidat: preferredIobj = PreferredIobj

Alespoň bez toho mi to nefungovalo.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 6. Listopad 2015 - 19:43
Jasně, to dává smysl. Takže v tomto případě by byl nejlepší nůž, i kdyby ve hře reálně fungoval příkaz jen na jeden objekt, protože by mohly existovat další situace, ve kterých by dávalo smysl, že chci něco uříznout, i kdyby to mělo hodit jen odezvu, že to nejde.

V podstatě ano. Ale pro úplnost i zde platí, že je zároveň potřeba se řídit knihovnou. Akce CutWith je zakázaná verify metodou dobj i iobj, takže verify je nutné přetížit prázdným tělem v rámci dobj liány i iobj nože, čili na obou místech. Právě ty verify() metody zobrazují hlášku, že to nejde.

Sladění synonym u CutWithWhat a CutWith pomohlo. Jen odezva na uřízni lianu odpoví - Co jí chceš uříznout.

Mě to tu funguje, asi bychom se museli bavit o konkrétním testcase. Mám tu něco jako:

Kód: [Vybrat]
+ PreferredIobj, Thing 'nůž' 'nůž' *2
    iobjFor(CutWith)
    {
        verify() {  }
    }

    gcName = 'nože, noži, nůž, noži, nožem'
    gcVocab = 'nože/noži/nožem'
;

+ Thing 'liána' 'liána' *3
    dobjFor(CutWith)
    {
        verify() {  }
        action() { "{Kýmčím iobj} jsi přeřízl {kohoco dobj}."; }
    }

    gcName = 'liány, liáně, liánu, liáně, liánou'
    gcVocab = 'liány/liáně/liánu/liánou'
;

Ještě jsem přemýšlel, o takové vychytávce, že by ta akce pouze s přímým objektem automaticky vybrala vhodný objekt. Zjistilo by to např. jestli mám objekt odpovídající třídy a akci provedl s ním, případně by se zeptal, který pokud by jich bylo více. No, to už je taková pomalu zbytečnost.

To není problém, to tak funguje automaticky. Pokud je jen jediný nůž, tak příkaz "uřízni liánu" ho zvolí automaticky, pokud mám víc nožů, zeptá se "Čím ji chceš uříznout?"

S čím mám problém je příkaz "uřízni nožem", na to není TADS v anglickém originálu stavěný a já zatím nepřišel na to, jak v situaci s chybějícím objektem prohodit roli iobj a dobj, jinýmy slovy TADS předpokládá, že vždy chybí iobj.

Ještě pro úplnost k třídě PreferredIobj. Ještě by se mělo do VerbRule(CutWith) přidat: preferredIobj = PreferredIobj

Ano, už jsem si toho také všiml. Ono by to spíš mělo být tak, že v cs_cz.t by podmínka:

Kód: [Vybrat]
            if (preferredIobj != nil && dobjInfo.obj_.ofKind(preferredIobj))Měla být změněna na:

Kód: [Vybrat]
            if (preferredIobj != nil && dobjInfo.obj_.ofKind(preferredIobj)
                || dobjInfo.obj_.ofKind(PreferredIobj))

Ty akce bez předložek (MoveWith, TurnWith, BurnWith, CutWith, CleanWith, (Un)LockWith, (Un)ScrewWith) nemám zatím moc prozkoušené a doladěné.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 21:24
Citace
Sladění synonym u CutWithWhat a CutWith pomohlo. Jen odezva na uřízni lianu odpoví - Co jí chceš uříznout.

Mě to tu funguje, asi bychom se museli bavit o konkrétním testcase.

Když jsem si s tím hrál, tak jsem ještě u objektů neměl dobjFor(CutWith). Nyní mám tedy objekty takto:
Kód: [Vybrat]
++ nuz: PreferredIobj, Thing 'japonský vojenský nůž' 'vojenský nůž' *2
    "Je to vojenský nůž japonské výroby, který jsi ukradl strážci. Je velmi ostrý, pozor! "

    gcName = 'vojenského nože, vojenskému noži, vojenský nůž, vojenském noži, vojenským nožem'
    gcVocab = 'vojenského japonského vojenskému japonskému vojenském japonském vojenským japonským
    nože/noži/nožem'

    iobjFor(CutWith)
    {
        verify() {  }
    }
;

+ liana: Hidden, Thing 'pevná pružná liána' 'liána' *3
    "Liána vypadá pevně a pružně. "
    initSpecialDesc = "Kousek od tebe visí liána. "

    gcName = 'liány, liáně, liánu, liáně, liánou'
    gcVocab = 'pevné pružné pevnou pružnou liány/liáně/liánu/liánou'

    dobjFor(Take)
    {
        check()
        {
            failCheck('Liána je příliš pevná a pružná, abys ji dokázal jen tak vzít. ');
        }
    }

    dobjFor(CutWith)
    {
        verify()
        {
            if(moved) { illogicalAlready('Nechceš liánu zbytečně řezat na menší kusy. '); }
        }
        action()
        {
            moveInto(gPlayerChar);
            "{Kýmčím iobj} jsi uřízl velký kus {kohočeho dobj} a omotal si ho kolem pasu. ";
        }
    }
;
akce s dobj i iobj proběhne vše správně. Když zadám pouze přeřízni liánu, tak dostanu:
(řežeš liánu)
Liánou nic nepřeřízneš

když už mám liánu v inventáři, tak je odezva: Co jí chceš uříznout?

Citace
To není problém, to tak funguje automaticky. Pokud je jen jediný nůž, tak příkaz "uřízni liánu" ho zvolí automaticky, pokud mám víc nožů, zeptá se "Čím ji chceš uříznout?"

To mi právě nejde, viz. výše. Je třeba ještě něco dopsat?

Jinak, nemám založit další diskuzi, abych to tady netapetoval?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 6. Listopad 2015 - 22:00
Jo víš, co jsem ještě udělal? Já smazal z CutWith tu variantu s opačným pořadím, která nedávala smysl:
Kód: [Vybrat]
VerbRule(CutWith)
    ('uřízni' | 'uříznout' | 'přeřízni' | 'přeříznout') singleDobj singleIobj
    : CutWithAction
    verbPhrase = 'uříznout/řež{eš}/uřízl{a} (co) (čím)'
    askDobjResponseProd = singleNoun
    askIobjResponseProd = singleNoun
;

Co se týče diskuse, to je asi celkem jedno, on se stejně nikdo moc na seriál neptal, tak to ani moc nevadí. Samozřejmě pokud by vznikly dotazy k určitým tématům ve větším množství, tak by bylo užitečnější je mít v samostatných vláknech s titulkem vyjadřující to které téma, aby se v tom ostatním lépe hledalo, pokud by řešili stejnou věc.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 6. Listopad 2015 - 22:30
Tak v tomhle byl problém. Je zajímavé, že i když se vymaže ta varianta s opačným pořadím, tak to příkaz s opačným pořadím pochopí.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 6. Listopad 2015 - 23:28
Parser TADSu je pro mě zdaleka nejsložitější část, jejíž vrstvy loupu jen velice pomalu. Kdysi jsem si myslel, že musím ve VerbRule uvést obě možná pořadí dobj a iobj, aby si parser mohl vybrat tu správnou interpretaci odpovídající pořadí, v němž zadal objekty hráč.

Ale parser pracuje trochu jiným způsobem, jakoby ve dvou krocích nebo vrstvách. Nejprve vybuduje všechny možné syntaktické stromy, které odpovídají příkazu hráče. Nejen VerbRule, ale celé strukturální fráze, jejichž součástí někde uvnitř jsou VerbRule se svými sloty pro objekty. Matchuje jednotlivá slova z frází a slova ze slovníku, u kterých rozlišuje gramatické kategorie (podstatná jména, přídavná jména,...).

Může tak vzniknout celá dlouhá řada různých syntaktických interpretací příkazu zadaného hráčem, která se různě hodnotí a řadí podle nejrůznějších kritérií, aby se vybrala nejlepší interpretace. Důležité je pochopit, že výběr interpretace se stane dříve, než se resolvují slova v dobj/iobj slotech na konkrétní herní objekty a začne se zjišťovat, co příkaz znamená sémanticky a jaký smysl dává.

S příkazy, ve kterých není určena role objektů předložkou, jsem si dlouho lámal hlavu, až jsem problém nadhodil na anglickém fóru a Mikawa mi poradil řešení. Po resolvování slotů na herní objekty, kdy už je možné o objektech zjišťovat informace, jako třeba jejich třídu, se provede případné prohození slotů mezi sebou. Detaily jsou na: http://www.intfiction.org/forum/viewtopic.php?f=10&t=5480 (http://www.intfiction.org/forum/viewtopic.php?f=10&t=5480)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 7. Listopad 2015 - 21:43
Teď si říkám, co se stane, když mám nůž s třídou PreferredIobj a chci hi použít v akci, kde ho chci mít jako dobj?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 7. Listopad 2015 - 21:58
Pokud by měl být zároveň přímým objektem v nějaké akci, která vyžaduje přímé i nepřímé objekty, a proto nebylo vhodné, že se vždy prohazuje do role nepřímého objektu, tak je tu vždy možnost vykašlat se na mix-in třídu PreferredIobj. Místo toho můžeš nůž podědit z Thing do nějaké své třídy (řekněme class Knife: Thing; + knife: Knife;), aby byl snadno identifikovatelný a modifikovat akci CutWith tak, že ji nastavíš preferredIobj = Knife. Mrkni třeba na konverzační akce GiveTo, ShowTo. Ty mají nastaveno preferredIobj = Actor.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 7. Listopad 2015 - 22:15
To je bezva řešení. Elegantnější, než PreferredIobj - kde vždy může nastat problém s tím, že se u každé TI akce přehodí na nepřímý objekt.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 10. Listopad 2015 - 17:05
Mimochodem, kdy bude další díl seriálu?

Řeším teď nové VerbRule. Mám dle CutWith, CutWithWhat z knihovny vytvořené RepairWith, RepairWithWhat.

Normálně neúplný příkaz např. oprav nůž hra(přes RepairWithWhat) automaticky doplní vhodným objektem, pokud je přítomný. Já bych spíše chtěl, aby se v podobném případě parser pouze zeptal, pomocí čeho chci nůž opravit.

Když úplně odstraním RepairWithWhat, tak neúplný příkaz vede k tomu, že hra ho nepozná vůbec. Napadlo mě jediné řešení, že bych vytvořil obecnější TAction Repair, ale nejlepší by bylo mít pro příkazy zahrnující přímý a nepřímý předmět řešení s doplňujícím dotazem, ale u některých neumožnit automatické doplnění nepřímého předmětu.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 10. Listopad 2015 - 17:07
Ve VerbRule se také často nastavují různé vlastnosti, ale nic, z čeho bych byl moudrý, jsem o nich nenašel. Možná jsem špatně hledal, ale třeba v Library Reference k některým je krátká věta, k některým nic.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 10. Listopad 2015 - 18:51
Jako obvykle ve čtvrtek v 6.00 ráno. A jak je to s automatickým doplněním nebo naopak nedoplněním objektů v různých situacích a akcích bude vysvětleno ;-)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 10. Listopad 2015 - 20:03
Tak, na to si rád počkám:)
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 12. Listopad 2015 - 22:56
Ok, takže nonObvious ve verify objektu to vcelku řeší. Další varianta je mít verzi akce pouze s dobj a vypsat u ní pouze nápovědu/upřesnění jak je příkaz třeba zadat.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 13. Listopad 2015 - 07:53
Přesně tak, řeší se to pomocí nonObvious. Třeba v naší hře jsme měli tablet, který bylo možné >rozsvítit tablet, ale nechtěli jsme, aby se to stalo jen když hráč napíše samotné >rozsviť:
Kód: [Vybrat]
    dobjFor(Light)
    {
        verify() { nonObvious; }
        action() { replaceAction(Push, tabletButton); }
    }
U akcí se to pak řeší tak, že k jedné akci jsou dvě VerbRule, jedna s badness a místo slotu na iobj dělá v konstruktoru iobjMatch = new EmptyNounPhraseProd(), snadno to někde zahlédneš. Ale úplně do těchhle vnitřností zatím moc nevidím.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 13. Listopad 2015 - 15:28
Jo, zkopíroval jsem si pro druhé VerbRule k opravit právě z CutWithWhat, které má badness 500 a řeší to, že když se příkaz nezadá celý, tak se parser hráče dotáže(nebo automaticky doplní, když nemám u akce v objektu nonObvious).

Jen mi přijde zvláštní, že kód v constructu se dle mého tváří, že doplní pouze chybějící iobj, ale podle hry doplní i dobj, pokud chybí.

Kód: [Vybrat]
VerbRule(RepairWithWhat)
    [badness 500] ('oprav' | 'sprav') singleDobj
    : RepairWithAction
    verbPhrase = 'opravit/opravuj{eš}/opravil{a} (co) (čím)'
    construct()
    {
        iobjMatch = new EmptyNounPhraseProd();
        iobjMatch.responseProd = singleNoun;
    }
;

Pořád mi není úplně jasné askDobjResponseProd a askIobjResponseProd (je např. v CutWith, mám podle něj RepairWith) - to má pochopit v jaké podobě očekává doplnění příkazu? Znamená to, že to nějak pracuje ve spojení s CutWithWhat, bez kterého se hra na doplnění vůbec ptát nebude a příkaz prostě nepochopí?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 13. Listopad 2015 - 20:28
Jen mi přijde zvláštní, že kód v constructu se dle mého tváří, že doplní pouze chybějící iobj, ale podle hry doplní i dobj, pokud chybí.

Kdybys do toho chtěl více nahlédnout, tak je možné kdykoliv zapnout ladění parseru pomocí příkazu libGlobal.parserDebugMode = true; a pak se třeba o příkazu "uřízni", kterému chybí oba objekty, dozvíš, že byl zachycen oběma predikáty CutWith i CutWithWhat a to díky gramatice singleNoun(empty):

Kód: [Vybrat]
>uřízni
———-
firstCommandPhrase(commandOnly) [uřízni]
  commandPhrase(definiteConj) [uřízni]
    predicate(CutWith) [uřízni]
      singleNoun(empty) []
      singleNoun(empty) []
———-
firstCommandPhrase(commandOnly) [uřízni]
  commandPhrase(definiteConj) [uřízni]
    predicate(CutWithWhat) [uřízni]
      singleNoun(empty) []
—– Winner —–
firstCommandPhrase(commandOnly) [uřízni]
  commandPhrase(definiteConj) [uřízni]
    predicate(CutWithWhat) [uřízni]
      singleNoun(empty) []
    (provaz)
Čím ho chceš uříznout?

Z obou vyhrává CutWithWhat, protože má v součtu menší badness, než když se singleNoun(empty) doplnilo dvakrát. Ta gramatika singleNoun(empty) vypadá následovně, najdeš ji někde v hlubinách cs_cz.t:

Kód: [Vybrat]
/*
 *   An empty single noun is one with no words at all.  This is matched
 *   when a command requires a noun list but the player doesn't include
 *   one; this construct has "badness" because we only want to match it
 *   when we have no choice.
 */
grammar singleNoun(empty): [badness 500] : EmptyNounPhraseProd
    /* use a nil responseProd, so that we get the phrasing from the action */
    responseProd = nil

    /* the fallback responseProd, if we can't get one from the action */
    fallbackResponseProd = singleNoun
;

Proč je to takhle udělané, že je v gramatice prázdný slot na objekt i je varianta příkazu bez jednoho objektu, ti neřeknu, nerozumím tomu do takové hloubky. Možná by bez toho nebylo jasné, který objekt chybí, a proto se preferuje chybějící iobj před dobj, ale to opravdu jen spekuluji.

Pořád mi není úplně jasné askDobjResponseProd a askIobjResponseProd (je např. v CutWith, mám podle něj RepairWith) - to má pochopit v jaké podobě očekává doplnění příkazu? Znamená to, že to nějak pracuje ve spojení s CutWithWhat, bez kterého se hra na doplnění vůbec ptát nebude a příkaz prostě nepochopí?

Vlastnosti askDobjResponseProd a askIobjResponseProd ovlivňují to, jakým způsobem bude parser zpracovávat odpověď hráče na otázku ohledně chybějícího objektu. Při odpovědi na otázku "čím chceš liánu uříznout?" hráč asi odpoví "nožem". Některé příkazy ale mohou vybízet k odpovědi obsahující kromě samotného objektu i předložku, např. na otázku "na koho chceš zaútočit?" může hráč odpovědět "na Borise". Výchozí hodnotou obou vlastností je nounList a právě příkazy, u nichž je očekávána možnost, že hráč odpoví s předložkou, mají nastavenou některou z možností inSingleNoun, onSingleNoun a dalších, které jsou někde kolem řádku 6000 v cs_cz.t. U žádné z těchto variant není předložka povinná.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 14. Listopad 2015 - 14:34
Citace
Kdybys do toho chtěl více nahlédnout, tak je možné kdykoliv zapnout ladění parseru pomocí příkazu libGlobal.parserDebugMode = true; a pak se třeba o příkazu "uřízni", kterému chybí oba objekty, dozvíš, že byl zachycen oběma predikáty CutWith i CutWithWhat a to díky gramatice singleNoun(empty):

Dobrý tip, vyzkouším. Asi si rovnou přečtu něco o ladění v Tads. Čtu vše víceméně podle aktuální potřeby na přeskáčku.

Citace
Vlastnosti askDobjResponseProd a askIobjResponseProd ovlivňují to, jakým způsobem bude parser zpracovávat odpověď hráče na otázku ohledně chybějícího objektu. Při odpovědi na otázku "čím chceš liánu uříznout?" hráč asi odpoví "nožem". Některé příkazy ale mohou vybízet k odpovědi obsahující kromě samotného objektu i předložku, např. na otázku "na koho chceš zaútočit?" může hráč odpovědět "na Borise". Výchozí hodnotou obou vlastností je nounList a právě příkazy, u nichž je očekávána možnost, že hráč odpoví s předložkou, mají nastavenou některou z možností inSingleNoun, onSingleNoun a dalších, které jsou někde kolem řádku 6000 v cs_cz.t. U žádné z těchto variant není předložka povinná.

To jsem víceméně odhadl dobře, jen mi to nesedělo s tím, že obě vlastnosti jsou definovány v CutWith, ale to pokládání upřesňujícího dotazu funguje díky CutWithWhat - no nechám to zatím být a budu předpokládat, že obě VerbRule prostě nějak pracují dohromady.

Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 25. Listopad 2015 - 23:18
Tak zítra následuje neobvykle dlouhý díl o NPC postavách. Doufám, že zaujme, protože konverzační systém v TADS je velice vychytaný.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 24. Prosinec 2015 - 22:49
Tamtadadáá! Dnes konečně vyšel poslední díl a s ním jsem zveřejnil i kompletní zdrojové kódy Základny na asteroidu, první plnohodnotné české textové hry, která v TADS 3 vznikla.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: tekket 10. Leden 2016 - 18:28
Super, už jsem si zdroják stáhnul, jen jsem to narychlo prosvištěl, je to hodně rozsáhlé. Na tads teď nějak nezbývá čas, tak snad mezitím všechno nezapomenu.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 13. Březen 2017 - 17:40
Je to sice více, než rok od zveřejnění článku pro TADS a kódů pro Základnu, teprve nyní jsem se však dostal k tomu, abych si jej vytiskl a pořádně pročetl. Musím se přiznat, že návod je psaný perfektně a otevřel mi oči, možnosti TADSu jsou opravdu rozsáhlé a rozhodně stojí za to v něm textovku naprogramovat.

Zkoušel jsem nainstalovat kompletní prostředí TADS v Linuxu i Windows XP, poslední verze Workbenche 3.1.3 je alespoň na mých počítadlech dosti nestabilní a ani WINE v Linuxu na tom není jinak, s trochou trpělivosti se však použít dá. Naštěstí Frobtads funguje parádně a i v připraveném Debianu 9 je k dispozici v repozitářích, takže není co řešit. A mimo jiné mě donutí konečně se vrhnout na ovládnutí editoru VIM, poměrně nedávno vyšel balík pro zvýrazňování syntaxe pro TADS, tato kombinace mi umožní programovat i v příkazové řádce téměř na jakémkoliv počítadle.

Po přečtení článku jsem chca nechca musel přehodnotit svůj postoj k tvorbě příběhu i programování, poslední závěrečná kapitola parádně popisuje doporučenou možnost tvorby, je pravda, že jsem zatím žádnou cizojazyčnou textovku nehrál a neměl jsem tedy možnost srovnávání. Ale je to tak v pořádku, člověk se stále učí a bez přiznání svých chyb se zkrátka dále nedostanu.

Takže se vrhnu na to samé, co jsem měl v plánu před několika lety, v TADSu naprogramuji Exotera tak jak byl na Spektru a poté tu samou hru s využitím více jeho možností, následně Kroužícího orla, kde se ještě hodně zamyslím nad úpravou příběhu. Pedrův engine je prostě super a moc se mi líbí, cítím ovšem, že s TADSem budu moci využít nové možnosti plus se mnohé naučit, takže jdu na to.

Moc děkuji za článek, přesně ten jsem potřeboval.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 14. Březen 2017 - 15:58
poslední verze Workbenche 3.1.3 je alespoň na mých počítadlech dosti nestabilní a ani WINE v Linuxu na tom není jinak, s trochou trpělivosti se však použít dá.

Nemohu moc posoudit, protože Workbench a obecně Windows téměř nepoužívám. Mám akorát virtuální prostředí na pracovním počítači a notebooku a nikdy jsem neměl pocit, že by nebyl stabilní, ale opravdu jsem to zapnul jen párkrát, když jsem potřeboval debugger, jinak používám jen FrobTADS a jako vývojové prostředí Qt Creator.

je pravda, že jsem zatím žádnou cizojazyčnou textovku nehrál a neměl jsem tedy možnost srovnávání.

To je škoda, to nějakou zkus, byť třeba s walkthrough po ruce, abyses nezasekával a prošel jí rychle. Vyplatí se kouknout, jak vypadají a fungují textovky známých autorů, kteří za ně kolikrát získali i ocenění.

Každopádně pokud nebudeš jen sršit přehnaným optimismem a skutečně se i pokusíš něco udělat, tak rád ve fóru zodpovím otázky, na které nevyhnutelně narazíš. Každopádně se snaž udržet na uzdě a nejprve zkoušej jednoduché věci, tedy deklarace místností a objektů, různé typy objektů a jak se chovají a až to budeš mít bezpečněji v ruce, tak teprve zkoušej různé akce a složitější interakci. Moje série článků je opravdu jen stručný přehled, ale ke skutečné práci to chce přečíst Learning TADS 3, alespoň kap. 1-9.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 15. Březen 2017 - 09:20
Ano, s Workbenchem jsme na tom stejně. Já mám na notebooku staré Windows XP a Q4OS, do XP chodím spouštět pouze aplikace, které v Linuxu nedokážu stabilně emulovat a je odpojen od internetu, právě sem jsem instaloval poslední verzi TADS a krom toho, že jej nelze klasickým způsobem odinstalovat, padá tehdy, když zde založím nový projekt a vytvářím zdrojáky. Vyřešil jsem to jednoduše, zdrojový t soubor píši v linuxovém VIMu a debugguji ve Workbenchi spuštěným přes WINE, tam už mám vždy otevřený projekt a jen aktualizuji t soubor, zde alespoň zatím nemám problémy. Zvýraznění syntaxe funguje parádně, jediné, co chybí, je právě ten debugger, viz příspěvek jednoho uživatele také používacího QT Creator:

http://www.intfiction.org/forum/viewtopic.php?f=10&t=11378&start=10

Ve Q4OS používám Trinity, což je vlastně fork starého KDE3, syntaxe mi funguje i v Kate, Creator rozhodně vyzkouším.


Moc díky za informace, teď si projdu Learning TADS od Erica Eveho a prozkoumám volně dostupné zdrojáky her SampleGames.zip . Máš pravdu, jako neprogramátor musím nejdříve začít s deklarací předem připravených místností a objektů, to už jsem testoval minule právě na tom Exoterovi, ale dost ad hoc a vlastně jsem ani nechápal jaký kód vlastně píšu. A já bych rád programoval něco, co mě bude opravdu bavit a čím třeba potěším i ostatní, právě TADS vše krásně skloubí a díky Tvé sérii jsem pochopil jeho obrovské možnosti, jsem moc zvědav, co mi ukáže Learning TADS.

Díval jsem se na textovky, zkusím The Elysium Enigma od Eveho a Return to Ditch Day spolu s The Plant od Robertse, zde mám k dispozici i zdrojáky.

Jdu tvořit a určitě se budu ptát, už se těším...
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 22. Březen 2017 - 11:32
Tak jsem se pomalu pustil do práce, hlídám nemocnou dcérenku, ale ve volných chvílích studuji manuál od Eveho a několikrát ten Tvůj, připravuji zatím Exoteří lokace a jejich propojení. Ještě bych se rád zeptal na jednu drobnost, abych se vyznal v místnostech a jejich pojmenování, potřebuji si připravit mapu. V dokumentaci TADSu jsem nenašel, zda přímo Workbench něco podobného podporuje a zatím využívám Dungeon Crafter. Ve WINE spustím starší verzi 1.41 i zatím nejnovější 3 Silver, v první vidím paletu nástrojů, ale pod emulátorem mi nefunguje export výsledné mapy, naopak u 3 export funguje bez problémů, ale nevidím paletu nástrojů, ufff, tohle opravdu zamrzí. Zatím to řeším tak, že v jedničce udělám snímek obrazovky a ten oříznu GIMPem.

Jinak po aktualizaci Wine na dvojkovou řadu se Workbench zdá být stabilní, hurá.

Jak si u Základny řešil mapu pod Linuxem? Neznáš elegantnější řešení?
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 22. Březen 2017 - 12:39
Na rozdíl od Inform7, které má i nástroje pro vykreslení mapy (myslím automaticky ze zdrojáku), tak Workbench připomíná spíš běžné programátorské vývojové prostředí a tyto věci jsou mimo jeho oblast zájmu. Existuje program Trizbort (http://trizbort.genstein.net/ (http://trizbort.genstein.net/)), který je však windowsový. Měl by ale umět do jisté míry zpracovat log hry a mapu automaticky vytvořit. Ovšem asi jen v angličtině. Pak ještě vím o IFMapperu (http://ggarra13.github.io/ifmapper/en/start.html (http://ggarra13.github.io/ifmapper/en/start.html)), ale ani s ním nemám přímou zkušenost.

Já osobně jsem to totiž neřešil v podstatě nijak, mapu jsem měl natolik malou, že jsem si ji pamatoval. Stanovil jsem si, že budu cílit na zhruba dva tucty lokací, což pro mě byl rozumný rozsah hry, aby se i hráč v ní dobře vyznal. Pro kolegy jsem pak nakonec i jednoduchou mapu nakreslil v rámci nástrojů, které má OpenOffice, byla rozdělena na část lodi, základnu horní patro, spodní patro a koncovou část v tunelech. Kdybych chtěl něco hezčího, tak bych ji kreslil v Inkscapu.

Spíš co jsem řešil, tak že jsem organizoval zdrojáky tak, aby každá místnost měla samostatný soubor, aby se ve všem dalo rychle zorientovat a snadno přecházet mezi různými místnostmi. Totiž když je vše pohromadě v jednom souboru a je tam už hodně objektů, tak je to hodně rolování a blbě se hledá, kde člověk má nějaký objekt. Navíc TADS kompiluje jen nezbytně nutné soubory, ve kterých nastala změna, takže se šetří čas.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 24. Březen 2017 - 12:30
Díky moc za info, Trizbort jsem vyzkoušel a ve WINE funguje, jen ten zpropadený export zlobí - v obrázku se zobrazí jen názvy lokací a ohraničení už ne. IFMapper je v tuto chvíli na serveru nedostupný, zkusím v pondělí. Takže zatím budu testovat Dungeon Crafter a Trizbort s využitím snímku obrazovky, je pravda, že u menšího počtu lokací to bude zcela dostačovat.

Já jsem si zatím vzal kostru zdrojáku Heidi.t, do které se snažím dosazovat místnosti, uznávám ale, že to asi nebude zrovna ideální řešení a Tvé rozdělení u Základny bude vhodnější. Připravím si tedy podobné soubory roomXXX.t jako máš ty a zkusím je zpočátku propojit, spolu s jednoduchou mapou bude pro mě vše parádně přehledné. Nemám holt alespoň zatím ty správné programátorské návyky, to ale přijde časem. Plus rychlost kompilace je pro mě důležitá, dělám teď na deset let starém armádním notebooku, takže to sakra ocením.

Přes víkend mám akci s řechtáky, ale dcérenka už je zdravá, takže se k TADSu konečně více dostanu a dám vědět jak se zadařilo plus určitě bude pár dotazů.

Příjemný víkend přeje Orel

Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 20. Duben 2017 - 12:36
V příloze zasílám svůj první výtvor. Celý původní Exoter jsem dohrál a veškeré popisy místností, předmětů a hlášek jsem připravil do souboru Exoter.t. Ještě mě čekají hlášky, které se objevují v některých místnostech, na ty se zaměřím až na konec. Zkusil jsem připravit konektory místností a doplnit i pár předmětů. Hnedle na počátku je třeba dostat se z první místnosti mříží, nevím, zda je mé řešení takto OK, trochu kostrbaté, ale funguje. Vše, co chybí, by mělo být v komentářích, nyní se zaměřím právě na jejich obsah. Místnosti jsou nyní již přístupné, čeká mě hlavně doplnění předmětů a omezení u dveří. Původně jsem plánoval udělat pro každou místnost samostatný soubor, jen mi to alespoň zatím přijde nepřehledné, takže zatím zůstanu u zdrojáku jediného.

Největší problém jsem měl s kódováním. Text vkládám v linuxovém GVimu a poté testuji debuggerem přes Workbench. Ze mě nepochopitelného důvodu jej GVim zobrazuje a na první pohled ukládá správně, po dalším načtení se ale znaková sada pokazila tak, že jsem soubor již nemohl otevřít ani v Linuxu ani ve Win. Můžeš se juknout na soubor Aktuální popis místností a lokací.txt, ke psanému textu jsem se nedostal ani pomocí UTF-8, ani žádného kódování pro DOS nebo Windows. Takže jsem všechna chybně se zobrazující nabodeníčka poctivě ručně přepsal, uff, hlavně, že jsem zatím jen u malého textu. Nyní edituji v Kate a vše raději ještě ukládám do pdf pro jistotu, naštěstí i on zná TADS syntaxi. Debugger však potřebuji, odhalil opravdu všechny syntaktické chyby a že jich bylo. Už vůbec nebudu pokoušet windows-1250, možná byl problém i zde, při utf-8 vše Workbench a především FrobTADS správně přeloží, i když se v něm u háčků a čárek zobrazují paznaky a např. znak "ř" nemohu vkládat vůbec. Měl jsi s kódováním taky takové bolesti?

Výsledný exe soubor jsem bez problémů spustil ve Wine a t3 zkompilovaný z Frobtadsu pomocí QTads, vše parádně funguje a s češtinou problém není. Konzolový frob také jede a pokud oželím nabodeníčka, funguje v ncurses režimu parádně a to i ve skutečné konzoli, nejen v terminálu. Čeština se mi v tomto režimu ani nezobrazuje, takže nevidím žádné blikající znaky, nyní jedu na Q4OS na svém armádním stroji. Právě jsem zkusil Tebou popisovaný přepínač -i plain -k utf8 a hurá, jako plaintext je vše v pořádku, tohle se mi moc líbí, určitě podobnou možnost využiji na Raspberry, ostatně dříve se takhle hrály BSDGames na terminálech serverů, pokud je pravda, co staří unixáci píšou.

Exoter bych moc rád nechal tak jak je, ještě si musím rozmyslet, zda i s tou otravnou smrtí, když vlezu do místnosti bez správného předmětu, chápu ale, že tohle "vylepšení" sloužilo ke ztížení jinak dosti krátké hry. Teď se zase vrhnu na Tvůj a Eveho manuál a budu si hrát s předměty plus jejich interakcí, zase dám vědět, až se dostanu o něco dále. Až se s principy TADSu více seznámím a zmáknu Exotera, rád bych se vrhnul na můj veleoblíbený Bad Night, ten už si ale lapnu jen jako inšpiraci a mám v plánu jej mohutně rozšířit včetně těch parádních atmosférických hlášek, tahle moje nej textovka na Spectrum si to určitě zaslouží. A text typu "jak do místnosti pronikají krásným mozaikovým oknem mihotavé paprsky světla" ze Tvého návodu zde využiji opravdu velmi často, moc se těším. No a poté zkusím prvního a konečně i druhého Orla... Ještě jednou díky za manuál, bez něj bych se do TADSu asi nikdy nepustil.

Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 20. Duben 2017 - 14:28
V příloze zasílám svůj první výtvor.
Proběhnul jsem to a pár postřehů posílám níže:

Řádka 34: Před "me" bys neměl mít plus, když zároveň nastavuješ location na kobku. Plus je totiž jen zkratka zastupující nastavení vlastnosti location. V tomto případě by plus znamenalo, že se location nastaví na gameMain, ale to by nedávalo smysl.

Řádka 44: Většinou se dává přednost nepsat otevírací a zavírací složenou závorku na úrovni objektu a místo toho ukončit definici objektu středníkem podobně, jako jsi výše definoval objekt Actora. Možné je oboje, ale není přehedné míchat styl v rámci jednoho zdrojáku. Také 'Kobka' můžeš napsat prostě v rámci šablony stejně, jako u chodby níže, tj. bez uvádění vlastnoosti roomName =. Podobně místo psaní desc = "" stačí naspat jen text ve dvojitých uvozovkách.

Řádka 51: Při výpisu zpráv pomocí dvojitých uvozovek je dobrým zvykem na konci věty po tečce nechat mezeru, jako to máš u desc výše. Je to proto, že TADS často hlášky kombinuje a doplňuje a mohl by vytisknout něco dalšího za tvým řetězcem a chyběla by pak mezera mezi větami. Ne, že by to byl tento případ, ale je to dobrý zvyk tak psát všechny zprávy.

Řádka 64: Objevení pilníku v mrtvole lze i méně otrocky, až budeš mít náladu, tak si prostuduj Hidden a PresentLater objekty. A asi by nebylo špatné použít RestrictedContainer, aby se do mrtvoly nedaly odkládat jiné objekty.

Řádka 89: Vlastnost noun nic neznamená. Nastavuj name a gcName pro zobrazené jméno a vocabWord a gcVocab pro slovník parseru. Nezapomeň, že správně a dokonale to bude fungovat až tehdy, když si dáš práci a zadáš všechno skloňování. Podobně u pochodně.

Na různých místech: Značka \n značí zalomení řádky, ale \b nebo <.p> je zalomení odstavce. Záleží, co chceš, ale přijde mi, že takové to zalamování řádek bez nového odstavce není přehledné a neodpovídá zbytku výpisu.

Původně jsem plánoval udělat pro každou místnost samostatný soubor, jen mi to alespoň zatím přijde nepřehledné, takže zatím zůstanu u zdrojáku jediného.

Pokud hra není příliš rozsáhlá, tak proč ne, ale hodilo by se místnosti oddělit třeba čarou vytvořenou z komentářových znamének, nebo tak. Já jsem to rozsypával do více souborů, protože objektů bylo hodně a měl jsem problém přecházet mezi a hledat, kde v souboru je určitá část.

Každopádně ale na sebe zkus být přísnější ohedně formátování zdojáku, aby byl jednotnější a přehlednější.

Největší problém jsem měl s kódováním. Text vkládám v linuxovém GVimu a poté testuji debuggerem přes Workbench. Ze mě nepochopitelného důvodu jej GVim zobrazuje a na první pohled ukládá správně, po dalším načtení se ale znaková sada pokazila tak, že jsem soubor již nemohl otevřít ani v Linuxu ani ve Win. Můžeš se juknout na soubor Aktuální popis místností a lokací.txt, ke psanému textu jsem se nedostal ani pomocí UTF-8, ani žádného kódování pro DOS nebo Windows. Takže jsem všechna chybně se zobrazující nabodeníčka poctivě ručně přepsal, uff, hlavně, že jsem zatím jen u malého textu. Nyní edituji v Kate a vše raději ještě ukládám do pdf pro jistotu, naštěstí i on zná TADS syntaxi. Debugger však potřebuji, odhalil opravdu všechny syntaktické chyby a že jich bylo. Už vůbec nebudu pokoušet windows-1250, možná byl problém i zde, při utf-8 vše Workbench a především FrobTADS správně přeloží, i když se v něm u háčků a čárek zobrazují paznaky a např. znak "ř" nemohu vkládat vůbec. Měl jsi s kódováním taky takové bolesti?

Ten .txt soubor má zmršené kódování, ve windows-1250 rozhodně není. Workbench bohužel neumí zobrazit a editovat Unicode, je to známá chyba, která nebude opravena, je to nějak moc složité. Zabudovaný editor Scintilla by utf uměl, ale zbytek workbenche ne. Debugovat se to dá, ale nesmíš to editovat.

Pro odhalení syntaktických chyb stačí překladač, debugger (krokování kódu příkaz po příkazu) je fajn, ale většinou není potřeba.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 2. Květen 2017 - 13:07

Moc díky za postřehy, své poznámky posílám se znakem komentáře a na konci budou další dotazy a postřehy:

Řádka 34: Před "me" bys neměl mít plus, když zároveň nastavuješ location na kobku. Plus je totiž jen zkratka zastupující nastavení vlastnosti location. V tomto případě by plus znamenalo, že se location nastaví na gameMain, ale to by nedávalo smysl.

//Aha, sakra, myslel jsem si, že plus bylo i ve zdrojáku Heidi a bez přemýšlení jsem jej okopíroval, buď jsem jej viděl jinde nebo jsem si všiml, že je uvedeno u věcí, které má zpočátku na sobě a to mě zmátlo - jasné, pokud nastavuji lokaci, nemá smysl.

Řádka 44: Většinou se dává přednost nepsat otevírací a zavírací složenou závorku na úrovni objektu a místo toho ukončit definici objektu středníkem podobně, jako jsi výše definoval objekt Actora. Možné je oboje, ale není přehedné míchat styl v rámci jednoho zdrojáku. Také 'Kobka' můžeš napsat prostě v rámci šablony stejně, jako u chodby níže, tj. bez uvádění vlastnoosti roomName =. Podobně místo psaní desc = "" stačí naspat jen text ve dvojitých uvozovkách.

//Tady je vše jasné, místnost Kobka jsem zkopíroval ze šablony z manuálu, kde použili plný zápis a ty další místnosti už jsem si zjednodušil. Každopádně názvy i popisy místností musím sjednotit a hned si na to zvyknout. Nejprve jsem otevřené závorky zkusil vymazat, debugger ale nepochopil jak interpretovat mříž, takže jsem je vrátil na úroveň objektu, pokud je to takto správně.

Řádka 51: Při výpisu zpráv pomocí dvojitých uvozovek je dobrým zvykem na konci věty po tečce nechat mezeru, jako to máš u desc výše. Je to proto, že TADS často hlášky kombinuje a doplňuje a mohl by vytisknout něco dalšího za tvým řetězcem a chyběla by pak mezera mezi větami. Ne, že by to byl tento případ, ale je to dobrý zvyk tak psát všechny zprávy.

//Aha, stejný případ jako minule, desc u popisu Actora jsem zkopíroval ze šablony a jak vidím, u popisu mříže, pilníku a mrtvoly také, souhlasím, zvyknu si na tento zápis už zpočátku.

Řádka 64: Objevení pilníku v mrtvole lze i méně otrocky, až budeš mít náladu, tak si prostuduj Hidden a PresentLater objekty. A asi by nebylo špatné použít RestrictedContainer, aby se do mrtvoly nedaly odkládat jiné objekty.

//Rozumím, RestrictedContainer je určitě vhodnější, odkládat cokoliv do mrtvoly už nepůjde. Zkusil jsem použít hidden, více níže v dotazech.

Řádka 89: Vlastnost noun nic neznamená. Nastavuj name a gcName pro zobrazené jméno a vocabWord a gcVocab pro slovník parseru. Nezapomeň, že správně a dokonale to bude fungovat až tehdy, když si dáš práci a zadáš všechno skloňování. Podobně u pochodně.

//Pokusil jsem se doplnit skloňování, budu testovat přímo ve hře.

Na různých místech: Značka \n značí zalomení řádky, ale \b nebo <.p> je zalomení odstavce. Záleží, co chceš, ale přijde mi, že takové to zalamování řádek bez nového odstavce není přehledné a neodpovídá zbytku výpisu.

//Souhlasím, zalomení \b vypadá v textu lépe, upravil jsem tak všechny texty, kde toto dává smysl.

Citace: Kroužící orel  20. Duben 2017 - 12:36

    Původně jsem plánoval udělat pro každou místnost samostatný soubor, jen mi to alespoň zatím přijde nepřehledné, takže zatím zůstanu u zdrojáku jediného.

Pokud hra není příliš rozsáhlá, tak proč ne, ale hodilo by se místnosti oddělit třeba čarou vytvořenou z komentářových znamének, nebo tak. Já jsem to rozsypával do více souborů, protože objektů bylo hodně a měl jsem problém přecházet mezi a hledat, kde v souboru je určitá část.

Každopádně ale na sebe zkus být přísnější ohedně formátování zdojáku, aby byl jednotnější a přehlednější.

//Naprosto souhlasím, že sjednotit formátování zdrojáku je velmi důležité. Začal jsem světovými stranami a popisy východů z lokací, budu se držet směrů S, V, J, Z, N a D v celém textu. Zatím ponechám jediný zdrojový soubor, oddělení místností komentáři je super nápad, vyzkouším.

Citace: Kroužící orel  20. Duben 2017 - 12:36

    Největší problém jsem měl s kódováním. Text vkládám v linuxovém GVimu a poté testuji debuggerem přes Workbench. Ze mě nepochopitelného důvodu jej GVim zobrazuje a na první pohled ukládá správně, po dalším načtení se ale znaková sada pokazila tak, že jsem soubor již nemohl otevřít ani v Linuxu ani ve Win. Můžeš se juknout na soubor Aktuální popis místností a lokací.txt, ke psanému textu jsem se nedostal ani pomocí UTF-8, ani žádného kódování pro DOS nebo Windows. Takže jsem všechna chybně se zobrazující nabodeníčka poctivě ručně přepsal, uff, hlavně, že jsem zatím jen u malého textu. Nyní edituji v Kate a vše raději ještě ukládám do pdf pro jistotu, naštěstí i on zná TADS syntaxi. Debugger však potřebuji, odhalil opravdu všechny syntaktické chyby a že jich bylo. Už vůbec nebudu pokoušet windows-1250, možná byl problém i zde, při utf-8 vše Workbench a především FrobTADS správně přeloží, i když se v něm u háčků a čárek zobrazují paznaky a např. znak "ř" nemohu vkládat vůbec. Měl jsi s kódováním taky takové bolesti?

Ten .txt soubor má zmršené kódování, ve windows-1250 rozhodně není. Workbench bohužel neumí zobrazit a editovat Unicode, je to známá chyba, která nebude opravena, je to nějak moc složité. Zabudovaný editor Scintilla by utf uměl, ale zbytek workbenche ne. Debugovat se to dá, ale nesmíš to editovat.

Pro odhalení syntaktických chyb stačí překladač, debugger (krokování kódu příkaz po příkazu) je fajn, ale většinou není potřeba.

//Přesně tak, nyní využívám k editaci souboru KATE nebo GVIM s tím, že Workbench se vždy sám zeptá, zda chci změněný soubor aktualizovat. Pokud souhlasím, krokování kódu proběhne v pořádku ať už s chybami nebo bez nich, co naplat, hlavně, že o tom vím a nebude se opakovat ta nepříjemná zkušenost.

A nyní mé dotazy:

Při debuggování bych si potřeboval uložit pozici a testovat hru z konkrétní místnosti. Když ale hru ukončím a znovu zkompiluji, uložený soubor není kompatibilní. Je tu nějaká lepší možnost testování ve Workbenchi?

Zkoušel jsem použít na mrtovlu direktivu RestrictedContainer a Heavy, právě při použití Heavy není ve hře vidět, ale lze jí prozkoumat, dělám něco špatně? Po vymazání Heavy je zase vše OK.

Pokusil jsem se pilník definovat jako hidden, ale bez úspěchu, v takovém případě se sice zobrazí při zadání příkazu "koukni se do mrtvoly", ale následně prozkoumat ani sebrat nelze. Rád bych také místo otrockého příkazu "odemkni mříž" použil "přepiluj mříž". Pokud budeš mít chvilku, prosím koukni se na definici objektů mriz, mrtvola a pilnik, nyní si vůbec nejsem jist, zda tato definice není celá špatně. Prozkoumal jsem zdrojový kód Základny, hidden objektů je zde mnoho, nejpodobnější jsem nalezl v souboru roomAlien.t, po použití definice objektu sheet jsem se dál nedostal.

Kromě hidden objektů mě čeká nastudovat chování strážce a po jeho zabití manipulace s jeho předměty, podobné to bude i u draka a psa, rozsvícecní pochodně ve studni (o tom píšeš v návodu, takže by neměl být problém), naprogramování akce pádu do kupky sena nebo hráčovy smrti, pokud tam není. Dveře by měly být OK, ještě musím vyřešit omezení přechodu do lokace před jejich odemknutím, to nastiňuješ v manuálu, juknu se ještě na příklady v Heidi a u Eveho. Slovník předmětů jsem definoval, zatím jsem nepoužil pomnožný tvar. Mříž a pilník tedy zatím nechám být a budu se věnovat výše popsanému.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 2. Květen 2017 - 21:15
Nejprve jsem otevřené závorky zkusil vymazat, debugger ale nepochopil jak interpretovat mříž, takže jsem je vrátil na úroveň objektu, pokud je to takto správně.

Jsou dvě možnosti, jak deklarovat objekt a Eric obě na začátku knížky popisuje. Buď se použije otevírací i uzavírací složená závorka na úrovni objektu, nebo se místo nich použije jen středník označující konec objektu. Druhý způsob je obvyklejší v praxi, protože je úspornější a přehlednější. Je dobré si na něj zvyknout, protože ho najdeš prakticky výhradně v dalších kapitolách knihy a a příkladech a rozšířeních stáhnutých z internetu. Tedy v tvém případě by to znamenalo první otevírací závorku vymazat a zavírací také vymazat a místo ní dát středník.

Pokusil jsem se doplnit skloňování, budu testovat přímo ve hře.

Jen u gcName na rozdíl od gcVocab musíš zadat pády, i když se opakují. Konkrétně v pořadí 2, 3, 4, 6, 7, tedy např. gcName = 'mříže, mříži, mříž, mříži, mříží'.

Při debuggování bych si potřeboval uložit pozici a testovat hru z konkrétní místnosti. Když ale hru ukončím a znovu zkompiluji, uložený soubor není kompatibilní. Je tu nějaká lepší možnost testování ve Workbenchi?

Při zkompilování hry vznikne vlastně "nová hra", která není co se týče uložených pozic kompatibilní s tou původní. Je to nutný důsledek toho, jak ukládání pozic a UNDO v TADSu funguje. Tyto funkce jsou vytvořené na nízké úrovni a pracují s binární reprezentací objektů v paměti virtuálního stroje. Uložená hra je vlastně obrazem paměti (tj. stav objektů), přesněji řečeno je to rozdíl oproti výchozímu stavu hry, který je uložený v samotném souboru s hrou.

Přímo Workbech má funkci, že když hraješ hru, tak nahrává jednotlivé příkazy do souboru a příště jedním dvojklikem můžeš celé sezení přehrát a podívat se, jak se hra změnila. Nebo příkazem >přehraj 'soubor' můžeš interaktivně přímo ve hře nechat přehrát soubor s příkazy. Já osobně ve Workbenchi běžně nepracuji, ale mám udělaný skript, který mi hru tímto způsobem otestuje a rovnou mi zobrazí změny oproti poslednímu průchodu, který považuji za správný:

Kód: [Vybrat]
#!/bin/sh

t3make -d
frob -i plain -k utf8 --no-pause -S -c -e 1000 -R testCommands.txt asteroid.t3 > testOutput.txt
diff -Nur testTranscript.orig testTranscript.txt > testTranscript.diff
kwrite testTranscript.diff

potom mám soubor s příkazy, do nějž postupně doplňuji cokoliv, co chci vyzkoušet, ten vypadá např.:

Kód: [Vybrat]
>zapni zápis
>testTranscript.txt
>restart
>a
>nápověda
>o hře
>kontrola překlepů
>zapni kontrolu překlepů

Na začátku hry jsme ve své kajutě.

>p sebe
>zhasni
>p dozimetr
>p ventily
>přemýšlej
>na 20
>přemýšlej o věčnosti

atd., u Základny má přes 2000 příkazů. Když jsem s výsledkem spokojený, tak překopíruji obsah souboru testTranscript.txt do souboru testTranscript.orig a tím vytvořím novou bázi pro hledání změn. Po každé úprave programu spustím ten výše uvedený skript, hra se přeloží a za chvíli mám před očima rozdíl v kwritu:

Kód: [Vybrat]
@@ -2138,8 +2182,8 @@
 >rozsvitit displej tabletu
 Zmáčkl jsi tlačítko a displej se rozzářil. Na obrazovce tabletu je zobrazena
 hra Dělostřelecký souboj. Na nádherně malované krajině v hyperrealistickém 2D
-zobrazení stojí dvě děla. Hra ukazuje, že děla jsou od sebe 10 km daleko a
-čeká, až zadáš úhel hlavně, pod kterým chceš vystřelit. (např. ZADEJ 45)
+zobrazení stojí dvě děla. Hra čeká, až zadáš úhel hlavně, pod kterým chceš
+vystřelit.

 Servisní šachta
 Jsi v servisní šachtě. Tudy vedou kabely z přední části lodi s řídicím

Sice je trochu otrava s náhodnými akcemi, ale i tak je to fajn a rychlé řešení, vlastně jsem při vývoji hru interaktivně skoro nikdy nehrál.

Zkoušel jsem použít na mrtovlu direktivu RestrictedContainer a Heavy, právě při použití Heavy není ve hře vidět, ale lze jí prozkoumat, dělám něco špatně? Po vymazání Heavy je zase vše OK.

Heavy je třída poděděná z Immovable a ta zase z NonPortable. Tyto třídy slouží typicky k reprezentaci různých pevných součástí lokace, jako je nábytek, lustr na stropě apod., které se nevypisují v rámci rozhlédnutí v místnosti, protože se předpokládá, že to není běžný objekt, který by si hráč mohl odnést.

Když pracuješ s nějakou třídou, kterou ještě moc neznáš, tak je fajn se podívat na její definici do referenční příručky: http://www.tads.org/t3doc/doc/libref/index.html (http://www.tads.org/t3doc/doc/libref/index.html) Po levé straně vyhledáš Heavy v seznamu tříd, klikneš a podíváš se na vlastnosti a metody, které třída definuje. Úplně nejlépe se pak můžeš prokliknout přímo do zdrojáku kliknutím na číslo řádky v pravém horním rohu, zde objects.t[2054]:

Kód: [Vybrat]
/*
 *   Heavy: an object that's immovable because it's very heavy.  This is
 *   suitable for things like large boulders, heavy furniture, or the like:
 *   things that aren't nailed down, but nonetheless are too heavy to be
 *   carried or otherwise move.
 *
 *   This is a simple specialization of Immovable; the only thing we change
 *   is the messages we use to describe why the object can't be moved.
 */
class Heavy: Immovable
    cannotTakeMsg = &cannotTakeHeavyMsg
    cannotMoveMsg = &cannotMoveHeavyMsg
    cannotPutMsg = &cannotPutHeavyMsg
;

Vidím, že se zde nastavují jen hlášky, tak zatočím kolečkem a podívám se výše (nebo najdu přes seznam) a podívám se na Immovable. Tam toho je trochu více, upravují se akce, ale když vyhledám ještě dalšího předka, tak najdu:

Kód: [Vybrat]
class NonPortable: Thing
    /*
     *   An immovable objects is not listed in room or container contents
     *   listings.  Since the object is immovable, it's in effect a
     *   permanent feature of its location, so it should be described as
     *   such: either directly as part of its location's description text,
     *   or via its own specialDesc.
     */
    isListed = nil
    isListedInContents = nil
    isListedInInventory = nil

Všimni si, že právě tady mají tyto objekty definováno, že na rozdíl od běžných přenosných objektů třídy Thing se nemají vypisovat ani v místnosti, ani v inventáři atp. A pokud bys chtěl, tak to můžeš zvrátit, nastavit některou z vlastností u své mrtvoly zpátky na true. Druhý mechanismus, který můžeš využít pro popis objektu, který je v místnosti důležitý a je potřeba ho zmínit, tak je nastavení vlastnosti specialDesc, viz příklady v Základně.

Pokusil jsem se pilník definovat jako hidden, ale bez úspěchu, v takovém případě se sice zobrazí při zadání příkazu "koukni se do mrtvoly", ale následně prozkoumat ani sebrat nelze.

Existují dva vzájemně se deoplňující způsoby, jak zacházet se skrytými objekty. Třída Hidden a PresentLater. Nevím, co přesně a jak jsi zkoušel, našel jsem ve zdrojáku zhruba tohle:

Kód: [Vybrat]
+ mrtvola : RestrictedContainer 'mrtvola' 'mrtvola' *3
;

pilnik : Key 'pilník' 'pilník' *2
;

Doporučil bych ti přidat Hidden třídu, tj. deklarovat pilník jako Key, Hidden. Tím způsobem bude objekt skrytý před zraky, jako by ve hře nebyl, dokud nebude objeven. Hidden má ještě jednu vlastnost a sice že takové objekty hráč automaticky nalezne, pokud prohledá kontejner (>podívej se do mrtvoly).

Aby ti to fungovalo, musíš udělat ještě jednu důležitou věc - musíš pilník umístit do mrtvoly. To uděláš tak, že přidáš dvojici znamének plus před deklaraci objektu. Dvě proto, že mrtvola má znaménko jedno a místnost žádné, tedy mrtvola je v místnosti a pilník v mrtvole. Když není znaménko žádné, tak pilník existuje, ale není nikde ve hře umístěn. Podobně by to fungovalo u PresentLater, jen bysis tam musel sám objekt zviditelnit při prohledání. Ale v obou případech platí to o nutnosti psát známénka plus. Podobně na konci zdrojáku nemáš provaz v truhle.

Zahlédl jsem ve zdrojáku také poznámku "nevím, zda má smysl dobjFor(Search) asDobjFor(LookIn)". Kdybys po tom pátral, tak najdeš, že u Thing je právě tohle udělané a Container to trochu mění v tom smyslu, že akce Search (>prohledej něco) na rozdíl od LookIn (>podívej se do něčeho) má malinko upravené podmínky a na rozdíl od nahlédnutí vyžaduje, aby se postava předmětu mohla dotýkat. Ale to je pro tebe nezajímavý detail, takže nemusíš přesměrovávat akci.

Rád bych také místo otrockého příkazu "odemkni mříž" použil "přepiluj mříž". Pokud budeš mít chvilku, prosím koukni se na definici objektů mriz, mrtvola a pilnik, nyní si vůbec nejsem jist, zda tato definice není celá špatně.

To je pak něco jiného. V tom případě by se asi hodilo přepilování modelovat jako samostatnou akci a vůbec nebrat pilník jako klíč ke dveřím. Co se týče "dveří", které se nedají otevírat hráčem jako běžné dveře, ale mají nějakou formu externího ovládání, tak to viz dveře přechodové komory v Základně. Co se týče přepilování, tak viz některou definici nového příkazu, ale to je trochu pakárna, tak bych si to schoval, až budeš jistější.

Stručně chce to definovat akci a k ní VerbRule. Potom modify Thing a definovat základní chování příkazu se všemy objekty (něco jako hlášku Tohle není něco, co bys mohl přepilovat) a selektivně povolit u žádaných objektů. Aby to bylo dokonalé, tak to chce TAction i TIAction, aby reagovalo na >přepiluj mříž, >piluj pilníkem i >přepiluj mříž pilníkem. U té poslední varianty je ještě problém s tím, že ji lze říci v obou pořadích slov, takže musíš pořešit, aby parser nepochpil, že má mříží přepilovat pilník, viz debata s Tekketem.

Slovník předmětů jsem definoval, zatím jsem nepoužil pomnožný tvar.

Pomnožné jsou např. typicky dveře, těm bys měl nastavit isPlural = true. Když to neuděláš, tak bude hra špatně reagovat, když napíšeš příkaz >prozkoumej dveře a vzápětí zkusíš >otevři je, tak parser nebude vědět, že slovem "je" se odvoláváš na dveře.

+ drahokam_1 : Thing 'drahokam č. 1' 'drahokam č. 1' *2
  "Je nádherný. "
    gcName = 'drahokamu č. 1, drahokamu č. 1, drahokam č. 1'
    gcVocab = 'drahokamu č. 1/drahokamu č. 1/drahokam č. 1'
;

Tady pozor, takhle nemůžeš zapsat slovník. Jednak si nejsem jistý, jestli parser rozdejchá tečku za "č", ale hlavně když se zapisuje několik synonym, tak nemůžeš psát delší frázi lomeno delší frází. Vždy to je ve formátu "přídavné přídavné podstatné/podstatné*množné", takže gcVocab = 'drahokamu' a nahoře v šabloně 'drahokam (č.) 1'. Závorky označují nespecifickou část slovníku, tedy slova, která když jsou použita samotná, tak nejsou brány jako shoda, protože jsou moc slabá.

Nicméně vřele bych se doporučil těmto problémům úplně vyhnout např. označením 'první diamant' apod.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 4. Květen 2017 - 11:33
Citace: Kroužící orel   2. Květen 2017 - 13:07
deklarace objektu
//Ano, na straně 11 jsem tuto informaci našel přesně tak jak píšeš. Nyní již používám všude zkrácený zápis s ukončovacím středníkem. A právě zde jsem v příkladu s první hrou našel direktivu noun, kterou jsem dříve používal, aniž bych věděl, co znamená.

Citace: Kroužící orel   2. Květen 2017 - 13:07
Pokusil jsem se doplnit skloňování, budu testovat přímo ve hře.
Jen u gcName na rozdíl od gcVocab musíš zadat pády, i když se opakují. Konkrétně v pořadí 2, 3, 4, 6, 7, tedy např. gcName = 'mříže, mříži, mříž, mříži, mříží'.
// Rozumím, opakující se pády jsem zadat zapomněl, ale máš pravdu, v manuálu píšeš o nutnosti zadat všechny pády. Všude opraveno. Je to sice pracné, ale musím uznat, že pocit z parádní češtiny na Základně stál za to, nedivím se, že právě zde kladeš takový důraz. Jo, musím se přiznat, že jsem si pády musel pořádně zopakovat, už jsem pár let ve škole nebyl...

Citace: Kroužící orel   2. Květen 2017 - 13:07
debug a uložení pozice ve WB
// Tohle je moc zajímavé jak píšeš práci s pozicemi. Jestli dobře rozumím, využívá se zde malý virtuální stroj podobně jako v javě – uložená hra je tedy obraz aktuální paměti, který rekompilací ztrácím. Mě se hned od začátku seznámení se s TADSem líbila možnost UNDO, na kterou nejsem z našich textovek zvyklý, teď už vím odkud vítr fouká…
Pořádně jsem se podíval do manuálu k Workbenchi, v sekci Scripting and Auto-Scripting jsem našel přesně to, co jsem hledal. Nyní k testování využívám automaticky generované skripty s příponou cmd – ty mohu vyvolat i po překompilování hry a je to asi nejpohodlnější způsob, v samotném Workbenchi se zobrazují správně i s diakritikou na rozdíl od jejich ručního otevření v Linuxu. Skriptovací funkce naštěstí pod emulovaným WB fungují bezchybně a moc mi testování ulehčuje, hurá.
Ale Tvůj skript je taky bezva řešení, hnedle jsem si říkal, že ty soubory testTranscript a testPlay v Základně nebudou jen tak pro nic za nic.  Skoro 700kb textu, to by bez tohodle mechanizmu otestovat opravdu nešlo. Upravil jsem jej pro Exoter a funguje parádně, je to super možnost i pro příkazovou řádku. Zajímalo mě, zda testCommands.txt schroupne i češtinu, naštěstí výsledný testOutput.txt jí zobrazuje naprosto bez problémů, jasné, tady je opravdu potřeba direktiva frob -i plain -k utf8.

Citace: Kroužící orel   2. Květen 2017 - 13:07
Zkoušel jsem použít na mrtovlu direktivu RestrictedContainer a Heavy
// Aha, tady narážím na své limity, protože programování šlo prozatím zcela mimo mě. A přitom ve svém manuálu o TADS 3 Library Reference Manual píšeš. Je parádně zpracovaný, prozkoumal jsem kromě Heavy i další, super příručka, už se stahuje wgetem, ať nemusím být vždy závislý na připojení. Stále čtu o vlastnostech, metodách, třídách a objektech, ovšem abych plně vše pochopil, musím začít na příkladech a právě tento manuál je to pravé. Moc se mi líbí ta možnost proklikat se do zdrojáku – nemusím zdlouhavě procházet objects.t, ale hned vidím číslo řádky. Tady vidím class Heavy: Immovable – takže pokud to dobře chápu, Heavy je potomek třídy Immovable, kterou rozšiřuje dalšími parametry a zachovává si všechny její vlastnosti. A nad CustomImmovable nacházím class Immovable: NonPortable plus ouplně nahoře je hlavní třída Thing, teď už je to jasné.
Takže jsem upravil mrtvolu jako RestrictedContainer, Heavy a přidal direktivu isListed = true
Teď už se chová jak má, tohle je opravdu cenná praktická zkušenost.

Citace: Kroužící orel   2. Květen 2017 - 13:07
Pokusil jsem se pilník definovat jako hidden, ale bez úspěchu...
// Ano, zkoušel jsem před objekt pilník definovat dvakrát plus takto:

+ mrtvola : RestrictedContainer 'mrtvola' 'mrtvola' *3
++ pilnik : Key, Hidden 'pilník' 'pilník' *2

Ovšem situace je stále stejná, hráč po příkazu koukni se do mrtvoly sice pilník vidí, ale není možné jej sebrat. Po odstranění direktivy Hidden je vše v pořádku. Tady mě to docela mate, raději dopíšu celou definici:

+ mrtvola : RestrictedContainer 'mrtvola' 'mrtvola' *3
 "Je v pokročilém stádiu rozkladu. "
     gcName = 'mrtvoly, mrtvole, mrtvolu, mrtvole, mrtvolou'
     gcVocab = 'mrtvoly/mrtvole/mrtvolu'
   dobjFor(LookIn)
   {
      action()
      {
         if(pilnik.moved)
         {
            "Na mrtvole jsi neobjevil už nic zajímavého. ";
            exit
            ;
         }
            pilnik.moveInto(self);
                     "Bližší pohled na mrtvolu odhalil pilník schovaný v záhybech polorozpadlých šatů! ";
      }
   }
;

++ pilnik : Key, Hidden 'pilník' 'pilník' *2
       "Je šikovně upraven na přepilovávání mříží. "

       gcName = 'pilníku, pilníku, pilník, pilníku, pilníkem'
       gcVocab = 'pilníku/pilníku/pilník'
;

Laicky řečeno se mi zdá, že jsem v těle objektu mrtvola už pracuji se skrytým objektem pilník jiným způsobem a není tedy možné využít direktivu Hidden. Ovšem po jejím vymazání se jak jsem očekával v popisu místnosti zobrazí hláška Vidíš tu mrtvolu (která obsahuje pilník), což je také špatně. Takže jedině po vymazání dvou znamének plus vše funguje jak potřebuji, ale nerozumím jak, což není dobré – budeš po přečtení zdrojáku moudřejší? Jinak je dvojité znaménko jasné, doplnil jsem jej do provazu v truhle, kde samozřejmě nesmí chybět. Stejné je to např. u kupky sena, tam Tvůj návod funguje bez problémů. Tam ale budu potřebovat objevení jehly až po spálení sena, takže se podívám na změnu stavu objektu po konkrétní akci.

Se Search a LookIn je to jasné, u tohoto objektu nemusím tuto věc řešit.

Malá aktualizace – Tvé komentáře projíždím, testuji a snažím se vnímat postupně, vzpomněl jsem si na třídu Heavy a referenční manuál. Kouknul jsem se tedy na definici Hidden a nalezl zajímavou možnost „can be sensed“ na str. 906:

    canBeSensed(sense, trans, ambient)
    {
        /*
         *   If the sense is sight, and we haven't been discovered yet, we
         *   cannot be sensed.  Otherwise, inherit the normal handling.
         */
        if (sense == sight && !discovered)
            return nil;
        else
            return inherited(sense, trans, ambient);
    }

Pokud uvnitř if změním hodnotu nil na true, pilník je zase vidět, tato direktiva tedy upravuje vlastnost třídy Hidden a de facto jí neguje, jestli to dobře chápu. Tak jako tak se mi zatím nezadařilo objekt správně definovat, otázka zní, zda není zakopaný pes spíš v definici mrtvoly, než u pilníku.

Citace: Kroužící orel   2. Květen 2017 - 13:07
Rád bych také místo otrockého příkazu "odemkni mříž" použil "přepiluj mříž"...
// Rozumím, až se pohnu dále, juknu se na zdrojáky Základny, prozkoumám přechodové dveře a juknu do diskuze. Ohledně přepilování jak radíš raději počkám, až naberu více zkušeností, zatím podumám o elegantnějším řešení, v mrtvole může být třeba šperhák a na mříži zámek – sakra, tady ti naši autoři měli s příkazem použij sakra ulehčenou práci přesně jak píšeš v manuálu.

Citace: Kroužící orel   2. Květen 2017 - 13:07
Slovník předmětů jsem definoval, zatím jsem nepoužil pomnožný tvar.
// Paráda, zde jsem využil příklad z Heidi u dveří a použil na obě ve své hře, budu testovat.

Citace: Kroužící orel   2. Květen 2017 - 13:07
+ drahokam_1 : Thing 'drahokam č. 1' 'drahokam č. 1' *2...
// Naprosto souhlasím, sám jsem byl zvědav jak si s č. 1 interpretr poradí. Použil jsem označení první až čtvrtý drahokam, je to určitě lepší řešení.

---

Svůj projekt zase zasílám v příloze. Každopádně je paráda, že dokumentace k TADSu je tak rozsáhlá a je čeho se chytit, i když zpočátku je jí pro mě opravdu mnoho, člověk něco přečte a vzápětí zapomene, co naplat. Každopádně i u správy serverů ocením kvalitní dokumentaci, dříve jsem jí tak neřešil, ale u linuxu jsem bez ní nahraný, tady je parádní příklad wiki Archu nebo u světa BSD manuály k OpenBSD. Když projíždím zdrojáky Základny, zjišťuji, že jsem toho mnoho opomněl, je opravdu rozsáhlá a bezva zpracovaná.

Teď budu pokračovat dále, zkusím nadefinovat akci se strážcem a otestuji chování dveří, fakt nesmím nic uspěchat, ale snažit se pochopit co nejvíce jak tenhle bezva systém funguje. Jako neprogramátor to mám těžké, na druhou stranu skripty v pythonu a weby v php mě nikdy moc nechytly, raději vytvořím něco, co mě baví a to TADS beze zbytku splňuje.

Ale v první řadě oceňuji Tvojí pomoc, je paráda, že se mám koho zeptat a jak rychle reaguješ na mé  dotazy. Stejně se snažím reagovat i já, pokud se mě lidi zeptají na něco z oblasti Linuxu a umím jim pomoci. Dal jsi si obrovskou práci s překladem, se Základnou a teď i s vysvětlováním, tady je krásně vidět, že kvalitní systém je hlavně o lidech. Tím spíš se těším na další programování a objevování, textovky nestárnou a možnosti TADSu jsem\prozkoumal zatím jen povrchně. Taky mi pomohl v přehodnocení mého názoru na programování, stojí to za to.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 5. Květen 2017 - 20:57
A právě zde jsem v příkladu s první hrou našel direktivu noun, kterou jsem dříve používal, aniž bych věděl, co znamená.

Ah, pardon. Zalistoval jsem zdrojáky a ono to opravdu funguje, je to nějaká pomůcka mimo vocabWords, která umožňuje také vložit slova do slovníku. Ale v podstatě se to skoro nikde nepoužívá, používej normálně vocabWords/gcVocab, jak máš ve zbytku programu.

Tohle je moc zajímavé jak píšeš práci s pozicemi. Jestli dobře rozumím, využívá se zde malý virtuální stroj podobně jako v javě – uložená hra je tedy obraz aktuální paměti, který rekompilací ztrácím.

Ano. Zdrojový kód v TADSu je přeložen do strojového kódu podobně, jako když se třeba program v C++ přeloží do spustitelného souboru. Rozdíl je ovšem v tom, že při překladu C++ vznikne strojový kód spustitelný přímo na procesorech, kdežto překladem TADSu vznikne bytekód spustitelný v softwarově simulovaném počítači. Ve zkompilovaném programu jsou objekty a jejich proměnné identifikovány pořadovými čísly, ne symbolickými názvy kvůli rychlosti zpracování. A tak i při malé změně programu dojde leckde k přetřesení číselných identifikátorů, některé objekty zaniknou, jiné přibydou a tím se ztratí kompatibilita s uloženou pozicí.

Zajímalo mě, zda testCommands.txt schroupne i češtinu, naštěstí výsledný testOutput.txt jí zobrazuje naprosto bez problémů, jasné, tady je opravdu potřeba direktiva frob -i plain -k utf8.

Jo, jasně, s diakritikou není problém. Jenom jsem zapoměl napsat, že na konci souboru s testovacími příkazy to chce >konec a >ano, aby nezůstal interpret viset.

Stále čtu o vlastnostech, metodách, třídách a objektech, ovšem abych plně vše pochopil, musím začít na příkladech a právě tento manuál je to pravé.

V LearningT3 jsou ze začátku kapitoly "coding excursus", které postupně základní pojmy vysvětlují. Stručně:

 

Tady vidím class Heavy: Immovable – takže pokud to dobře chápu, Heavy je potomek třídy Immovable, kterou rozšiřuje dalšími parametry a zachovává si všechny její vlastnosti. A nad CustomImmovable nacházím class Immovable: NonPortable plus ouplně nahoře je hlavní třída Thing, teď už je to jasné.

Ano, přesně tak.

Ano, zkoušel jsem před objekt pilník definovat dvakrát plus takto:

Kód: [Vybrat]
+ mrtvola : RestrictedContainer 'mrtvola' 'mrtvola' *3
++ pilnik : Key, Hidden 'pilník' 'pilník' *2

Ovšem situace je stále stejná, hráč po příkazu koukni se do mrtvoly sice pilník vidí, ale není možné jej sebrat. Po odstranění direktivy Hidden je vše v pořádku. Tady mě to docela mate, raději dopíšu celou definici:

Kód: [Vybrat]
+ mrtvola : RestrictedContainer 'mrtvola' 'mrtvola' *3
 "Je v pokročilém stádiu rozkladu. "
     gcName = 'mrtvoly, mrtvole, mrtvolu, mrtvole, mrtvolou'
     gcVocab = 'mrtvoly/mrtvole/mrtvolu'
        dobjFor(LookIn)
        {
                action()
                {
                        if(pilnik.moved)
                        {
                                "Na mrtvole jsi neobjevil už nic zajímavého. ";
                                exit
                                ;
                        }

                        pilnik.moveInto(self);
                        "Bližší pohled na mrtvolu odhalil pilník schovaný v záhybech polorozpadlých šatů! ";
                }
        }
;

++ pilnik : Key, Hidden 'pilník' 'pilník' *2
       "Je šikovně upraven na přepilovávání mříží. "

       gcName = 'pilníku, pilníku, pilník, pilníku, pilníkem'
       gcVocab = 'pilníku/pilníku/pilník'
;

Laicky řečeno se mi zdá, že jsem v těle objektu mrtvola už pracuji se skrytým objektem pilník jiným způsobem a není tedy možné využít direktivu Hidden. Ovšem po jejím vymazání se jak jsem očekával v popisu místnosti zobrazí hláška Vidíš tu mrtvolu (která obsahuje pilník), což je také špatně. Takže jedině po vymazání dvou znamének plus vše funguje jak potřebuji, ale nerozumím jak, což není dobré – budeš po přečtení zdrojáku moudřejší? Jinak je dvojité znaménko jasné, doplnil jsem jej do provazu v truhle, kde samozřejmě nesmí chybět. Stejné je to např. u kupky sena, tam Tvůj návod funguje bez problémů. Tam ale budu potřebovat objevení jehly až po spálení sena, takže se podívám na změnu stavu objektu po konkrétní akci.

Trochu upřesním - nejde sebrat, ani hráč pilník nevidí, protože je stále skrytý. Jen jsi vypsal hlášku o jeho nalezení, ale pro TADS je stále neviditelný.

Teď je trochu více možností, jak dál postupovat. Záleží na tom, jakého efektu chceš dosáhnout. Asi nejblíže k tvému pojetí bude manuální zviditelnění doprovázené hláškou. V podstatě můžeš vyjít z toho, co máš, jen místo pilnik.moveInto(self) použiješ pilnik.discover();

Tohle řešení bude fungovat. Ale když to vezmu kolem a kolem, vlastně se moc neliší od přemístění objektu, jako jsi ho měl. Když nedáš žádné plus, znamená to, že objekt "nikde není", tudíž je pro háče nedosažitelný až do okamžiku, kdy ho do mrtvoly přemístíš a zobrazíš hlášku.

Já jsem promýšlel ještě některé jiné souvislosti, ale je fakt, že pokud chceš dodržet hlášky, jak je máš napsané, tak je to asi nejjednodušší cesta, takže se toho přidrž. On TADS umí lecos, ale někdy je větší problém se automatických hlášek, které se nehodí, zbavit :-)

Protože jsem ale nakousnul to automatické zviditelnění pří prohledání kontejneru, tak pro úplnost vysvětlím. Aby se Hidden objekt zviditelnil automaticky, je potřeba nechat TADS dělat, co má naprogramováno v knihovně. A to je obecný princip, na který je potřeba si dát při programování pozor, protože se do něj začátečník může zamotat. Půjdu-li do referenční příručky a vyhledám-li RestrictedContainer, dozvím se, že dobjFor(LookIn) je poděděné z Containeru:

Kód: [Vybrat]
dobjFor(LookIn)
{
    verify() { }
    check()
    {
        /*
         *   If I'm closed, and I can't see my contents when closed, we
         *   can't go on.  Unless, of course, the actor is inside us,
         *   in which case our external boundary isn't relevant.
         */
        if (!isOpen
            && transSensingIn(sight) == opaque
            && !gActor.isIn(self))
        {
            /* we can't see anything because we're closed */
            reportFailure(&cannotLookInClosedMsg);
            exit;
        }
    }
    action()
    {
        /* show our fixed "look in" description, if any */
        lookInDesc;

        /* examine my interior */
        examineInterior();
    }
}

Když ty si u kontejneru predefinuješ příslušnou action(), tak zdědíš verify() a check(), ale původní action() nahradíš tím svým. O co jsi přišel? Můžeš sledovat cestu kódem a dojdeš k funkci examineInteriorWithLister(lister), ve které se provádí mj. zviditelnění ukrytých objektů:

Kód: [Vybrat]
/* if desired, reveal any "Hidden" items concealed within */
if (revealHiddenItems)
{
    /* scan our contents and reveal each Hidden item */
    foreach (local cur in contents)
    {
        /* if it's a Hidden item, reveal it */
        if (cur.ofKind(Hidden))
            cur.discover();
    }
}

Tedy pokud chceš, aby TADS konal správně svou práci, tak když přetížíš nějakou metodu ve své třídě, tak bys obvykle měl zavolat zděděné chování a to tak, že do své action() metody nějak umístíš volání inherited(). Výjimkou je situace, kdy víš, že chceš zděděné chování úmyslně potlačit.

Jinými slovy stačilo by vynechat úplně dobjFor(LookIn) kontejneru a pilník by se sám zviditelnil. Byla by ale trochu potíž, že doprovodná hláška by byla velice fádní a nudná. To by se dalo poladit, ale bylo by to zbytečně složité, řešení s přemístěním je výhodnější.

Malá aktualizace – Tvé komentáře projíždím, testuji a snažím se vnímat postupně, vzpomněl jsem si na třídu Heavy a referenční manuál. Kouknul jsem se tedy na definici Hidden a nalezl zajímavou možnost „can be sensed“ na str. 906:

Kód: [Vybrat]
canBeSensed(sense, trans, ambient)
{
    /*
     *   If the sense is sight, and we haven't been discovered yet, we
     *   cannot be sensed.  Otherwise, inherit the normal handling.
     */
    if (sense == sight && !discovered)
        return nil;
    else
        return inherited(sense, trans, ambient);
}

Pokud uvnitř if změním hodnotu nil na true, pilník je zase vidět, tato direktiva tedy upravuje vlastnost třídy Hidden a de facto jí neguje, jestli to dobře chápu.

Ano. To je právě jádro toho, jak Hidden objekty fungují. Zablokují možnost smyslově vnímat objekt, pakliže není ještě objevený. To se pozná podle vlastnosti discovered, do které je po objevení uložena hodnota true. Tu ale nenastavuj ručně, místo toho zavolej v programu metodu discover(), tedy v tomto případě např. pilnik.discover(); a objekt bude zviditelněn.

Svůj projekt zase zasílám v příloze. Každopádně je paráda, že dokumentace k TADSu je tak rozsáhlá a je čeho se chytit, i když zpočátku je jí pro mě opravdu mnoho, člověk něco přečte a vzápětí zapomene, co naplat.

Jo, docela dobrý. Prolítl jsem zdroják a vedeš si dobře, žádné zásadní problémy tam nevidím.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 9. Květen 2017 - 14:48
Ohledně noun je vše jasné, budu používat vocabWords/gcVocab a zvyknu si na něj.

Znovu jsem pročetl Tvůj návod a ohledně virtuálního stroje našel informaci ohledně T3VM, dokonce popisuješ jeho podobnost s Javou, ha, tady jsme to pochopili oba podobně. Naštěstí je to prcek, takže žádné zpomalování se nekoná, i na první verzi RPi řádím ve Frobtadsu bez omezení.

Vidíš, u skriptu je dobré dát na konec příkazy >konec a >ano, díky za doplnění, já jsem jej vždy ukončil ručně.

Moc díky za lidské vysvětlení tříd, metod a objektů, tohle si mi opravdu hrozně těžko chápe bez skutečných příkladů, teď když je budu stále používat konečně budu moci zjistit více. Je mi fuk, že začínám hnedle s OOP, nezdržel jsem se ani u Pascalu, prostě mě programování do této doby míjelo. Ale na zdrojáku jsem četl, že programovat se dá naučit i ve čtyřiceti, tady mám ještě rezervu, hurá.

U pilníku jsem nakonec dle Tvého doporučení použil dvě znaménka plus a direktivu pilnik.discover(). Nyní vše parádně funguje, zkusil jsem mříž "odemknout" a zase "zamknout", po následném pokusu o odemknutí už je parser natolik chytrý, že vše udělá za mě. Jo, velmi trefné s těmi automatickými hláškami, těch se budu muset zbavit právě u dveří, už se těším...

Pečlivě jsem si našel ve třídě RestrictedContainer objekt dobjFor(LookIn), chápu, že pokud změním akci, tedy přesněji řečeno metodu action, metody verify a check podědím a zůstávají stejné. Přiznám se, že tohle je pro mě ještě dosti složité, metodu examineInteriorWithLister(lister) bych bez Tvého vysvětlení sám nenalezl. Každopádně jsem vyzkoušel vymazat celé tělo metody dobjFor(LookIn), vše v pilníkem je v pořádku, ale přesně jak píšeš, hláška není nic moc, takže ponechám první řešení. Je to ale cenná rada, s tímhle se ještě určitě mnohokráte setkám - musím hlídat, co má TADS uvedeno ve svých knihovnách.

Pilník jsem nakonec proměnil na šperhák, texty nyní vypadají realističtěji. Časem upravím mříž tak, že zde bude ještě jeden objekt např. s názvem zámek a hráč bude otevírat právě jeho. Nyní se posunu dále. Přemýšlím o kupce sena, tmavé místnosti, doplnění druhého názvu místností jako to máš např. u velínu, u mě 'kobka' 'do kobky', konektorech dveří a místnostech... A jak uvádím výše, stačí si ještě jednou projít Tvůj manuál, kde vše popisuješ. Jen ty Akce pro mě nebudou jednoduché, nechám je tedy až na konec - viz správná definice zbavení se strážce. Musím holt ty manuály číst stále dokola, vše se najednou pamatovat nedá, je to ale paráda.

Zítra se zase dostanu k úpravě zdrojáku, takže budu makat a o výsledek se rád podělím. Až se dostanu dále, určitě bude zase nějaká ta nová otázka, tuším, že s akcemi, už se těším...
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 9. Květen 2017 - 15:26
Moc díky za lidské vysvětlení tříd, metod a objektů, tohle si mi opravdu hrozně těžko chápe bez skutečných příkladů, teď když je budu stále používat konečně budu moci zjistit více. Je mi fuk, že začínám hnedle s OOP, nezdržel jsem se ani u Pascalu, prostě mě programování do této doby míjelo. Ale na zdrojáku jsem četl, že programovat se dá naučit i ve čtyřiceti, tady mám ještě rezervu, hurá.

Žádný problém, dej tomu čas, případně se zeptej. Ono to pomalu začne pomalu zapadat dohromady. Je to trochu těžké pochopit, protože tyhle věci vyžadují už poměrně dost abstrakní způsob uvažování a představivost. Proto je také snaha studentům přiblížit objektově orientované programování tím, že se připodobňují ty programátorské objekty k objektům z reálněho světa. To obvykle dobře funguje do té doby, než student potká něco jako:

http://geek-and-poke.com/geekandpoke/2014/1/2/games-for-the-real-geeks-part-2 (http://geek-and-poke.com/geekandpoke/2014/1/2/games-for-the-real-geeks-part-2)

Pečlivě jsem si našel ve třídě RestrictedContainer objekt dobjFor(LookIn), chápu, že pokud změním akci, tedy přesněji řečeno metodu action, metody verify a check podědím a zůstávají stejné. Přiznám se, že tohle je pro mě ještě dosti složité, metodu examineInteriorWithLister(lister) bych bez Tvého vysvětlení sám nenalezl. Každopádně jsem vyzkoušel vymazat celé tělo metody dobjFor(LookIn), vše v pilníkem je v pořádku, ale přesně jak píšeš, hláška není nic moc, takže ponechám první řešení. Je to ale cenná rada, s tímhle se ještě určitě mnohokráte setkám - musím hlídat, co má TADS uvedeno ve svých knihovnách.

Hlavní poselství je, že bysis měl zvyknout vždy při přetěžování knihovních metod volat inherited. Vyhledej si to slovíčko fulltextem ve zdrojácích Základny, abys viděl příklady, kde a jak se to používá, to bude asi nejvíce ilustrativní. Nezavolání inherited musí být vědomé rozhodnutí, ne opomenutí.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 12. Květen 2017 - 13:46
Krásný pátek přeji,

konečně se dostávám k počítači, počasí se úplně otočilo, takže každý, opravdu každý den zde mám lidi na řechtáky a ani tento víkend a téměř celý týden příští nebude výjimkou. OOP skutečně nebude nic jednoduchého, jestli zmáknu abstraktní myšlení nebo ne se dozvím tak, že se do něj pořádně opřu, pamatuji si, že mi jeden vývojář řekl něco jako „řešení Tě někdy napadne jen tak třeba při cestě autobusem nebo u Tebe při jízdě na koni, dej tomu čas“, přesně tak je to i u textovek, večer jsem si s jedním problémem lámal škebli a druhý den ráno řešení přišlo samo.

Ten odkaz je super, dostala mě hlavně ta hláška ohledně suda v Geeks And Non-Geeks. Netušil jsem, že používáš i javovský Spring, tu už je asi jiná třída.

Grepnul jsem si klíčové slovo inherited ve všech souborech Základny a budu študovat, co nepoberu, na to se zeptám. Postupně budu pokračovat i v Exoterovi, je to teď půjde trochu pomaleji, čas si ale najdu vždy. Až se posunu dále, pošlu další zdroják.
Modrou oblohu nad hlavou a konečně už slunečný víkend přeje

Orel
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 16. Květen 2017 - 15:14
Tak dnes jsem se konečně dostal k pokračování a alespoň něco se zadařilo.

Řešil jsem dveře – měl jsem potíže s jejich odemykáním, hra psala následující:
-------------------------------------------------
>odemkni dveře svazkem
To není něco, co bys mohlo odemknout.
>odemkni dveře svazkem klíčů
To není něco, co bys mohlo odemknout.
>odemkni dveře svazek klíčů
To není něco, co bys mohlo odemknout.
>odemkni dveře
Čím je chceš odemknout?
>svazkem klíčů
Hotovo.
-------------------------------------------------
Upravil jsem dle vzoru u Heidi skloňování u svazku klíčů, nyní je vše funkční, akci s dveřmi tedy mohu uzavřít.

Zatím jsem nezvládnul použití lana, které potřebuji pro vstup do studny, bude to nějaká akce a jak píšeš, naprogramovat realisticky se chovající lano nebude jednoduché. Nikde v manuálech ani tutoriálech na webu jsem nenašel příklad s přivázáním lana, to by mi parádně pomohlo a ani v Základně podobná akce pokud vím není, takže zde budu ještě bádat. Oficielní manuály moc hezky popisují šplhání po skalách, škoda, že vynechali právě to lano.


Pád z výšky do sena / na dlažbu – zde bude nějaká konstrukce if else. Napadlo mě použít:
 dobjFor(Enter) - method of ThroughPassage in travel.t[2618],
případně přesměrování, zatím jsem však nebyl úspěšný. Budu dále studovat nebo zkusím metodu jinou.


Útok na strážce – zde se mi konečně podařilo donutit hráče, aby dokázal sekerou zneškodnit strážce. Jen u výrazu zabij získávám nesmyslnou hlášku:
-------------------------------------------------
>zabij strážce sekerou
Strážcem nemůžeš zaútočit.
>zaútoč na strážce sekerou
Jediným mocným úderem se ti podařilo poslat strážce do věčných lovišť.
-------------------------------------------------

Teď ještě musím vymyslet, aby se předměty objevily až po zneškodnění strážce, změnu textu pomocí if – else – end jsem už doplnil. Pokud vložím jediné plus, předměty lze sebrat, pokud dvě, jsou vidět jen před zabitím strážce – tady by možná byl vhodný kontejner, jen nesmím strážce nechat „zmizet“, na to se teď vrhnu. Pokud se mi vše podaří, podobnou situaci připravím u draka a psa.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 17. Květen 2017 - 09:28
Tady jsem našel diskuzi ohledně řešení přivazování provazu a také zajímavou definici akcí TAction – přesně tu bych využil při definici nové akce typu „přivaž“, „přepiluj“ apod., pokud jí dobře chápu. Také uvedené příklady dobjFor se hodí. Budu studovat a juknu se zase do Library reference a definici tříd a objektů

http://rec.arts.int-fiction.narkive.com/zp9ZA3sU/tads-3-attaching-problem
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 19. Květen 2017 - 19:57
Zatím jsem nezvládnul použití lana, které potřebuji pro vstup do studny, bude to nějaká akce a jak píšeš, naprogramovat realisticky se chovající lano nebude jednoduché. Nikde v manuálech ani tutoriálech na webu jsem nenašel příklad s přivázáním lana, to by mi parádně pomohlo a ani v Základně podobná akce pokud vím není, takže zde budu ještě bádat. Oficielní manuály moc hezky popisují šplhání po skalách, škoda, že vynechali právě to lano.

Teď pár týdnů budu mít málo času, tak odpovídám po kouskách. Realistická lana patří k těm nejsložitějším věcem k simulování a já vlastně ani nevím, jak se lano v Exoterovi používá. Ale hodil jsem na web překlad jedné demonstrační hry Attachable třídy. Kdysi dávno jsem ji přeložil, ale byly tam po staru zadané názvy a slovníky objektů. Teď jsem ji oprášil a připravil k publikování, je na http://www.tads.cz/cs/demonstracni-hra (http://www.tads.cz/cs/demonstracni-hra).

Ten odkaz je super, dostala mě hlavně ta hláška ohledně suda v Geeks And Non-Geeks. Netušil jsem, že používáš i javovský Spring, tu už je asi jiná třída.

Né, nepoužívám, jen čtu Geek and Poke...
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 21. Květen 2017 - 22:08
Pád z výšky do sena / na dlažbu – zde bude nějaká konstrukce if else. Napadlo mě použít:
 dobjFor(Enter) - method of ThroughPassage in travel.t[2618],
případně přesměrování, zatím jsem však nebyl úspěšný. Budu dále studovat nebo zkusím metodu jinou.

Možnosti a způsoby přesunů postav jsou docela rozsáhlé, spíš bys mohl použít v místnosti metodu enteringRoom, která tě informuje o vstupu postavy:
Kód: [Vybrat]
    enteringRoom(traveler)
    {
        if(traveler == me && nejake dalsi podminky)
        {
            "Něco... ";
        }
    }

V ní si otestuješ, o jakou postavu se jedná a jakékoliv jiné podmínky a něco uděláš. Pokud postavu nezabiješ, tak se výstupy zobrazí před rozhlédnutím v nové místnosti.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 22. Květen 2017 - 08:17
Krásné ránko přeji,

paráda, hru Attachable jsem si stáhnul, binárka je v pohodě, jen zdroják attachment-20170519-1.zip bude asi poškozený, po rozbalení vidím jen prázdný adresář Attachable, můžu poprosit ještě jednou o nahrátí na server? Na řešení toho lana se moc těším, snad najdu inspiraci.

Taky mám teď spoustu práce, celý víkend koně a dnes kroužky s dcérenkou, vždy se ale alespoň o něco posunu dále. Se strážcem zatím ještě bojuju, budu dále zkoušet a podívám se na ten pád do sena - v místnosti sv_nadvori přidám metodu enteringRoom s podmínkami, zda je/není seno v místnosti, až se pohnu, dám sem výsledek.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 22. Květen 2017 - 20:18
Pardon, už je to spravené.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 25. Květen 2017 - 12:16
Vrhnul jsem se na pád z výšky do kupky sena, přiznám se, že si nejsem jist, kde mám metodu enteringRoom(traveler) použít – zda ve druha_mistnost_vrchol_vez nebo v sv_nádvoří, u obou případů jsem nedosáhl kýženého výsledku. Ale po juknutí se do zdrojáků Heidi a Tvého Attachment mě napadlo ještě jedno, nevím zda ouplně správné systémové řešení:

druha_mistnost_vrchol_vez: Room 'Druhá místnost na vrcholu věže' 'do druhé místnosti na vrcholu věže'
    "Jsi v místnosti na vrcholu věže. \bMůžeš jít na východ, dolů. "
    east = mistnost_vrchol_vez
    down : TravelMessage
          {  ->sv_nadvori
              "Spadl jsi přímo doprostřed kupky sena, která ideálně ztlumila tvůj pád. "
                canTravelerPass(traveler) {return kupka_sena.isIn(sv_nadvori); }
              explainTravelBarrier(traveler)
         { "Zabil jsi se pádem z výšky. "; finishGameMsg(ftDeath, [finishOptionUndo] );}
    }
;

Pomocí metody  TravelMessage jsem dosáhl toho, že pokud se kupka sena nachází v sv_nadvori, hráči se nic nestane a v opačném případě zahyne přesně tak jako v Exoterovi.

Mimochodem teprve dalším studiem zdrojáků Heidi jsem se dozvěděl, že ve hře lze i křičet a tento křik může zanikat ve větru, to minimálně u předělávky a dalším pokračování Kroužícího orla musím využít. Opravdu bezva systém, líbí se mi čím dál tím více.
 
Na tomto místě jsem zjistil, že po smrti hráče hra vypisuje ZEMŘELO JSI. - u definice hráčovy postavy me však nemohu využít striktní definici rodu typu *1, setkal jsi se s tím také u tvorby Základny?

V místnosti se studnou jsem pomocí zdrojáku Attachment a výše uvedené kombinace  TravelMessage zkusil něco podobného, zatím ale bez kloudného výsledku:

jz_nadvori: Room 'Jihozápadní část nádvoří' 'do jihozápadní části nádvoří'
    "Stojíš na nádvoří. \bMůžeš jít na sever, na východ, na jih, dolů. "
    north = sz_nadvori
    east = jv_nadvori
    south = brana
    down : TravelMessage
          {  ->ve_studni
              "Sešplhal jsi dolů za pomoci přivázaného lana. "
//                canTravelerPass(traveler) {return provaz.moveinto(studna); }
        canTravelerPass(traveler) {!provaz.isConnectedTo(studna); }
              explainTravelBarrier(traveler)
         { "Studna je moc hlubová na to, abys do ní skočil jen tak. "; }
    }
;

+ studna : Attachable, Thing, Heavy 'studna' 'studna' *3
    @jz_nadvori
    "Hluboká studna, nyní však již zcela vyschlá. "
    specialDesc = "Je tu stará kamenná studna. "

    canAttachTo(obj) {return obj == provaz;}
    handleAttach (other)
    {   provaz.moveinto(studna);
       "Spustil jsi jej dolů. ";
     }

     gcName = 'studnu, studni, studna, studni, studnou'
     gcVocab = 'studnu/studni/studnou'
;

Také doprovodné hlášky zatím nejsou zrovna ideální:

>prozkoumej studnu
Hluboká studna, nyní však již zcela vyschlá.
Studna je připevněna k provazu.

>d
Je tu příliš velká tma, než abys vidělo na cestu.


Zde asi TravelMessage nepoužívám správně, zkusím si ještě jednou projet zdroják a v Library reference prozkoumat používané metody. Tak jako tak mi provaz zůstane po připevnění ke studni v ruce, takže zde budu muset upravit změnu stavu.

Každopádně uvázání provazu a boj se strážcem/drakem/psem jsou poslední dva zádrhele, až tyhle rozseknu, tvorba se bude chýlit ke konci.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 25. Květen 2017 - 12:36
Abych nehádal, prosím napiš mi, jak má vypadat ideální výstup ze hry s provazem i kupkou sena, tj. příkazy hráče a odpovědi hry na ně.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 25. Květen 2017 - 12:57
Sakra, ty jsi ale rychlík, ještě jsem zapomněl dát sem aktuální zdroják.

Projel jsem celou současnou hru tak, že napoprvé spadnu do sena, pak zkouším vlézt do studny pomocí provazu, seberu seno a druhým pádem na dlažbu hra končí.

A ještě mě napadlo upravit Tebou přeložené příkazy. U studny mohu použít "připevni provaz", ale ne už "přivaž provaz". Upravil jsem soubor cs_cz.t v adresáři /usr/share/frobtads/tads3/lib/adv3/cs_cz i v tom samém pod Wine a hurá, možnost "přivaž" už interpretr zná. Takže pokud se nepletu, mělo by zafungovat přidání slova "přepiluj" tam, kde máš uvedeno odemkni, to zkusím příště.

Vše potřebné zasílám v příloze. Teď za chvíli frčím pro dcérenku do školky, během zítřka nebo nejpozději o víkendu se zase dostanu k Exoterovi, baví mě to čím dál více.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 26. Květen 2017 - 08:55
Dnes jsem ještě jednou v klidu juknul na soubory, které jsem Ti zaslal a jak vidno, spěch není to pravé, zase je tu problém s kódováním. Nyní posílám následující soubory v jednom archivu:

Pruchod_Exoter.txt a Pruchod_Exoter.pdf - to je přesný postup zkopírovaný z hraní hry ve Win verzi TADS3 Interpretr
Auto 318.cmd - nahraný průchozí skript pod Linuxem s nečitelným kódováním, ve Win verzi Workbenche plně funční
cs_cz.t - moje malá úprava s přivázáním provazu

Se senem je tedy vše OK, nyní se pokusím zprovoznit jeho spálení pomocí zapálené pochodně plus bude asi vhodnější, aby jej hráč nemohl sebrat. Budu ještě laborovat ohledně lana a studny. Až bude hra hotová, vrhnul bych se na doplnění souboru cs_cz.t a doplnil další slova, která se mi zdají být užitečná, pokud budeš souhlasit a je-li to správný postup, můžeme jej dát i na Tvůj web jako novou verzi, alespoň takto málo budu schopen i já pomoci v překladu TADSu.

Krásný víkend a modrou oblohu nad hlavou přeje

Orel
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 31. Květen 2017 - 09:40
Tak se zase dostávám k tvorbě, lano a strážce zatím nechám stranou a zaměřil jsem se na zapálení pochodně. Prozkoumal jsem v Library - extras.t třídu class Candle: FueledLightSource a pečlivě přečetl práci s baterkou v Heidi a především Tour Guide stranu 102 - Light and Fire. Parádně je tu popsána klasická svítilna na baterky jako OpenableContainer, olejová lampa a informace o tom, že pochodeň mohu definovat podle Candle & FireSource. Zkoušel jsem všechny příklady, posílám aktuální zdroják, kde mám na str. 181 pochodeň a str. 247 křesadlo. Ve všech případech dostávám po příkazu zapal pochodeň hlášku "{Tím iobj} nemůžeš nic zapálit.".

Až budeš mít čas, zkus se prosím juknout i na pochodeň, zatím budu dále zkoumat.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 22. Září 2017 - 15:27
Máme po táborech a konečně budu mít více času a hlavně spoustu chuti pokračovat s parádním TADSem. Jen tak bastlit a zkoušet opravdu nejde, Exoter bych tímto způsobem nikdy nedokončil. Znovu jsem si pročetl Gaspodův návod a vidím, že programovat to chce opravdu systematicky a od začátku.

Vytisknul jsem si tedy všechna dostupná pdf plus to hlavní z technického manuálu, nyní musím kompletně projít Learning TADS 3, Heidi jako příklad pro neprogramátora opravdu nestačí. Kromě TADS mě jako linuxáka zajímá nejvíce C a C++, jak vidno, syntaxe je podobná, takže proč nezačít něčím, co mě opravdu baví, u her a hlavně textovek se budu učit s radostí. Třeba časem jako céčkař vyřeším i ten nešťastný problém s UTF-8 a mé oblíbené knihovny ncurses ve Frobtadsu, jůů, to by bylo něco... Tahle aplikace si o další vylepšování sama říká, jen škoda, že není zrovna v hlavním hledáčku tvůrců balíčů jednotlivých distribucí, aktivně využívám Arch a Debian 9/Q4OS, v prvním je pro úspěšný překlad nutno upravit PKGBUILD a v tom druhém se již ani nenachází, naštěstí upravená verze z nestabilní větvě funguje parádně.

Exoter se tedy trochu pozdrží, budu se snažit co nejlépe pochopit popsané příklady v manuálech, mimochodem ty návody pro TADS jsou opravdu profesionálně zpracované. Díval jsem se i na Inform, také se dnes již zrovna moc nevyvíjí, synaxe TADSu je ale narozdíl od něj podobnější klasickému C++, takže není co řešit.

Námětů na texovky mám spoustu, hotový scénář k druhému Orlovi a připravený třetí, mnohem rozšířenější a přepracovaný Bad Night, aztékové a májové, středověké hrady jako vystřižené z vondruškových románů, ruská občanská válka za Války velké, partyzání v Jusoslávii v té druhé... je toho moc, takže se programování holt nevyhnu, to je osud, který si musím prožít.

Jakmile něco nového zbastlím, další zdrojáky sem rozhodně hodím, všechny své textovky chci dávat k dispozici včetně zdrojáků jako ve většině linuxových aplikací. Plus testování nové textovky od Thoorina, mám se na co těšit.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 23. Září 2017 - 10:47
Jo, jo, omlouvám se, já padl před prázdninami vyčerpáním a tak trochu jsem spoléhal na to, že budeš mít letní akce a nevzpomeneš si na to, že jsem neodpověděl. Musím tam něco opravit v knihovně.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 25. Září 2017 - 09:18
Jasná věc, nic se neděje, já jsem se upřímně o táborech k textovkám taky vůbec nedostal, s dvaceti dětmi není žádný den zrovínka oddych. Pilně teď študuju Learning TADS3, dříve jsem dumal nad tím, kterým programovacím jazykem začít, teď ale začínám chápat, že je to fuk, třídy a objekty se budou používat i v C++ podobně jako zde a až pořádně pochopím syntaxi a algoritmy, bude mi v každém jazyce hej. Eve parádně vysvětluje objekty, jejich vlastnosti a metody a rovnou na příkladech, takové učení mě baví, některé nic mi zatím neříkající matematické úlohy např. v Pascalu nebo Pythonu mojí pozornost nedokázaly udržet.

Hnedle od začátku mluví také o dědičnosti a vícenásobné dědičnosti, tohle se na příkladech dá parádně vstřebat. Zatím jsem u mix-in třídách, nyní ještě netuším, proč Darkroom není mix-in, ale ShipboardRoom a FloorlessRoom ano, důvod tady ale určitě je a věřím, že jej naleznu později v textu nebo v Library, tyhle otázky pokud sám vyřeším, mě posunou zase dále.

Stále jezdíme a za měsíc tu mám podzimní prázdniny u koní, volná dopoledne ale dycinky najdu, takže můžu študovat, jdu na to. Pokud budeš cokoliv upravovat, prosím o info např. sem:

http://tads.cz/cs/novinky

tam často chodím a hnedle je vidět, co máme nového - už se těším na novou knihovnu.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 25. Září 2017 - 11:38
dříve jsem dumal nad tím, kterým programovacím jazykem začít, teď ale začínám chápat, že je to fuk, třídy a objekty se budou používat i v C++ podobně jako zde a až pořádně pochopím syntaxi a algoritmy, bude mi v každém jazyce hej.

Nakonec je to jedno, já jen cítím určité problémy s pochopením, pokud se někdo začne učit programování v prostředí webových stránek, ať už PHP nebo JavaScript, tam je to hodně přiohnuté a pro pochopení základních principů opravdu ne moc vhodné.

Zatím jsem u mix-in třídách, nyní ještě netuším, proč Darkroom není mix-in, ale ShipboardRoom a FloorlessRoom ano

Mix-in třída je taková třída, která není určená k tomu, aby se použila samostatně, tedy aby se přímo od ní samotné vytvořil objekt. Je to proto, že sama nedědí žádnou kompletní fukcionalitu, je to jen malý doplněk, který lze k něčemu přidat. Obvykle se používá pro ty věci, které chceš přidat na více místech v základní hierarchii tříd. Typickou ukázkou je mix-in třída Lockable a její potomci, jako LockableWithKey. Ty definují samotnou funkcionalitu zamykání a odemykání, která je sama o sobě k ničemu, dokud se nezkombinuje s nějakým objektem, třeba dveřmi, nebo kontejnerem. Dveře a kontejner jsou dva hodně odlišné objekty, které jsou v základní hierarchii objektů odvozených od Thing dost daleko od sebe, zejména kontejner má pak i hodně různých potomků s různým chováním, ale sdílejí tu potřebu je občas učinit zamykatelnými. Proto je Lockable mix-in třída, která jde přidat k jednomu či druhému a jde tak vytvořit hodně různých kombinací chování.

U Shipboard i Floorless máš ve skutečnosti obě možnosti:
Kód: [Vybrat]
/*
 *   A shipboard room.  This is a simple mix-in class: it can be used
 *   along with any type of Room to indicate that this room is aboard a
 *   ship.  When a room is aboard a ship, the shipboard travel directions
 *   (port, starboard, fore, aft) are allowed; these directions normally
 *   make no sense.
 *   
 *   This is a mix-in class rather than a Room subclass to allow it to be
 *   used in conjunction with any other Room subclass.  To make a room
 *   shipboard, simply declare your room like this:
 *   
 *   mainDeck: Shipboard, Room // etc
 */
class Shipboard: object
    /* mark the location as being aboard ship */
    isShipboard = true
;

/*
 *   For convenience, we define ShipboardRoom as a shipboard version of the
 *   basic Room type.
 */
class ShipboardRoom: Shipboard, Room
;

Tedy třída Shipboard je mix-in třída použitelná s jakýmkoliv druhem místnosti (a musíš si ji sám s nějakým druhem místnosti namíchat) a pokud žádný speciální druh místnosti nechceš, tak můžeš použít přímo ShipboardRoom, která představuje základní místnost s Shipboard směry.

Proč není stejným způsobem udělaný i Darkroom nevím, zřejmě nepřišlo autorovi důležité to tak udělat. Asi předpokládal, že místnost bez osvětlení budou lidé zřídka kdy chtít kombinovat s něčím jiným (a když, mohou to něco jiného přimíchat k ní). Nehledal bych v tom nějaký hlubokomyslný důvod. Snad jen snahu mít co nejvíce samostatně použitelných tříd a co nejméně mix-inů, které vyžadují o krůček navíc k pochopení.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 27. Září 2017 - 10:02
Výborně, já to cítím zrovna tak, je velmi lákavé naučit se např. PHP s Javascriptem a nějakým tím frameworkem, spousta z nás by poté mohla pracovat z domova, což by mi v minulosti moc pomoho, u síťařiny tohle nejde. Nyní už ale tuhle potřebu nemám a mohu se učit jazyk, který je mi blízký, TADS, C, C++ a Python v kombinaci s linuxem nebo unixem je přesně to, co mě láká nejvíce.

Learning TADS3 je psaný čtivě a se zajímavými příklady, už jsem u šedesáté stránky a mnohé jsem pochopil, je hezké vědět, že existuje třída, objekt, vlastnosti a metody, ale teprve zde vidím prakticky, k čemu jsou. Autor parádně ukazuje jednoduchou definici vlastností a využití šablon, poté mix-in třídy a vícenásobnou dědičnost, nevěděl jsem, že i třída může dědit z jiné třídy.

Taky už vidím rozdíl mezi
vlastností = statická data
a
metodou = blok kódu čekající na spuštění

a na všechny ty tajemné příkazy uvnitř složených závorek u Heidi i Základny se už budu dívat jinak.

Snad jsem i správně pobral rozdíl mezi metodou a funkcí
metoda = kód přiřazený ke konkrétnímu objektu
funkce = kód nepřiřazený

tohle bude určitě v C++ podobné.

V manuálu jsou i bezva příklady, např. prsten schovaný pod kobercem se dá definovat více způsoby, metodou discover nebo makePresent.  Už vím jak změnit název objektu po jeho změně, např.  zapálenou pochodeň a spoustu dalších věcí, s tímle se pohnu mnohem více dále. I v Exoteru využiji třídu Outdoorroom a více si s ním vyhraji, teď už snad pochodeň a studnu nadefinuji správně. Metody jsou krásně vidět i v Sample games, soubor LightFire.t mi hodně pomůže.

Jo, my lidi jsme holt líní, nedal jsem na Tvou i autorovu radu, že začít Getting started a hrou Heidi pro neprogramátora není ten nej nápad, ale nevadí. Teď už snad konečně získám i ty programátorské návyky, hurá...

---

Moc děkuji za parádní vysvětlení mix-in tříd, autor je posléze popisuje i v dalších tématech, mě hlavně zajímalo, proč právě Darkroom, u kterého bych mix-in očekával, takto připravený není. Teď už vím, že autor standardní knihovny se prostě tak rozhodl při implementaci TADSu, nakonec novou mix-in třídu si mohu nadefinovat i sám, proč ne, takové vychytávky ale až časem. Na Lockable se podrobněji podívám, se Shipboard je vše jasné, tu jako samotnou třídu nemohu využít, pak by samozřejmě mix-in ztrácel smysl.

Mimochodem, díval jsem se, že i v C++ se mix-in třídy používají a jak jsem předpokládal, má svojí Standard Library, to mě více, než těší, začít programovat s TADSem mě nenásilnou formou dostane i sem...

Za půl hodinky mě čeká vyjížďka, pak bude chvíli volno, takže budu študovat dále a zase něco upravím a přidám do zdrojáku.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 28. Září 2017 - 09:21
...nevěděl jsem, že i třída může dědit z jiné třídy.

Že třída může dědit od jiné třídy a ta zase od jiné je úplně běžné, právě tak je vystavený celý strom dědičnosti v knihovně a mají to tak snad všechny objektově orientované jazyky. Co není úplně běžné, je vícenásobná dědičnost, tedy že třída dědí od více než jedné rodičovské třídy. V C++ to možné je, ale např. PHP se tomu zuby nehty brání a zavádí raději interfejsy a traity, které část vlastností vícenásobné dědičnosti přidávají, ale přitom nedávají plnou volnost.

Taky už vidím rozdíl mezi vlastností = statická data a metodou = blok kódu čekající na spuštění

Na slovo "statický" pozor, to má jiný význam. Vlastnost je prostě proměnná - pojmenovaná paměťová buňka, do které se dá uložit nějaká hodnota (a měnit, proto ne statická). Když jsou proměnné a funkce součástí objektu, tak se jim říká vlastnosti a metody, aby se zdůraznila jejich příslušnost k daným objektům. V C++ se používají stejné pojmy, akorát v C++ musíš vždy nejprve udělat třídu a pak teprve vytvořit objekt dané třídy, v TADSu můžeš psát už hotové objekty.

Mimochodem, díval jsem se, že i v C++ se mix-in třídy používají a jak jsem předpokládal, má svojí Standard Library, to mě více, než těší, začít programovat s TADSem mě nenásilnou formou dostane i sem...

To ano, TADS je navržen jako běžný moderní profesionální programovací jazyk. Principy, které si v něm osvojíš, tak jsou přenositelné dál. Tím se liší např. od informu, který je postaven na programování v anglickém jazyce, což je sice na první pohled neotřelé a zajímavé, ale v jiných oblastech jsou tyto znalosti zcela nepoužitelné. A zároveň i od různých klikacích prostředí, kde se dají gamebooky naklikat a sem tam napsat jednoduchý skript, což však je jen velmi omezená podmnožina skutečného programování.

Nevýhodou TADSu je, že právě díky tomu je dost těžký pro neprogramátory. Má strmou křivku učení - první schod, který lidé musejí překonat, je tak trochu jako menší horolezecká stěna. Na druhou stranu až na ní vylezeš, uvidíš mnohem dál.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 3. Říjen 2017 - 09:15
Díky za parádní vysvětlení, já opravdu žil v domění, že třída od třídy nemůže nebo spíše není nutno, aby cokoliv dědila, na to přijdu až s vysvětlením od programátora nebo vlastní praxí. S tou vícenásobnou dědičností je to moc zajímavé, čím dál více se mi líbí kombinace TADS a C++. U PHP chápu, že OOP zde není ještě úplně dozrálé, přeci jen pokud se nepletu, opravdové objekty tam byly až od verze 5, na druhou stranu původní C také nic takového nemělo, jeho následník má ale historii samozřejmě delší.

A sakra, já jsem právě slovo „statický“ převzal z Eveho manuálu, kde na straně 23 vysvětluje rozdíl mezi daty vlastností a blokem kódu uvnitř medoy, jak vidno, definici jsem pochopil nesprávně. Spolu jsme se v minulosti bavili právě o proměnných a funkcích, psal jsi mi, že u OOP se jedná o vlastnosti a metody daného objektu, díval jsem se do historie zpráv.

Ano, četl jsem velmi zajímavé srovnání TADS a Inform, kde právě Tebou popsaný rozdíl v programování autor uvádí. Určitě nebudu spěchat a pořádně si vyzkouším všechny příklady v manuálu, ano, Eve píše, že práce s objekty je u TADSu zjednodušena, na to si v budoucnu u C++ musím dát pozor. Mimochodem velmi mě zaujaly tyto stránky:

http://www.sallyx.org/

Autor zde parádně popisuje začátek v jazyce C, přechod k C++, poté programování v Linuxu a popis mnou velmi oblíbené knihovny ncurses, také Postgresql se bude hodit. Je to spíše věc budoucnosti, pokud bys však měl čas a chuť a v rychlosti se juknul na popsanou látku, můžeš mi jako programátor sdělit svůj názor zda jsou tyto tutoriály vhodné na seznámení s těmito jazyky? Toto ale v žádném případě nespěchá, nejprve musím projet Learning T3, ten se mi jako manuál zdá naprosto parádní. A přečtu si jej několikrát, což dělám právě teď...

Ještě jednou si projedu mnou popisovanou část manuálu, ať je mi vše jasné. Tento víkend jsme jezdili a také tento týden mám téměř celý zaplněn jízdami na koních, takže se k počítači dostanu méně, ve volných chvílích budu dále studovat, OOP není žádná sranda. Už vím jak definovat metodu uvnitř objektu pochodeň, v Library i příkladu s názvem LightFire jsem nalezl vše potřebné plus následná změna názvu po změně stavu se také zadařila, ještě si projedu všechny příklady a příště sem snad už konečně hodím další kus exoteráckého kódu.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 3. Říjen 2017 - 20:36
Díky za parádní vysvětlení, já opravdu žil v domění, že třída od třídy nemůže nebo spíše není nutno, aby cokoliv dědila

V praxi se poměrně běžně vytvářejí složitější hierarchie dědičnosti tříd. V TADSu to máš třeba právě na příkladu třídy Thing a jejich desítek potomků: http://www.tads.org/t3doc/doc/libref/object/Thing.html#_SubClassTree_ (http://www.tads.org/t3doc/doc/libref/object/Thing.html#_SubClassTree_) Od Thing dědí Actor, BasicLocation, BulkLimiter, od BasicLocation dědí Room, od ní zase DarkRoom a další. Ale v jiných jazycích a programech to máš také, třeba v Qt knihovně pro tvorbu uživatelského rozhraní zase máš třeba třídu pro Widget, od ní dědí tlačítko atd. (https://wiki.qt.io/Qt_for_Beginners#Qt_class_hierarchy (https://wiki.qt.io/Qt_for_Beginners#Qt_class_hierarchy)). Představi si to jako podobenství s fylogenetickým stromem živočichů (https://cs.wikipedia.org/wiki/Klasifikace_%C5%BEivo%C4%8Dich%C5%AF#Fylogenetick.C3.A9_stromy (https://cs.wikipedia.org/wiki/Klasifikace_%C5%BEivo%C4%8Dich%C5%AF#Fylogenetick.C3.A9_stromy)), který říká, které druhy živočichů jsou si příbuzné. Třeba člověk a šimpanz mají hodně společného. V programování je podobná motivace - hledat společné vlastnosti a metody a ty pak vkládat do společného předka, odkud jsou zděděny do všech potomků, které je potřebují. Důvod je, aby to společné bylo naprogramováno jen jednou na jednom místě.

A sakra, já jsem právě slovo „statický“ převzal z Eveho manuálu, kde na straně 23 vysvětluje rozdíl mezi daty vlastností a blokem kódu uvnitř medoy, jak vidno, definici jsem pochopil nesprávně. Spolu jsme se v minulosti bavili právě o proměnných a funkcích, psal jsi mi, že u OOP se jedná o vlastnosti a metody daného objektu, díval jsem se do historie zpráv.

Ná já tam nikde slovo statický nevidím, ale já reagoval hlavně na pojem "statická data" a vlastnost, to je vlastně proměnná a může svou hodnotu měnit, takže slovo statický není na místě. Ale to je detail, moc nad tím nespekuluj.

Mimochodem velmi mě zaujaly tyto stránky: http://www.sallyx.org/

Nevím, proč ne. Psal to někdo mladší, kdo se to sám učil, tak třeba ti to bude vyhovovat. Proběhl jsem část o postgresu a přišlo mi to celkem fajn, takový zestručněný manuál. Vytkl bych asi hlavně to, že učí spojování tabulek zápisem s čárkou (kartézský součin) a následnou filtraci ve WHERE místo aby rovnou vysvětlil syntaxi LEFT resp. INNER JOIN ... ON ...  a jaký je mezi tím rozdíl.

O tom céčku je to taky takový docela hezký manuál. Akorát já osobně, když učím, tak kladu menší důraz na šířku znalostí a větší na schopnost porozumět principu a schopnost prakticky znalosti použít a proto se snažím všechno motivovat nějakou praktickou situací. Hlavní je mít nějakou motivaci, nějaký cíl, který chceš dosáhnout a který tě bude pohánět vpřed.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 9. Říjen 2017 - 07:07
Hierarchie dědičnosti tříd:
Ano, právě na třídě Thing je vše parádně ilustrativní, někteří její potomci jsou popisováni v Eveho manuálu a také v návodu od Tebe. Díky za zajímavý odkaz na strom živočichů, ten jsem neznal, přeci jen od školy už mám pár let za sebou, hledání společných vlastností a metody je mi sympatické, tady krásně na konkrétním příkladě vidím výhodu OOP. S podobnou třídou pro Widget jsem se setkal už s GTK tuším v Glade při návrhu uživatelského rozhraní, když jsem si s ním hrál, tehdy jsem ale samozřejmě netušil nic o stromu dědičnosti a nyní je vše mnohem jasnější. Ouplně lituji, že nejsem programátor, TADS potřebuje pořádný moderní workbench pro Windows i Linux, moc dobře se mi pracuje s klasickými DOSovými okny ála Turbo nebo FreePascal IDE, mít takový naprogramovaný v ncurses pro příkazovou řádku a klidně i v GTK a QT pro X nebo Wayland by byla paráda. Ale co naplat, zatím musí stačit Wine.

Programování v C:
Moc díky za reakci, kvalitu tutoriálů zatím nejsem schopen posoudit, takže je paráda, že jsi se na web podíval a zhodnotil, mě zaujal hlavně popis oblastí, které mě nejvíce lákají, především ke knihovně ncurses jsem nenašel v češtině příliš mnoho materiálů. Podobný zajímavý návod nejen na C/C++ jsem nalezl i na webu www.itnetwork.cz a příklady her se zdrojovými kódy mám v plánu pořádně prozkoumat hnedle po zvládnutí TADS. Mám k dispozici i zajímavý úvod do programování v C na Raspberry - Essentials_C_v1.pdf, kde v závěru odkazují na asi tradiční knihu tohoto jazyka s názvem “The C Programming Language” od Kernighana and Ritchieho. Zde se ale právě bojím ztráty motivace a právě proto mě TADS zaujal, protože jeho ovládnutím se mi otevře můj dávný sen naprogramovat textovou hru, motivace je tedy obrovská. A stejně mě láká prozkoumávat linux a bsd, k tomu se dostanu později.

Pokud učíš právě tímto stylem, je to paráda, nakonec, proč bychom se na nějaké výuce nemohli dohodnout, vůbec nejsem proti.

Zapálení pochodně:
Nyní řeším zapálení pochodně. Několikrát jsem si přečetl T3TourGuide od strany 102 do 109 plus pečlivě prozkoumal LightFireSource v Sample Games. Zde jsou popisovány nejrůznější metody kontrolující množství oleje v lampě nebo způsob zapálení dynamitu, prosté zapálení pochodně něčím jiným, než sirkami, jsem však nenalezl. Napadlo mě grepnout metodu "canLightWith" a "canLightWith(obj)" ve všech souborech včetně Základny, které mám na disku, žádný příklad tohoto typu však nebyl k mání. Ani google nepomohl, divím se, že není k nalezení možnost zapálit pochodeň křesadlem, že by něco takového žádný autor pro textovku nepotřeboval?

Zkoušel jsem pomocí tipu na straně 104 v T3TourGuide v souboru LightFireSource ze Sample Games uvedený příklad LIGHT CANDLE FROM TORCH, ten mi úspěšně funguje, ovšem k zapálení předmětu musím mít krom zápalek v takovém případě věc, která již hoří.

Jediné, co mě po několikadenním zkoušení napadlo, bylo využít objekt Matchstick - jen díky němu jsem schopen křesadlem pochodeň zapálit. Zde zasílám transskript hry:

--------------------------------------------------------------------------------------------------------------------------
Vítejte v konverzační hře Exoter, přesněji řečeno v její co nejvěrnější předělávce ze skvělého počítače ZX Spectrum a Didaktik Gama.

Kobka
Jsi v malé kamenné kobce. Je tu cítit mrtvolný zápach. Světlo sem proniká z jediného stropního otvoru, ve kterém je mříž.
Nemůžeš jít nikam.
Vidíš tu mrtvolu.

>koukni se do mrtvoly
Bližší pohled na mrtvolu odhalil šperhák schovaný v záhybech polorozpadlých šatů!

>vezmi sperhak
Hotovo.

>odemkni mriz
(šperhákem)
Hotovo.

>n
(nejprve otevíráš mříž)
Chodba
Stojíš na kamenné dlažbě středověké chodby. Nízká klenba Ti rozhodně nedodává pocit jistoty.
Můžeš jít na východ, na jih, dolů.
Nevidíš nic zvláštního.

>v
Chodba
Jsi v chodbě.
Můžeš jít na východ, na západ.
Vidíš tu pochodeň.

>vezmi pochoden
Hotovo.

>prozkoumej pochoden
Kdyby se Ti jí podařilo zapálit, jistě by vydávala hodně světla.

>v
Chodba
Jsi v chodbě. Vidíš strážce, naštěstí je k Tobě obrácen zády.
Můžeš jít na východ, na západ.
Vidíš tu svazek klíčů a křesadlo.
Strážce tu stojí.

>vezmi kresadlo
Hotovo.

>prozkoumej kresadlo
Snad by se s ním dal rozdělat oheň.

>v
Konec chodby
Jsi na konci chodby. Vidíš dveře.
Můžeš jít na východ, na západ.

>zapal kresadlo
Škrtnutím křesadla zapaluješ malý plamínek.

>i
Neseš šperhák, pochodeň a křesadlo (lit).

>zapal pochoden
(křesadlem)
Zapálená pochodeň příjemně praská a vydává hodně světla.

Křesadlo dohořelo a plamen mizí v obláčku dýmu.

>

- po několika příkazech hra vypíše: "Pochodeň už vyhořela až na konec a zrovna zhasíná.", toto chování předpokládám musím potlačit změnou metody objektu Candle. Právě se koukám do T3TourGuide na stranu 104, kde autor popisuje vytvoření nové třídy RedCandle a právě metoda dobjFor(BurnWith) bude nejspíše ta pravá:

dobjFor(BurnWith)
{
   check()
   {
      if(fuelLevel < 1) // tento if musím potlačit?
        sayBurnedOut;
      else
        inherited; //volání předka tohoto objektu, pokud dobře rozumím?
    }
}

--------------------------------------------------------------------------------------------------------------------------

Křesadlo se stále chová jako sirka, viz "Škrtnutím křesadla zapaluješ malý plamínek." Po zadání i se v inventáři objeví „křesadlo (lit)“, zde asi bude nepřeložený textový řetězec. Následně křesadlo dohoří stejně jako sirka v Sample games - LightFireSource.

Napadlo mě modifikovat jednu z metod objektu Matchstick tak, aby lépe odpovídal křesadlu - je tento mnou zamýšlený postup správný? Pokud ano, pokusím se přijít na to, kterou. Skutečně jsem zatím nepřišel na jinou možnost jak zapálit nehořícím objektem objekt hořící, při vyhledávání na internetu jsem ještě narazil na zjednodušenou knihovnu adv3lite, která pravděpodobně tuto situaci řeší elegantněji:

http://tads3.gerynarsabode.org/index.php?title=Thing_(adv3Lite)

--------------------------------------------------------------------------------------------------------------------------
canBurnWithMe    
Use this property to declare that a player can burn something with the object being defined. The default setting is that one cannot use objects to burn other things with. Can be either true or nil
canBurnWithMe = true
--------------------------------------------------------------------------------------------------------------------------

Rád bych se však alespoň zpočátku naučil knihovnu klasickou, protože výše popsané zjednodušení mi ve výuce programování určitě nepomůže. Dostupná dokumentace je dle mého názoru perfektní, to spíše já zatím ještě neumím dohledat všechny potřebné informace.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 9. Říjen 2017 - 19:36
...divím se, že není k nalezení možnost zapálit pochodeň křesadlem, že by něco takového žádný autor pro textovku nepotřeboval?

Ono těch různých možných kombinací je hodně, takže TADS nemůže postihnout úplně každý případ a proto dává k dispozici jen obecný rámec, který si musíš podle situace trochu přizpůsobit. Jak jsi asi zjistil, existuje mix-in třída FireSource, která představuje hořící objekt který může něco zapálit. To není úplně tvůj případ, protože chceš křesadlo, které může zapálit, ale samo o sobě nehoří. Nicméně je je docela dobrý nápad se podívat do knihovny na definici třídy FireSource, abys viděl, jak je udělaná. Je v ní akorát definice iobjFor(BurnWith), tedy nepřímého objektu akce zapal (přímý je ten, co bude zapálen a nepřímý ten, který slouží jako pomůcka zapálení).

Pojdme tedy udělat obyčejný objekt (Thing) a dát mu iobjFor(BurnWith), jen ho trochu zjednodušíme, aby křesadlo samo nehořelo. Pochodeň je vzata víceméně ze sample games. PreferredIobje je tam proto, že zapal nepoužívá předložky a tak je pro parser neodhadnutelné, co zapaluješ čím, tak si to sám prohodí tak, aby to dávalo smysl.

Kód: [Vybrat]
+ PreferredIobj, Thing 'křesadlo/křesadla/křesadlu/křesadlem' 'křesadlo' *4
    "Snad by se s ním dal rozdělat oheň. "

    iobjFor(BurnWith)
    {
        preCond = [objHeld]
        verify()
        {
            /* don't allow using me to light myself */
            if (gDobj == self)
                illogicalNow(&cannotBurnDobjWithMsg);

            nonObvious;
        }
    }
;

+ FireSource, Candle 'pochodeň/pochodně/pochodni/pochodní' 'pochodeň' *3
    desc()
    {
        if(isLit)
            "Hoří plápolavým plamenem<<if fuelLevel < 3>>, ale ten už začíná dohasínat<<end>>. ";
        else
            "Kdyby se Ti jí podařilo zapálit, jistě by vydávala hodně světla. ";
    }
    fuelLevel = 7
    brightnessOn = 2

    dobjFor(BurnWith)
    {
        check()
        {
            if(fuelLevel < 1)
                sayBurnedOut;
            else
                inherited;
        }
    }
;

Křesadlo se stále chová jako sirka, viz "Škrtnutím křesadla zapaluješ malý plamínek." Po zadání i se v inventáři objeví „křesadlo (lit)“, zde asi bude nepřeložený textový řetězec. Následně křesadlo dohoří stejně jako sirka v Sample games - LightFireSource.

Napadlo mě modifikovat jednu z metod objektu Matchstick tak, aby lépe odpovídal křesadlu - je tento mnou zamýšlený postup správný?

Matchstick je objekt, který můžeš zapálit sám o sobě, tj. zapálíš a hoří matchstick a od něj můžeš zapálit něco jiného, takže to moc neodpovídá. To (lit) u sebe nemám, možná jsem to někdy přeložil později a není to ve zveřejněné knihovně a nebo je to někde, kde nevím kde. Candle dědí z FueledLightSource, takže časem dohoří. Kdybys to chtěl odrušit, tak viz:

Kód: [Vybrat]
    /*
     *   If the light source can burn forever, simply return nil as the
     *   fuel level. 
     */
    getFuelLevel() { return fuelLevel; }

Rád bych se však alespoň zpočátku naučil knihovnu klasickou, protože výše popsané zjednodušení mi ve výuce programování určitě nepomůže. Dostupná dokumentace je dle mého názoru perfektní, to spíše já zatím ještě neumím dohledat všechny potřebné informace.

Adv3lite má na svědomí Eric Eve. Totiž ono to bylo tak, že po uvedení TADS 3 spousta lidí léta remcala, že to programování je moc těžké a nebyli ochotni přejít z TADS 2 dál. A vznikla taková pověra, že kdyby to programování bylo snazší, že by to umožnilo mnohem snadnější vstup do této oblasti těm, kteří pro domělou snadnost dávají přednost Informu a dalším systémům.

Mike Roberts zkoušel něco udělat, napsal nový trochu jednodušší parser nazvaný Mercury, ale neměl už moc času dotáhnout celou situaci až do stavu alternativní knihovny, která by byla obtížností někde mezi TADS 2 a 3. Eric se toho tehdy ujal a naprogramoval Adv3Lite. Původní idea byla odstranit některé ze složitějších vlastností, které knihovnu komplikují (postoje postav, simulování smyslů, hru v reálném čase, tisk řetězců přes žurnál atp.), ty totiž hodně znesnadňovaly orientaci a málo kdo je využil. Původní plán byl udělat hodně jednoduchou knihovnu, která by sloužila jako mezikrok pro programátory, než se pustí do plnohodnotné Adv3. Skutečnost však šla kousek dál, došlo k mohutné redukci, knihovna má o hodně menší počet tříd, ale zároveň i přidává některé nové vlasntosti, třeba scény, takže nakonec není ani zdaleka tak lite, jak se někteří původně domnívali a remcalové remaci dál...

No z hlediska našeho je hlavní problém v tom, že k ní není k dispozici překlad a nebude.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 12. Říjen 2017 - 12:27
1. Křesadlo a pochodeň
Nádherně vysvětleno, právě se dívám na mix-in třídu FireSource, která má jedinou podtřídu Matchstick a jedinou metodu iobjFor(BurnWith).  A pokud si třídu rozkliknu odkazem 1895, skutečně vidím „We don't provide any action handling - we leave that to the direct object.“ - tady autor přímo nabádá, abych si odvozený objekt upravil, přesně jak píšeš.

S „PreferredIobj“ jsem se zatím nesetkal nebo si jej nevšiml, vidím, že jej používáš ve svém překladu a konkrétně v demonstraci Attachable:

preferredIobj = nil
replace doActionMain()

Dívám se na třídu FueledLightSource, zde je jako jediná podtřída uvedena Candle. Direktivu getFuelLevel() { return fuelLevel; } jsem našel při rozkliknutí odkazu třídy i její podtřídy, odkaz extras.t 2079 i 2205.

Nyní vše v pochodní funguje, viz soubor Exoter_v2.t, jediný problém, který zatím vidím, je příkaz:

>zapal pochoden kresadlem
To není něco, co by mohlo hořet.

ale

>zapal pochoden
Čím ji chceš zapálit?

>kresadlem
Zapaluješ pochodeň.

funguje parádně, zatím to tak nechám, tyhle detaily si nechám na později.

Hledání ve třídách, vlastnostech, metodách apod. v knihovně už je mi jasné, teď se mi jen vše musí spojit dohromady, chápu, to chce čas, jo to vlastně „gró“ programování. Místo abych hledal v knihovně, snažil jsem se nalézt co nejvíce v příkladech, což je asi běžný postup programátorů začátečníků. Upřímně řečeno přes obrovský záběr TADSu jsem si ani neuvědomil, že tak triviální věc jako zapálení pochodně křesadlem, troudu ocílkou nebo obyčejné rozdělání ohně něčím jiným, než sirkami, zde není už jako hotové řešení, tady jsem dost ovlivněn našimi textovkami a příkazem použij – je ale jasné, že standardní knihovna bude popisovat jen obecné věci, vše obsáhnout nelze, chápu, že se s tím v budoucnu setkám i v C++ a jiných jazycích, asi proto existují knihovny rozšiřující, které se snaží nějakou konkrétní množinu problémů řešit. Na programátorovi je také to, aby tyto knihovny znal a ve svém projektu je uměl použít plus to, co jinde nenajde, dokončil sám, to mi stále více a více ukazuje praxe.

Teď když už se s Library reference manual více kamarádím a ještě jednou si prohlížím třídu FueledLightSource, napadá mě otázka, co znamená a k čemu slouží soubor  extras.t, na jehož definici se dívám? Když si přeložím popis „This module defines classes for specialized simulation objects. “, vidím, že se jedná o modul, který definuje třídy pro objekty specializující se na konkrétní simulaci. Jedná se tedy o hlavičkový soubor umístěný v podadresáři lib a když rozkliknu odkaz Source file, mimo celého bohatě komentovaného dokumentu vidím, že na začátku obsahuje direktivu:

#include "adv3.h"

To znamená, že odkazuje na standardní knihovnu adv3, okolo které se celý TADS točí, teď už mi to do sebe více zapadá.

Možná bude pro mě lepší, když budu více zkoumat Library reference manual a nejlépe zkoušet dostupné příklady, tak pochopím více, ostatně i Eveho manuál sem mnohokráte odkazuje. Definice místností a objektů je mi již víceméně jasná, rozhovory s NPC postavami si nechám na jindy, nyní mi jde hlavně o akce, o kterých píšeš i ve svém manuálu a k jejich definici potřebuji pořádně pochopit práci s metodami, o nic se, jak překpokládám, dozvím nejvíce zde. 

2. Nepřeložený řetězec "lit"
Ještě jednou jsem si zkusil projet moji původní verzi Exotera, zde se po zapálení pochodně křesadlem s tím, že jej definuji jako Matchstick, viz soubor Exoter_v1.t, objeví toto:

„Neseš šperhák, pochodeň (svítí) a křesadlo (lit).“

Následně jsem to samé zkusil po Tebou navrhované úpravě, viz soubor Exoter_v2.t:

Neseš šperhák, pochodeň (svítí) a křesadlo.

V souborech cs_cz.t a msg_neu.t je dle mého laického pohledu vše v pořádku, zde asi překladač k objektu Matchstick přiřadil chybný textový řetězec nebo je na místě, které jsem zatím nenalezl. Pokud budeš v budoucnu připravovat další verzi češtiny, prosím o kontrolu objektu Matchstick a přidání překladu, snad alespoň tímto svým testováním alespoň trochu pomohu k jeho zlepšení.

3. Knihovna Adv3lite a TADS Workbench
Moc děkuji za parádní popis této knihovny, chápu, proč lidi toužili po něčem jednodušším, upřímně řečeno jsem dle Tvého popisu nabyl dojmu, že TADS2 byl mnohem jednodušší na použití, než třetí verze, já jsem se setkal až s trojkou.
Sakra, nečekal jsem, že tato knihovna přidává i nové vlastnosti, na druhou stranu vidím, že dopadla podobně jako např. Wordpress nebo Nginx, původně štíhlé projekty vesele bobtnají a původní záměr mizí. I proto je mi velmi sympatická knihovna ncurses, mám rád jednoduché řádkové aplikace s rozhraním ála M602 nebo dosedit, které jsou určené k jediné konkrétní činnosti nebo mé oblíbené účetnictví Tichý – Ježek, které i po dvaceti letech zachovává stejné rozhraní a jen upravuje funkcionalitu, dnes podporuje i EET a existuje i snadný krok, jak jej plně integrovat do Linuxu.
Zatím jí tedy nechám na pokoji, pokud neexistuje překlad, není pro mě určena, takže se na ní podívám v budoucnu. Ta klasická mě stále více a více ohromuje tím, co vše dokáže, takové práce, kterou autoři věnují komunitě, si nesmírně vážím.
S tím Informem jsem si také trochu hrál, na root.cz vyšel i český článek tuším o dvou dílech, který základy popisuje, vypadá mnohem jednodušší, ale obávám se, že složitější problémy už nebude taková sranda realizovat a domnělá jednoduchost se rozplyne jak pára nad hrncem. Pro mě je tedy TADS výhodnější,  díky českému překladu a  především jako parádní příprava na C++.

Neodolal jsem a do google jsem zadal „TADS Workbench source“, napadlo mě, když je TADS otevřený, zda jsou i k WB k dispozici zdrojové kódy. V diskuzi:

https://www.intfiction.org/forum/viewtopic.php?f=10&t=4088

Jeden diskutující píše: „The Workbench source is available as part of the htmltads source release. It's all built directly on Win32 (no MFC or any other Microsoft class libraries are involved).“

Plus zde na github:

https://github.com/uliwitness/TADSWorkbench

Jsou k dispozici nějaké zdrojáky, zběženě jsem je prozkoumal a vypadá to, že jsou určeny pro MAC, ostatně pro něj je k dispozici i starší oficiální verze dostupná na stránkách.  Škoda, linuxový WB by byla paráda plus jak jsem minule psal ta verze ncurses/GTK/QT, jen ty zdrojáky mě zatím opravdu děsí, je jich nějak privela…
Takže zatím zůstanu u kombinace Frobtads/editor českého textu/WB ve Wine, sice trochu krkolomné, ale naštěstí funkční.

4. Lano a attachable obecně
Nyní po vyřešení pochodně bych se rád vrhnul na přivázání lana k temné studni a vše, co s tím souvisí. Využiji všechny dostupné znalosti, jak vidím, attachable je parádně popsaná v manuálu i v Library plus připravil jsi parádní demonstrační hru, pokusím se vše vyřešit sám, jedině tak se dostanu zase o krok dále.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 12. Říjen 2017 - 12:28
... ještě ty přílohy...
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 12. Říjen 2017 - 23:23
1. Křesadlo a pochodeň
Nádherně vysvětleno, právě se dívám na mix-in třídu FireSource, která má jedinou podtřídu Matchstick a jedinou metodu iobjFor(BurnWith).  A pokud si třídu rozkliknu odkazem 1895, skutečně vidím „We don't provide any action handling - we leave that to the direct object.“ - tady autor přímo nabádá, abych si odvozený objekt upravil, přesně jak píšeš.

To není narážka na odvozený objekt, ale na něco trochu jiného. TADS je založený na objektově orientovaném programování a to znamená, že se k herním objektům píší různé metody, které něco dělají. K akcím, které používají dva objekty (přímý a nepřímý), jako zapal koho/co kým/čím, se váží hned dva objekty ve dvou rolích. Přímý objekt, který je manipulován (pochodeň) a nepřímý, který slouží jako pomůcka (křesadlo). Výsledek takové akce se dá naprogramovat na dvou místech. Buď v metodě dobjFor(BurnWith) u pochodně nebo v iobjFor(BurnWith) křesadla.

Na kterém místě reakci naprogramovat je na tvém uvážení. Je to zpravidla jedno. V tom se objektový přístup trochu liší od třeba Informu, který je založen na tabulkách s pravidly. Tam se prostě přidá pravidlo a nemusí se přemýšlet, ke kterému objektu ho přilepit, prostě se hodí na jednu společnou hromadu všech pravidel.

To, co se v manuálu píše tedy říká, že akce bude naprogramovaná u přímého objektu a tady u nepřímého tedy není nic.

S „PreferredIobj“ jsem se zatím nesetkal nebo si jej nevšiml, vidím, že jej používáš ve svém překladu a konkrétně v demonstraci Attachable:

Parser sám neumí poznat, co je přímý a co nepřímý objekt u akcí, které nemají předložku, např. můžeš napsat "podej kafovak Borisovi" i "podej Borisovi kafovak". Proto třída Actor je označkovaná jako PreferredIobj a podle toho, když parser vezme objekty obráceně, tak je před dalším zpracováním prohodím. Je to právě ta situace, kdy by hra řekla, že kafovaku nemůžeš Borise podat. Značka říká, který z objektů je nepřímý, aby se to prohodilo do správného pořadí. U kací s postavou je to automaticky v knihovně, ale u některých akcí nebo nových akcí se to nedá dopředu určit a tak to musí udělat autor hry. Co ještě musím udělat je opačnou variantu, PreferredDobj, protože to u některých akcí je potřeba.

Nyní vše v pochodní funguje, viz soubor Exoter_v2.t, jediný problém, který zatím vidím, je příkaz:

>zapal pochoden kresadlem
To není něco, co by mohlo hořet.

ale

>zapal pochoden
Čím ji chceš zapálit?

>kresadlem
Zapaluješ pochodeň.

funguje parádně, zatím to tak nechám, tyhle detaily si nechám na později.

Jo, já se podívám, jaká verze knihovny je zveřejněná a vyzkouším to.

Teď když už se s Library reference manual více kamarádím a ještě jednou si prohlížím třídu FueledLightSource, napadá mě otázka, co znamená a k čemu slouží soubor  extras.t, na jehož definici se dívám?

Knihovna je poměrně velká, čítá téměř 100 tis. řádek a proto je rozdělená do většího množství souborů, je jich kolem čtyřiceti. Snaha je, aby žádný nebyl extrémně velký. Některé třídy, jako např. Thing, které jsou základem všeho, tak jsou už tak dost velké. Zabírají jeden celý velký soubor jen s pár drobnostma navíc (thing.t). Všechny objekty, které od Thing dědí, jsou rozdělené do několika souborů. Většinu najdeš v objects.t (dveře, kontejnery a kde co), ale pár jich je i v souboru extras.t a tam jsou takové ty exotičtější, jako komplexní kontejnery, baťoh, klíč a další. Jsou to věci, které začínající programátor asi hned nepoužije a myslím, že je to taková sbírka kódu, který naprogramovali (nebo navrhli) pro TADS vesměs jiní lidé, když hledali, čím knihovnu ještě obohatit. Myslím, že nebyly součástí TADSu od úplného počátku.

Jedná se tedy o hlavičkový soubor umístěný v podadresáři lib a když rozkliknu odkaz Source file, mimo celého bohatě komentovaného dokumentu vidím, že na začátku obsahuje direktivu:

#include "adv3.h"

Hlavičkové soubory jsou ty s příponou .h a normální zdrojáky mají koncovku .t. Hlavičkový soubor je zjednodušeně něco, co jen učí kompilátor rozumět zdrojovému kódu v .t souboru. Proto se inkludují do každého .t souboru na začátku. Nic co je uvedeno v hlavičkovém souboru se nepřeloží do výsledné hry, nevznikne žádný program. Jsou v nich tedy hlavně definice maker, šablon atp., ale žádný příkaz, žádná proměnná.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 14. Říjen 2017 - 21:10
Zveřejnil jsem poslední verzi knihovny, kterou mám. Je tam jen pár drobných oprav. To s tím (lit) nevím, já když to vyzkouším u sebe se zdrojákem, který jsi přiložil, tak mi to v inventáři normáně česky píše, že pochodeň (svítí). Nevrtal ses v knihovně sám? Nebo nemáš nějakou jinou verzi TADSu, než já? Já mám normálně TADS 3.1.3, to by měla být poslední zveřejněná verze.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 16. Říjen 2017 - 11:34
1. Přímý a nepřímý objekt

Konečně se zase dostávám k programování, krásné počasí o víkendu jsme celé projezdili. Paráda, teď už je mi
konečně věta we "leave that to the direct object" jasná, s přímými a nepřímými objekty se zde aktivně setkávám právě až u pochodně, Ericův manuál studuji postupně, vidím, že o nich píše v sekci Actions a právě u třídy Attachable, o které se zmíním později. Metodu iobjFor(BurnWith) jsem využil u křesadla, vyzkoušel jsem si i dobjFor(BurnWith) u pochodně, kterou jsem nakonec zakomentoval, k tomuto řešení bych se přiklonil v případě, že bych chtěl řešit její postupné vyhasínání, čímž u Exotera hráče trápit zatím nechci. Vidím, že jsi studoval také Inform, ten jsem zatím nezkoušel, snad časem, ovšem vypadá to, že TADS je tak komplexní, že jeho možnosti ani nebudu schopen využít. Na ten kafovak u Borise se juknu do Tvých zdrojáků, ohledně PreferredIobj není samozřejmě v Learning TADS 3 ani slovo, je mi jasné, že jsi jej potřeboval vytvořit sám při přípravě překladu.

2. Knihovna, hlavičkové soubory, zdrojáky a historie TADS

Podíval jsem se na adresářovou strukturu frobtadsu, nyní je to krásně vidět, hlavičkové soubory vidím v /usr/share/frobtads/tads3/include, vidím, že i u nich existuje vnořené inkludy, např. hned ten první bignum.h inkluduje systype.h . A na stejné úrovni adrsář /lib vidím zdrojáky s příponou .t, jasně, zde je ten obrovský thing.t, objekty, eventy a v neposlední řadě knihovna adv3.h, o které jsme se bavili minule. Napadá mě jak byla vygenerována dokumentace, vím, že např. u Javy nebo PHP lze vygenerovat dokumentaci z komentářů, předpokládám správně, že webová Library reference vznikla podobně?

Dívám se, že zde mám nainstalovanou také starší verzi TADS2 s mnohem skromnější strukturou, jedná se krom dokumentace jen o 3 soubory:
/usr/share/frobtads/tads2/adv.t
/usr/share/frobtads/tads2/gameinfo.t
/usr/share/frobtads/tads2/std.t

jak vidno, posun ve třetí verzi a tedy i složitost, je obrovský.

Právě to mě nejvíce láká, časem díky znalosti jazyka C budu schopen zkoumat tyto soubory a chápat, o čem jsou a jak linux opravdu funguje. Teď se dívám na wikipedii, TADS2 byl psán nebo spíše jeho syntaxe vycházela z C a trochu z Pascalu, zatímco TADS3 je úplně jiný objektový model vycházející z C++ a z Javy plus využití VM, o tom píšeš i Ty ve svém manuálu.

Zdálo by se tedy a někteří diskutující programátoři jsou toho názoru, že učit se staré C je už přežitek stejně jako Pascal, na druhou stranu pokud chci jít do hloubky, bude lépe se věnovat právě starému C a teprve poté C++, cítím, že jedině tak mohu programování opravdu do hloubky pochopit, viz Tvůj názor na prvotní výuku pomocí skriptovacích jazyků. Jen nevím, zda to pro mě nebude trochu obtížné, když se nyní snažím pochopit objektový model a budu se vracet ke strukturovanému, když se ovšem dívám na C++, není to čistě objektový jazyk a některé konstrukce jsou převzané z C, tak to snad půjde. Pascal, i když jeho implementace FreePascal a Lazarus už je objektová, mi dnes asi nic nedá a skutečné využití pro mě nevidím.

3. Attachable a malé rozšíření překladu

Pečlivě jsem prozkoumal popis této třídy v Learning TADS3, T3TourGuide, Tvůj překlad a také knihovnu. A vypadá to, že hurá, pečlivost se vyplatila, vytvořil jsem objekt studna, ke které pomocí metody canAttachTo(obj) lze přivázat provaz. U provazu jsem s definicí jako Attachable pohořel, to jsem ale očekával, manuály popisují, že typický problém, kdy jej přivázaný táhnu sebou celou mapou není tak jednoduché řešit. Napadlo mě použít NearbyAttachable, který tuto bolístku zvládá, nyní vše funguje jak má. U lana a provazu mě první slovo napadne přivaž/odvaž, nikoliv připevni, přidal jsem jej tedy do souboru cs_cz.t z aktuální verze překladu, tam i v budoucnu budu dávat synonyma. Společně s aktuálním zdrojákem a průchodem hrou jej zasílám v příloze, třeba Ti cokoliv z toho pomůže u tvorbě dalších verzí.

Ukončení hry sebráním 4 diamantů už naprogramovat nebude problém, toto popisuje i manuál, nyní musím vyřešit snad již poslední bolístku, což jsou boje se strážcem, drakem a psem. Tady jsem dříve také zuřivě hledal na internetu, teď znovu prozkoumám knihovnu, pokusím se najít obecnou formulaci a vymyslet řešení, bude to podobné jako Tvůj příklad s pochodní a křesadlem. Začíná mě to stále více bavit, což je přesně to, co potřebuji.

4. Nová verze překladu

A vidím, že jsi zveřejnil novou verzi překladu, vše jsem vyzkoušel. Pokud vím, nic kromě souboru cs_cz.t jsem neupravoval a používám skutečně verzi 3.1.3, s tou jsem také před lety začínal. Nyní již je pojem křesadlo(lit) minulostí, tehdy jsem chybně definoval jeho metodu, pochodeň skutečně svítí jak je vidět v přiloženém transskriptu hry.

Zkusil jsem ještě jednou starší verzi definice křesadla:
+ kresadlo : FireSource, Candle 'křesadlo/křesadla/křesadlu/křesadlem' 'křesadlo' *4
a po jeho zapálení je vidět:
 Neseš šperhák, pochodeň (svítí) a křesadlo (svítí).

I tak je tedy vše v pořádku, je ale samozřejmě možné, že jsem si s překladem hrál více, než je zdrávo a upravil něco, co jsem neměl. 
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 16. Říjen 2017 - 20:36
Napadá mě jak byla vygenerována dokumentace, vím, že např. u Javy nebo PHP lze vygenerovat dokumentaci z komentářů, předpokládám správně, že webová Library reference vznikla podobně?

Ano, přesně tak, referenční příručka je generovaná z komentářů v knihovně.

Zdálo by se tedy a někteří diskutující programátoři jsou toho názoru, že učit se staré C je už přežitek stejně jako Pascal, na druhou stranu pokud chci jít do hloubky, bude lépe se věnovat právě starému C a teprve poté C++, cítím, že jedině tak mohu programování opravdu do hloubky pochopit, viz Tvůj názor na prvotní výuku pomocí skriptovacích jazyků. Jen nevím, zda to pro mě nebude trochu obtížné, když se nyní snažím pochopit objektový model a budu se vracet ke strukturovanému, když se ovšem dívám na C++, není to čistě objektový jazyk a některé konstrukce jsou převzané z C, tak to snad půjde.

Abych to upřesnil, můj názor se týkal především skriptovacích jazyků v prostředí webového programování, které  je natolik specifickou doménou, že neposkytuje dobré možnosti pro pochopení základů. Mezi C a C++ bych nutně dělicí čáru nedělal, pochopit OOP je přirozenou součástí. Když budeš o C++ uvažovat tak, že je to Cčko s objektama a pár drobnostma navíc, tak to sice nebude úplně přesné, ale to nevadí. Prostě když se ti bude na něco hodit udělat třídu, tak udělej, když postačí procedurální kód, tak taky dobře.

U lana a provazu mě první slovo napadne přivaž/odvaž, nikoliv připevni, přidal jsem jej tedy do souboru cs_cz.t z aktuální verze překladu, tam i v budoucnu budu dávat synonyma. Společně s aktuálním zdrojákem a průchodem hrou jej zasílám v příloze, třeba Ti cokoliv z toho pomůže u tvorbě dalších verzí.

Jo, synonyma jsem si u sebe přidal. Ale obecně to není správný  způsob, TADS je udělán tak, abys nikdy nemusel do knihoven zasahovat. Cokoliv z knihovny můžeš změnit ve svém vlastním kódu hry. Kdyby ses podíval do zdrojáků Základny, tak podobné změny tam jsou soustředěné v souboru componentMods.t. Všimni si, že každou knihovní třídu můžeš změnit pomocí klíčového slova modify či replace.

A třeba přidání nějakých synonym se dá udělat jednoduše tím, že si patřičnou VerbRule napíšeš u sebe. Buď přidáš další VerbRule ke stejné akci, jako jsem přidával slovo 'bodni' jako synonymum AttachTo v roomControl.t a nebo můžeš existující VerbRule nahradit pomocí klíčového slova replace. Tak jsem třeba v souboru s počeštěním spelling correctoru nahrazoval původní anglické příkazy.

Jo a dej si pozor, máš tam provaz.moveinto(studna), ale mělo by to být s velkým písmenkem moveInto. Při překladu na to dostaneš upozornění, chce ho to číst.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 19. Říjen 2017 - 14:24
1. C a C++
Ano, podobnou definici jsem nalezl i na diskuzních fórech programátorů, tady bude asi jen opravdu malý rozdíl, někteří diskutující srovnávali C++ a Javu s tím, že Java je plně objektová, což asi nebude ve všech případech to pravé, nevím, toto zjistím až s dalšími zkušenostmi. Každopádně jsem si nainstaloval cppreference a cppman a zkouším jejich integraci s různými IDE a VIMem, to jistě využiji u různých tutoriálů, o kterých jsem psal v minulých dílech.

2. synonyma
Jasné, do knihovny raději už zasahovat nebudu, vlastní změny ve svém kódu určitě budou lepší řešení. Prozkoumal jsem componentMods.t a pokoušel se definovat synonymum dle roomControl.t. Ještě předtím jsou použil Tvůj překlad cs_cz.t a přepsal jím svůj upravovaný, jenže ouha, od té doby při hře vidím:

přivaž provaz
K čemu ho chceš připevnit?
>studna
(nejprve dáváš provaz na podlahu, potom ho uvolňuješ od studnu)
Provaz jsi spustil dolů.
>d
Studna je moc hluboká na to, abys do ní skočil jen tak.

a tohoto hlášení se nejsem schopen zbavit, i když jsem mnou upravenou češtinu zase nahrál zpět, hlášení je zde po kompilaci ve WB i Frobtadsu…
Musel jsem nebo možná Workbench nějakým příkazem přepsal definici AttachTo, budu hledat, sakra, tohle jsem nečekal.

3. chybové hlášení
No jo, máš recht, příkazu provaz.moveinto(studna) jsem si opravdu nevšiml, na debug ovšem používám Workbench s výchozím nastavením a o chybě píše pouze Frobtads:
Frobtads:
   compile Exoter.t -> obj/Exoter.t3o
Exoter.t(338): warning: undefined symbol "moveinto" - assuming this is a property name
   link -> Exoter.t3p
   preinit -> Exoter.t3
Errors:   0
Warnings: 1

---

Workbench – příkaz Compile for Debugging i Full Recompile for Debugging:

Tip: you can go to the source location of a compile error
by double-clicking on the error message in this window

----- begin build: Thu Oct 19 13:02:03 2017 -----
>t3make -Fy "Z:\home\wanbli\Plocha\TADS\Exoter\obj" -Fo "Z:\home\wanbli\Plocha\TADS\Exoter\obj" -o "Z:\home\wanbli\Plocha\TADS\Exoter_�s\Makefile_dbg.t3" -D "LANGUAGE=cs_cz" -D "MESSAGESTYLE=neu" -D "INSTRUCTIONS_MENU" -d -statprefix <@> -statpct "system.tl" "adv3\adv3.tl" "Exoter.t" -res
TADS Compiler 3.1.3  Copyright 1999, 2012 Michael J. Roberts
Build successfully completed.
----- end build: Thu Oct 19 13:02:04 2017 -----

Zkusím se poohlédnout po chybě v mém nastavení, s warningy jsem se ovšem v minulosti setkával, je zvláštní, že tuto chybu neodchytil. Také je mi divné, že metoda „moveinto“ projde, v knihovně je opravdu pouze moveInto, tady je asi překladač benevolentní.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 19. Říjen 2017 - 14:29
A kruci, ani nevím jak mě napadlo vrátit se zpět a metodu provaz.moveInto přepsat zase zpět na provaz.moveinto a chyba se už neobjevuje…:

>prozkoumej studnu
Hluboká studna, nyní však již zcela vyschlá.
>přivaž provaz ke studni
(nejprve dáváš provaz na podlahu)
Provaz jsi spustil dolů.
>d
Sešplhal jsi dolů za pomoci přivázaného lana.
Ve studni
Jsi na dně studny. Je tu vlhko.
Můžeš jít nahoru.
Vidíš tu druhý drahokam.
>i
Neseš šperhák, pochodeň (svítí), svazek klíčů a křesadlo.
>n
Jihozápadní část nádvoří
Stojíš na nádvoří.
Můžeš jít na sever, na východ, na jih, dolů.
Je tu stará kamenná studna.
Vidíš tu provaz.
>polož pochodeň
Hotovo.
>d
Sešplhal jsi dolů za pomoci přivázaného lana.
Ve tmě
Je tu naprostá tma.
>n
Jihozápadní část nádvoří
Stojíš na nádvoří.
Můžeš jít na sever, na východ, na jih, dolů.
Je tu stará kamenná studna.
Vidíš tu provaz a pochodeň (svítí).
>vezmi pochodeň
Hotovo.
>vezmi provaz
(nejprve uvolňuješ provaz od studnu)
Hotovo.
>d
Studna je moc hluboká na to, abys do ní skočil jen tak.

Uff, tohle opravdu zatím nepobírám, ale nevadí, pořádně si prostuduji Tebou popsané části základny a pokusím se znovu definovat VerbRules.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 19. Říjen 2017 - 15:07
Exoter.t(338): warning: undefined symbol "moveinto" - assuming this is a property name

Zkusím se poohlédnout po chybě v mém nastavení, s warningy jsem se ovšem v minulosti setkával, je zvláštní, že tuto chybu neodchytil. Také je mi divné, že metoda „moveinto“ projde, v knihovně je opravdu pouze moveInto, tady je asi překladač benevolentní.

Praktický rozdíl mezi warningem a errorem je v tom, že při varování může překlad pokračovat dál. I když kód asi není v pořádku, není to závada tak velká, aby kompilátor zastavila. V případě moveinto s malým písmenkem si všimni, že prohlásí, že to bude asi nějaká zatím nedefinovaná vlastnost a tak s ní i zachází, tj. nezavolá tu správnou metodu.

Protože varování nezastaví překlad a spustitelný soubor se vytvoří, tak opakovaný překlad beze změny ve zdrojáku už pak daný soubor znovu nepřekládá. To bude nejspíš důvod, proč jsi neviděl varování při překladu ve workbenchi, ono se píše, ale ne při opakovaném překladu bez provedení změn, takže ho lze snadno přehlédnout.

Kdyby sis přidal při překladu volbu -we tak se všechna varování převedou na chybu, tj. jakmile na ně kompiler narazí, tak odmítne pokračovat s překladem. Pak budeš donucen takové chyby opravit hned, což by bylo nejlepší.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 19. Říjen 2017 - 15:11
Uff, tohle opravdu zatím nepobírám, ale nevadí, pořádně si prostuduji Tebou popsané části základny a pokusím se znovu definovat VerbRules.

Kdyžtak prosím upřesni.
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: Kroužící orel 20. Říjen 2017 - 14:22
Moc díky za vysvětlení s překladem, vyzkoušel jsem ve frobtadsu volbu -we a s definicí provaz.moveinto jsem opravdu pohořel.  A máš pravdu, vše jsem zkusil znovu a nyní již i WB píše:

TADS Compiler 3.1.3  Copyright 1999, 2012 Michael J. Roberts
Exoter.t(338): warning: undefined symbol "moveinto" - assuming this is a property name
Errors:   0
Warnings: 1

Zajímavé, včera jsem zkoušel WB restartovat a vše znovu kompilovat, druhý den vše funguje, nechce se mi věřit, možná že zafungoval „restart“ celého linuxu. Tak to je super, jen bych rád volbu -we využil i ve WB, zkoumal jsem jeho manuály, především The TADS 3 Debugger a zatím nenašel nic, co by mi pomohlo, ještě na to juknu.

Byl jsem nadmíru překvapen příkazem provaz.moveinto(studna) a vše jsem dnes ještě jednou otestoval a zasílám v příloze.

1. scénář – použil jsem svůj upravený soubor cs_cz.t, takže mi funguje příkaz přivaž zatím bez využití Tebou doporučovaného VerbRule, ve zdrojovém kódu je „chybný“ vnitřek metody provaz.moveinto. Takto vše v pořádku funguje a hra nemá problém s přivázáním provazu a vlezením do studny. V příloze jsou to soubory provaz_moveinto_Exoter.t, transskript_provazmoveinto.txt a cs_cz.t

2. scénář – stejně jako 1 bod, ale s využitím „správného“ vnitřku metody provaz.moveInto, zde hra píše nesmyslné hlášení:
(nejprve dáváš provaz na podlahu, potom ho uvolňuješ od studnu)
Provaz jsi spustil dolů.
// do studny se však nedostanu
>d
Studna je moc hluboká na to, abys do ní skočil jen tak.
V příloze jsou to soubory provaz_moveInto_Exoter.t, transskript_provazmoveInto.txt a cs_cz.t

3. scénář stejně jako bod 1, jen využívám Tvůj aktuální překlad cs_cz.t, který jsem si stáhnul na stránkách. Zde musím zatím místo „přivaž“ použít „připevni“, jinak ale vše funguje tak jak má.
V příloze je to soubor transskript_provazmoveinto_preklad_Gaspoda.txt

4. scénář stejně jako bod 2, jen využívám Tvůj aktuální překlad cs_cz.t, který jsem si stáhnul na stránkách. Zde dopadnu zase špatně, viz soubor transskript_provazmoveInto_preklad_Gaspoda.txt

Z toho jsem zmaten, zatím s využitím mého zdrojáku musím využít původní chybný provaz.moveinto, jinak nemohu provaz ke studni připevnit a dostat se dolů. Na druhou stranu se divím, že hra místo chyby vyhodí jen varování, v Library jsem našel jen moveInto.

Pokud se na to podíváš, budu moc vděčný, snad jsem se vyjádřil srozumitelně. Tady mi potíž přijde nelogická, spíš ale někde dělám chybu, o které zatím nevím.

Krásný víkend přeje

Orel
Název: Re: Seriál o programování textových her v TADS 3
Přispěvatel: gaspoda 20. Říjen 2017 - 20:33
Tak to je super, jen bych rád volbu -we využil i ve WB, zkoumal jsem jeho manuály, především The TADS 3 Debugger a zatím nenašel nic, co by mi pomohlo, ještě na to juknu.

Ony to jsou úplně stejné nástroje, jako ve frobtads, jen přeložené do Windows a Workbench je k nim doplněný jako nadstavba. Možnost naklikat tuto volbu najdeš v menu Build - settings - diagnostics - treat warnings as errors. To propíše danou volbu do makefile.

2. scénář – stejně jako 1 bod, ale s využitím „správného“ vnitřku metody provaz.moveInto, zde hra píše nesmyslné hlášení:
(nejprve dáváš provaz na podlahu, potom ho uvolňuješ od studnu)
Provaz jsi spustil dolů.
// do studny se však nedostanu
>d
Studna je moc hluboká na to, abys do ní skočil jen tak.
V příloze jsou to soubory provaz_moveInto_Exoter.t, transskript_provazmoveInto.txt a cs_cz.t

Ano, tohle jsou už docela zapeklité situace, kdy je potřeba si dobře uvědomit, jak to tam funguje. Podíváš-li se na popis NearbyAttachable, tak uvidíš, že se snaží vynutit, aby provaz sdílel se studnou stejný nadřazený kontejner. Jinými slovy, aby mohl být provaz přivázán, tak musí být umístěn přímo v místnosti, protože studna je také přímo v místnosti.

Citace
A "nearby" attachable is a subclass of Attachable that adds a
requirement that the attached objects be in a given location.  By
default, we simply require that they have a common immediate
container,...

Tedy nesmí být přímo ve studni, což se právě pokoušíš dělat pomocí toho moveInto. On se položí na podlahu jako součást přivázání ke studni, ale pak příjde tvůj příkaz přemístění do studny a tak se provaz poslušně zase odváže, aby mohl být strčen dovnitř studny. (Ta špatná koncovka "uvolňuješ od studnu" je jen překlep ve tvém skloňování.)

Takže nejjednodušší řešení je žádné moveInto nedělat (ani to chybné s malým i). Budeš-li to chtít vylepšit a skutečně mluvit o provazu ve studni, tak to chce pár změn. Jednak udělej studnu také NearbyAttachable, ať je vztah symetrický. Dále z ní udělej kontejner, aby se daly věci do ní vůbec dávat. No a nakonec si pomocí getNearbyAttachmentLocs definuj, kde má být provaz a studna, když jsou k sobě přivázány. Tedy ne vedle sebe v lokaci, ale v sobě:

Kód: [Vybrat]
++ studna : NearbyAttachable, Container, Heavy 'studna' 'studna' *3
    "Hluboká studna, nyní však již zcela vyschlá. "
    specialDesc = "Je tu stará kamenná studna. "

    canAttachTo(obj) {return obj == provaz;}
    handleAttach (other)
    {
        "Provaz jsi spustil dolů. ";
    }

    getNearbyAttachmentLocs(other)
    {
        return [location, self, 0];
    }

     gcName = 'studny, studni, studnu, studni, studnou'
     gcVocab = 'studny/studni/studnu/studnou'
;

Potom dostaneš něco takového:

Citace
>přivaž provaz
K čemu ho chceš připevnit?

>studna
(nejprve dáváš provaz do studny)
Provaz jsi spustil dolů.

>podívej se do studny
Studna obsahuje provaz.

>p studnu
Hluboká studna, nyní však již zcela vyschlá. Obsahuje provaz.

Studna je připevněna k provazu.

>p provaz
Je pevný.

Provaz je připevněn k studni.

>d
Sešplhal jsi dolů za pomoci přivázaného lana.

To je už jistě lepší, akorát je to trochu problém, že "Studna je připevněna k provazu.". To by ti mohla vyřešit třída SimpleAttachable, kterou napsal Eric Eve a je k dispozici v SampleGames ve zdrojácích attachment. Ta umí určit, který předmět je tzv. hlavní objekt (major) a pak správně mluví, který je připevněn k čemu.

Na druhou stranu se divím, že hra místo chyby vyhodí jen varování, v Library jsem našel jen moveInto.

Programátorům se poměrně často stává, že použijí nějakou proměnnou a zapomenou ji deklarovat. V dynamicky typovaných jazycích často ani deklarace nejsou potřeba. TADS tedy v rámci přítulnosti k autorům předpokládá, že když použiješ nějaký název, který nezná, tak že to je proměnná, kterou jsi zapoměl deklarovat a tak ji promptně vyrobí a vyhodí jen varování. Nechce působit prudérně.

TADS ale zároveň na rozdíl od leckterého jiného jazyka nedělá velký rozdíl mezi proměnnou a funkcí. Totiž tam, kde se očekává nějaká proměnná v objektu, která má hodnotu, tak TADS rád připustí metodu, která hodnotu vygeneruje. Proto si o neznámé metodě tak snadno pomyslí, že jde o zapomenutou deklaraci proměnné.

I když v tomto případě je to zmatečné, tak je to důsledek vlastností, které jinde zase pomáhají šetřit práci. On tě na to upozorní, jen to nesmíš přehlížet ;-)