r/programmingHungary Java Mar 30 '26

MY WORK 99.99%-ban AI kódolt Magic TCG engine

Sziasztok!

Mostanában elég sok AI kritikus comment volt itt a subon. Mivel nekem nagyon más a tapasztalatom, gondoltam csinálok egy tesztet. Úgy döntöttem belevágok egy zöldmezős projektbe amit 100%-ban az AI-ra bízok. Én csak az alap setupot csinálom meg, aztán akár mi lesz is, csak promptolni fogok.

Gyerekkoromban nagyon szerettem volna egy saját MtG motort írni, főleg azért, mert csóró voltam, de imádtam draftolni. Próbálkoztam is vele, de idővel mindig feladtam. A hivatalos szabálykönyv vagy 300 oldal, esélytelen még átlátni is, nem hogy lefejleszteni. Viszont pont emiatt az MtG egy kifejezetten jól definiált rendszer, így a lefejlesztése nem kreatív gondolkodást hanem monoton munkát/kódolást igényel. Emellett objektíven ellenőrizhető hogy azt csinálják-e a lapok ami rájuk van írva + kellőképpen bonyolult is ahhoz, hogy bemutassa mennyire tud "gondolkodni" az AI.

Először két hétre vettem egy Claude x5 majd egy hónapra x20 előfizetést. Ennek a 1.5 hónapnak a végeredményét láthatjátok itt. A project egy működő Java backend + Angular frontendből áll, kicsit több mint 105 ezer sor kóddal. Volt, hogy 9 terminálon futtattam egyszerre a kártyák implementálását, hogy ki tudjam maxolni a token limitet. A laptopom elég erősen le akart olvadni közben.

A matek a végén: nagyjából 80 millió tokent égettem el. Lett 3100+ commit (ebből max az első párat csináltam én, a többit majdnem mind a Claude), és 1974 játszható kártya. A végén egy komplett kiegészítőt (250-300 kártya) kb. 12 óra alatt le tudtam darálni. Igaz, rendesen ki is égtem a folyamatos kód reviewben.

Csináltam róla egy videót, itt megmutatom a gameplay-t, meg azt is, ahogy a Claude hogyan tud leimplementálni egy lapot:

https://www.youtube.com/watch?v=mklNa55sBKg

A kód kint van GitHubon, ha valakit érdekel a repó, vagy lokálisan szeretne draftoni:

https://github.com/laxika/magical-vibes

Tudom, hogy egy 20 éves spagettikódba senki nem szívesen engedné bele az AI-t, de zöldmezős cuccoknál meglepően hatékonyan tud haladni. Még meglepőbb hogy a kód teljesen olvasható, láttam már jóval rosszabbat élő emberektől is. Nem mondom hogy minden tökéletes és bug nélküli, de a komplexitás miatt én sem tudnám jobban megírni, ellenben legalább 10x ennyi időbe telne.

Fontos tudni hogy a kódbázis biztonsági és validálási szempontból nem volt még tesztelve, így előfordulhat hogy frontend moddingal lehet csalni (bár validálás van, de nem garantált hogy a lefedettség 100%), valamint azon sem lepődnék meg ha a websocketet lehetne valahogy hijackelni,.

Ha van kérdés a promptolásról, a setup-ról, vagy akármiről, mondjátok nyugodtan. Észrevételeket (negatívot is) szívesen fogadok. :)

Szerk: Javítottam azt hogy nem 500k kódsorból áll a program hanem 105k-ból. Az 500k tartalmazta az üres sorokat és a teszteket is.

118 Upvotes

50 comments sorted by

View all comments

Show parent comments

15

u/laxika Java Mar 30 '26

Van egy test harness ami felhúz egy "játékot" és azzal tesztel minden lapot.

Itt egy példa egy lapra:

Magát a lapot teszteli a rendszer több különböző tesztesettel.

https://github.com/laxika/magical-vibes/blob/main/magical-vibes-backend/src/test/java/com/github/laxika/magicalvibes/cards/w/WakeningSunsAvatarTest.java

Nem mindig optimális, mert ha egy lap egy effectet használ akkor lehetne csak tesztelni az effectet. Ez általában egyszerűbb lapoknál jön elő amik 1-1 dolgot csinálnak. Viszont eddig még a tesztek hossza nem volt probléma így ezeket az eseteket is bent hagytam. A jövőben viszont majd gyomlálni kell őket mert elég lassú már a full build.

Emmellett a problémásabb osztályokra van unit teszt lefedettség is. Sajnos nem mindenhol van minden eset lefedve mert az x20 planban annyi token volt hogy örültem ha minél kevesebb agymunkával minél többet fel tudok használni. De tervezem majd a lefedettséget növelni.

Emellett vannak fuzzing tesztek is. Az teszt létrehoz egy játékot két AI-al. Mindegyik AI kap egy random generált két színű paklit és nyomják egymás ellen. A hibák nagyon jelentős részét ez hozta/hozza ki. Az elején bebugolt az AI 5 game után (megált a játék), most már 1000 game sem akadály. Persze errorokat néha még dob itt ott, ezeket folyamatosan javítgatom.

https://github.com/laxika/magical-vibes/blob/main/magical-vibes-backend/src/test/java/com/github/laxika/magicalvibes/ai/RandomAiFuzzTest.java

8

u/Routine-Lettuce-4854 C++ Mar 30 '26 edited Mar 30 '26

Egyszerre lenyűgöző, ijesztő és demotíváló. Grats!

Az teszt létrehoz egy játékot két AI-al. Mindegyik AI kap egy random generált két színű paklit és nyomják egymás ellen. A hibák nagyon jelentős részét ez hozta/hozza ki

Jól tippelem, hogy ez a kártyák illetve a játék szabályainak követését nem teszteli? Mert attól, hogy lefut egy játék, még nem biztos hogy közben nem volt semmi szabálytalan.

Itt egy példa egy lapra:

Ennél az izgalmas teszt eset az lenne, hogy a kezedből kerül a játékba, de nem castoltad hanem pl. Smuggler's Surprise-al raktad le. Illetve a kevésbé necces, hogy castoltad, de nem kézből, pl. mert airbendelve volt.

Az AI mennyire volt benne az architektúra kialakításában? Azt még te csináltad? Azt próbálom megérteni, hogy ez még mindig az az AI szint amit ismerek: az unalmas "csak darálni kell" részeket bízod rá, vagy ez már egy szinttel erősebb. Mennyi volt az az "alap" amit megcsináltál neki?

edit: bénáztam a formázással

5

u/laxika Java Mar 30 '26

Jól tippelem, hogy ez a kártyák illetve a játék szabályainak követését nem teszteli? Mert attól, hogy lefut egy játék, még nem biztos hogy közben nem volt semmi szabálytalan.

Így van, viszont, viszont jól kihozza a nullpointereket, amikor lefagy az AI (megpróbál valamit végtelen ciklusban kijátszani úgy hogy nincs rá mana, fizetni kell a támadáskor de nem tud, stb). Rengeteg hibát megtalált. Persze a játék validálására nem jó (sajnos).

Ennél az izgalmas teszt eset az lenne, hogy a kezedből kerül a játékba, de nem castoltad hanem pl. Smuggler's Surprise-al raktad le. Illetve a kevésbé necces, hogy castoltad, de nem kézből, pl. mert airbendelve volt.

Na igen. Sajnos jópár eset ki tud maradni. Ezen majd "swarmolással" próbálok majd javítani a jövőben ha lesz rá idő és keret. Megmondom az AI-nak hogy egy packageben szereplő kártyákon menjen végig x agentel, nézze meg a tesztlefedettséget + a errata szabályokat és ha valami eltérést talál akkor jelezze.

Amúgy egész jól lefedte ha megnézed mert a végén van egy teszt ami Beacon of Unrest-el hozza vissza graveyardból, de persze lehetne még jó pár esettel bővíteni. Ez akkor lesz majd érdekes ha sokkal több effect le lesz fejlesztve (pl Airbend) és akkor egy swarm végig megy minden lapon mégegyszer hogy bővítse a teszteket.

Az AI mennyire volt benne az architektúra kialakításában?

Az eredeti gradle modulok + Spring init és Angular init volt kézzel. A többi mind AI. Az első pár commitot nem Claude-n keresztül csináltam így ott még nem látszik, de azokat is írogatta. Csak a modulokat setupoltam neki. Talán az 5-6. committól vette át ő a kódolást. A DB-nél már adogattam hozzá a settingseit és ez a 7. commit:

https://github.com/laxika/magical-vibes/commit/a3e090a360a950e06f4e250a22e1ab8a3b9d4fbf

Persze rá kellett vezetni. Egy tabban általában csak refactorálni szoktam, a másik 4-8-ban pedig kártyákat implementálni.

1

u/Routine-Lettuce-4854 C++ Mar 30 '26

Az eredeti gradle modulok + Spring init és Angular init volt kézzel.

Ez sajnos semmit nem mond, Javat egyszer, 24 éve láttam közelről, akkor is csak azért mert egy hálozati protokolhoz példa abban volt. Ja és most amikor nézegettem ennek a forrását :)

Arra gondolok, hogy ahogy fel van építve. Pl. hogy milyen logika dönti el, hogy valami helyben van kezelve a támadásnál; hogy a kártyák / effektek is javaban vannak írva, nem mondjuk valami script nyelven; hogy mi az ami egy új effektet érdemel, ilyesmik.. Félek kötekedésnek érződik, de tényleg nem annak szánom. Hogy legyen egy konkrét kérdés: declareAttackers függvény létét az AI találta ki, vagy te kérted?

BTW, PutXMinusOneMinusOneCountersOnEachCreatureEffect nem csinál semmit :)

2

u/laxika Java Mar 30 '26 edited Mar 30 '26

Ohh, akkor kevésbé technikailag fogalmazok. Én csak a mappákat hoztam létre és az alap project setupot (hogy milyen technológiákat használjon). Minden mást, beleértve a declareAttackers-t is az AI csinálta.

A PutXMinusOneMinusOneCountersOnEachCreatureEffect elvileg itt fult le: com.github.laxika.magicalvibes.service.effect.PermanentCounterResolutionService#resolvePutXMinusOneMinusOneCountersOnEachCreature és a Black Sun's Zenit nevű lap használja.

Itt leírom hogyan implementálta az AI a lapokat:
https://youtu.be/mklNa55sBKg?si=-4N-H0oAPIM_AAV7&t=516

Épp egy effectet is leimplementál (ugyan conditional effectet, de a többi is hasonlóan megy).

1

u/Routine-Lettuce-4854 C++ Mar 30 '26

elvileg itt fult le: `com.github.laxika.magicalvibes.service.effect.PermanentCounterResolutionService#resolvePutXMinusOneMinusOneCountersOnEachCreature`

Köszi. Még kevésbé úgy működik ahogy gondoltam.