Vlákno názorů k článku Programovací jazyk Go a 2D grafika – kostra jednoduché hry od kvr kvr - Chápu snahu o jednoduchost, ale co separace grafiky...

  • Článek je starý, nové názory již nelze přidávat.
  • 2. 4. 2020 3:19

    kvr kvr

    Chápu snahu o jednoduchost, ale co separace grafiky od herní logiky? ;-) . Hodit všechno do jedné struktury gameState je dost velký mix.

    Kdysi hodně dávno jsem napsal v SDL (později upraveno na SDL2) hračku wormik: https://github.com/kvr000/wormik.git , dokonce ji někdo dostal do nějaké distribuce (teď bych ji musel asi trochu oprášit, aby fungovala, jsou tam nějaké hardcoded cesty k resources a fontům apod). Port SDL na SDL2 nebyl úplně přímočarý, ale zase žádná velká tragédie (matně si vzpomínám, že největší problém bylo SDL2-ttf, které stále pracovalo s původním software surface). V každém případě SDL2 je asi logicky jediná volba dnes.

    Je otázka, zda 2D grafika má ještě moc velký smysl, na LCD se pak stejně mění scaling a výkonově je to asi už jedno (nebo možná i horší?). Přišlo mi, že ty různé alpha blending apod nejsou úplně přímočaré a hlavně závislé na kontextu, takže bych si tipnul, že možná přijde další upgrade, až budou chtít využít Vulkan backend (ale zkušenosti s 3D mám malé, tak je to jenom odhad).

    Jinak mi zatím z uvedených příkladů nepřijde až tak velký rozdíl mezi Go a C++, obzvláště, když se původní "defer delete whatever" přesunul do jedné funkce, která ještě možná není korektní v případě, že se povede jen částečná inicializace. Čímž nechcu podceňovat možnosti jazyka, ale tady bude ta logika docela jednoduchá na to, aby nějak výrazně těch vlastností využila...

  • 2. 4. 2020 13:34

    Pavel Tišnovský
    Zlatý podporovatel

    Jj s SDL (jednickou) uz dneska mohou byt i problemy pri instalaci zavislosti, dnes uz jen 2.

    SDL2, kdyz se pouziji textury, renderuje taky pres texturovaci jednotku GPU, takze tam rozdil nebude. I pri modulaci, scalingu atd.

    Rozdily mezi Go a C++ (nebo radeji spis C, protoze SDL je ceckovina) jsou treba v jednodussim handlingu chyb - proste chyba je bud nil nebo struktura s jejim obsahem. Nemusi se resit, jestli SDL_Init vraci zaporne cislo, funkce pro ziskani surface NULL a mraky dalsich vyjimek. Je to mozna malickost, ale pise se mi takto mnohem rychleji. Taky je fajn, ze proste muzu udelat strukturu ve funkci a vratit ukazatel na ni (tedy fajn - neni zapotrebi na to myslet).

    Jinak je samozrejme pravda, ze pro takto primitivni veci se moc rozdilu nepozna. Zkusim nahodit to reseni s gorutina pro NPC, to mozna bude flame :)

    PS: castecna inicializace - asi myslite, ze si nekdo zachyti panic() a bude pokracovat dal? Jj to muze nastat.

  • 2. 4. 2020 20:23

    kvr kvr

    Tou částečnou inicializací jsem myslel, že třeba něco z SDL init, create window a create surface uspěje a něco ne. Finalize se v takovém případě nezavolá (v případě poslední varianty kódu). Je pravda, že ty objekty stejně posbírá GC v nějakém náhodném pořadí, ale korektní by bylo ty resources pozavírat slušně v opačném pořadí a pak teprve provést panic a "návrat" z funkce. Takže ta jednoduchost je zčásti za cenu korektnosti :-) . Vrácená chyba asi něco ušetří, ale stejně by byla volána na dalším řádku, který tu chybu reportuje jako SDL_error() nebo něco podobného. Exceptions s pouze optimistickým blokem by asi byly nejjednodušší, i když samozřejmě stále by měly uzavírat resources korektně. Ošetřování chyb je vždycky peklo :-)

    Ohledně scalingu apod - jasně, performance asi bude celkem jedno, zvláště u takových hříček. Problém je, že 640x480 na celou obrazovku neodpovídá rozlišení LCD a původní hra předpokládá, že obrázek příšery nebo jiných ikon se mapuje 1:1 ze zdrojového obrázku na obrazovku. Třeba zmiňovaný Wormik používá asi 16x16 ikonky a celkové rozlišení 640x480 (počítám, že tady to skončí podobně). Kdyby se automaticky upravila velikost obrazovky podle rozlišení, mohly by být původní ikony větší a vyhlazovat se podle skutečného rozlišení. V zásadě je to pořád 2D, ale takové dynamičtější :-)

    Ty goroutines jsou docela zajímavý nápad. V normální (C) hře by to asi zabilo výkon mutexama, ale Go s GC si může hrát s funkcionálními vlastnostmi a se snapshoty stavu, takže jednotlivé objekty se mezi sebou nemusí nutně synchronizovat. V podstatě stejně jako multiplayer po síti, akorát tady v rámci stejného runtime. Držím palce!

  • 2. 4. 2020 23:54

    Calculon

    Když se použije panic, tak se všechny defery zavolají v opačném pořadí, takže zrovna tohle se chová korektně.

  • 3. 4. 2020 0:24

    kvr kvr

    V té poslední verzi ale právě ty defer chybí. Místo toho je tam jedna finalize funkce, která se zavolá v případě, že celá inicializace skončila úspěšná. Obecně, ta výhoda defer se ztrácí, pokud se má výsledek vrátit a defer-ovat pouze v případě neúspěchu.

    Ohledně GCD - mutexy byly myšleny na modifikaci sdíleného stavu jednotlivých objektů, to GCD nezachrání (pokud nebudu schopen v předstihu identifikovat, které objekty se mohou dostat do konfliktu). Ale možnost pracovat se snapshotem, který může potenciálně být outdated, by věc zjednodušit mohla. V C by se to dělalo o dost hůř, neboť by se musela řešit životnost snapshotu, což znamená opět nějakou synchronizaci. GC jazyky to zvládnou líp.

  • 3. 4. 2020 9:05

    Calculon

    Jo, to s tím finalize jsem přehlédl. Tam by se skutečně mělo testovat na nil.
    V GCD lze mít hodně front a určit serializovatelnost, když výběru serial namísto concurrent, žádné dva tasky nepoběží v rámci fronty zároveň (teoreticky na jednom vlákně, ale to si interně rozhoduje knihovna). Popravdě nevím, jestli to je efektivnější než konkurentní fronta a mutexy.

  • 2. 4. 2020 23:55

    Calculon

    V C by se dalo snadno použít něco jako GCD, což je ekvivalentní korutinám a funguje to bez mutexů.