Evennow, justlikewithMario, they'reproducingverywonderfulgames, I thinklastyear, BreathoftheWildtookallthe I forgetwhichceremonyitwasourawardsortofshow, butittooklikeeveryawardpossiblethislastyearofthelatestSellTheBreathoftheWild.
Sointhecontextoftoday's example, we'llseehowwecangoaboutimplementing a dungeonthatsortofyoucangothroughforeverandeverandhowtosortofmodelthatandmakeitlookasifyou'retravelingthrough a dungeonoverandoveragainandgoingthroughdifferentscreensindifferentroomsthatarealldifferent.
Itallowsyoutosortofdecoupleaspectsofyourgameengine a littlebitandmakesfor a littlebitmorereadablecodeandallowsyoutodosomeinterestingthingswith, like, achievements, forexample, whereyoudon't necessarilywanttopulleverysingleframe.
Oh, did I dothissortofarbitrarylistofthings?
ThisframeRather, youcanjustprocessallofthatwithanyeventandhave a listenerand a functionthat, youknow, everytimeyoubroadcastOh, pickupcoin.
Maybe I haveanachievement.
That's like, Oh, uh, how I pickedup 50 coinsinthislevel.
So a verycommonareverysortoficonicaspectoflegendofZeldaiswhenyou'regoingfromonescreentoeanother, thereis a sortoftransitionperiodasonescreenloadsandtheotherscreengoesawayinhardwareintheNTS.
But, uh, thiswassortoftheonlywayyoucouldactuallyrender a lotof, um, sortofmorethan a screenwithoftiles.
Buttodaywe'llseehowwecansortofcreatetheillusionofdoingthatbyjustdrawing a roomandthenhavingourmainroomandthenjustsortoftwinningoverandthensettingeverythingbacktotheoriginat 00 Anditmakesitlookasifwe'removing, youknow, backandforthbetweenalltheseroomswheninreality, allwe'redoingisjustdoing a shiftandthenputtingeverythingbackto 00 Soallsortofillustratethatonthescreen, if I can, Andonelastthingwilllookathisdatadrivendesigninthecontextofah, lotoftypesofgames, particularlyRPGsandactiongames.
Andjustlikeinpriorlecturespriortotoday, wejusthave a spreadsheetlikewedidwithMario, whereeverythingislaidoutin a fairlyevensequenceof, um, tilesegments.
Inthiscase, thesegmentsare 16 by 16 pixels.
Here I'veoverlatergrid, justtoshowthatthepictureisindeedperfectly 16 by 16.
Assetsmakeiteasytochopupintolittlepiecessoyoucananindexintothisspriteviasometablequads, Um, andthen a sign, an I D towhateverobjectortileyouwanttorenderedtothescreen.
Havethe, youknow, an X Y thatrepresentsthetopleftofthatobjectplacedintherightposition.
Andinsteadofdrawingjustonetile, wedrawfourtiles.
Andthen, insteadofhavingjustonecollision, boss, that's 16 by 16 tiles.
Youcando a couplethings.
Youcaneithercheckcollisiononallfourofthesetilesorallatleastalltwoofthesedoortilesormodelyourowncustomhitboxthatthenmaybethatobjectthatrepresents a doorwayhascontrolofsoyoucansay, youknow, doorwaycollidesplayer, andthenthedoorwayhas a heightandwidthofhowevermanypixels.
Itiswidebytallhere, justthisdoorpart, andthenyouknow, youareabletothenbuilduponnotjusthavingonetilethatmodels a anobjectorentityinyourgamespace.
Butnowyouhavemoreartisticflexibility.
Youcandothingslikehavedoorwaysthataremorethanonepixelwhiteandsortofhave a moreconvincinggameworldas a resultofthat.
Andyousee a lotofthingslikethatingameslikeRPGs, whereyouhavefullhousesthatareobviouslynotjustonetile.
Becausethatwouldbe I mean, something.
Youcanmodelthingsasonetileifyouwantto.
Butfromanartisticperspectiveandfromjust a gameengineperspective, it's a littlebiteasiertoprogrammaticallybeabletocutupallyourassetsintotilesanddrawthemassuch.
Theswordsmananimationisactuallystoredin a 32 by 32 pixelframebecausesometimes, umdependingonwhichanglehe's lookingat, hisspreadcouldget a littlelargerorsmaller.
Sowhenyouhave a spritewithpadding, whatsortof a waythatwecandrawthistothescreen, um, reliably, like, howdoweHowdowetakethisintoconsideration?
Howwouldwerender a screen?
Ah, spreadwithpadding?
Solet's saythisrighthere.
Ourcharacterswinging a swordisin 32 by 32 pixelbox, right?
Allwereallyneedtodois a signthatspriteandoffsetjustsayOK, thespritesoffsetAccentoffset.
Whyaresomevaluethatbasicallyletsusdrawthespritetoe a negative X and a negative y valueAndthatwillshiftthespriteupsuspendedalignsperfectlywithwhereverhis x y r andweaken.
Youcantake a lookatthatinthecodetoseeexactlyhowthatworks.
Lastly, theactualentitiesforourgameworldaredifferentcreatures, andthisis a spreadsheet.
Thisis a moreidealspreadsheetwhereeverythingis 16 by 16 pixelswideandtall.
Andwecancreateanimationsverysimplybecauseofthis, um, as a sidenote, somethingthat I liketodowhen I'm, youknow, parsingorwhen I'm piecingapart a spreadsheetthat's got a lotofindividualframesparticularfromcreatinganimations, or I justneedtoknowitfor a tileparticulartiletodroptothescreen.
It's kindof a paintomanuallylookthrougheachandeverytileonebyoneandsay, OK, thisisone.
I wrote a simplepythonscriptthatwilljustgoover a fileandjustadd a digittoeachindividualquadtojustshowyouat a glancewhateachSpriteis.
Andthisisincludedinthedistricts.
Youcanseewhatitlookslike, saves a lotoftime, and I recommendtryingwhenyou're, youknow, sortofworkingwithassetsandyoufindyourselfdoingsomethingthattakes a longtimein a sortoftediousandmechanical.
Maybetry.
Trytofind a waytosortofautomatethat, oratleastmakeiteasiertodothingsat a glance.
Inthiscase, justsimplyimposing a numericalgridsolvesthatproblem.
I don't havetospend a significantamountoftimefiguringoutwhichframesofanimationtheghostfacingleftis.
I knowinstantlyit's 67 68 69 um, andallowsmetojustcrankthingsoutthatmuchfaster.
Sothefirstthingwe'lltake a lookatis, ah, sortoftopdownperspective.
Uh, andwemostlytalkedaboutthisbeforeearlier, butallitreallyisis a tilemap, whichwe'veseenbefore.
Sowhenyou'redesigning a topdowngamejustforconvincingthesakeofbeingmoreconvincing, tryandemulatethattheentitieshere, liketheskeletonandsuchare a littlebitmorestraightonthebatsandSlim's andwhatnot, eventhoughtheystillhave a littlebitofthatappearance.
Likethespider, itsortoflooksasifit's fromthetopback, butmodelingyourassetsfrom a topdownperspective.
Really, that's mademainlythething.
Payattentiontoshadowsandhighlights, whichadds a lotintermsofconvincingusthatwe'reinthisroomwithlightingAndalsomakesurethatyou'redoingthingslikecornersandstuffandmakingitlookasifthingsareslightlyskewed.
Soinwhat's thesortoflikethemainunitof a dungeon, atleastinthecontextofLegendofZelda?
Ifyouhadtoedistillwhatcomprises a dungeon, what's likethemostfundamentalunit?
Yes, a room.
Sowecanalmostlookatthisifwepictureitintermsof A to D array, right, wehaveassumingthatthisislikeindex 11 inlieu a 00 inotherlanguagesgoinglefttorighttoptobottom.
Thebossroomshouldhaveah, maybe a bossQiorsomethinglikethat.
ButthebossQishouldnotbeobviouslyinthatroom.
Itshouldbesomewhere.
Maybe, wherethere's, ah, a coupleofroomsbeforeitthathave a lockor a keysothatyouknow, there's somesortofchallengeinvolvedinyourdungeon.
It's notjustrandom.
Asasrandomaswe'vedonebefore.
Therehastobe a littlebitofsortofconsciousdesignonbehalfofyouralgorithms.
Todaywe'redoingthingscompletelyrandom.
Um, forillustrationisbecause a systemlikethisisfairlyrobustandcomplex, butwithsomeeffort, youcouldcreate a simpledungeongeneratorjustusingthosemechanics.
Justmakesurethatyouhavelockeddoors.
Thelockdoorscanonlyopenwhenyouhave a key.
Makesurethekeyexistsin a placethat's accessibleandsortofcreate a chainoflike, a sortoflike a controlflowmodel, maybevia a graphofsomekindthatrepresentsyourdungeonandtheprogressionthereof.
Sothat's that's whatZeldaDungeonlookslike.
That's what a to D dungeoninthissortofperspectivelookslike.
Butifyouhavejust a platformerlevel, maybeyouhave a regionsorzonesoranything, justlittlesubsegmentsofyourlevelthatyoucantransitionbetween.
Um, it's usefultothinkintermsofthat, becausefromanefficiencyandperformancestandpoint, youwant a dynamicallyprobablyloadcertainlevelsoneat a time.
Certainaspects.
Certaincomponents, subareasofyourlevel, oneat a timeratherthanjusttheentirelevelatwants.
Becausedependingonhowsufficientlycomplexandlargerlevelis, youcouldgettoah, youknow, exercisingyourcomputer's memoryconstraints, so I don't wanttodothat.
There's a doorgoingtothisfromdownbelowbutitdoesn't have a doorwayuptopin a doorontherightbecausetherearenoroomsgoingbetweenthatroomandthosedirections.
Sowhenyouhave a two D arrayofdungeonroomsandyouwanttomodelyourdoorways, itcouldbeassimpleasIsthere a roominthatdirection?
Ifthereis, andyouwillhaveyourdatastructuresortoflaidoutinadvancebeforeyougeneratethesedoorways, ifitdoes, ifitdoesnotexist, don't make a door.
Ifitdoesexist, make a doorandthenmakesurethatwhenyoutransitionbetween, thoughleftfrom, let's say, fromtherighttotheleftorfromthebottomtothetopthatyougotothecorrectroomsatthecorrectindicesinyourtwo D sortofroomarray.
Doesthatmakesense?
Anybodyhaveanyquestionssofarastolikehowthisworksat a highlevel?
WhatWhatdoweneedtodoifwe'reIfwe'regonnaputeverythingbackto, let's say, let's say I wanttomakethisthisroom, thenewcurrentroom.
Whatdo I needto d'oh?
Sowehavecurrentroomandwehavenextroom.
If I wantthecurrentroomtobecomethenextroom, All I needtodoissayselfdotcurrentroomequalsmyselfnextroom, right?
Andthenoncethathappens, JasonOfficer, whathappenstotheadjacentoffset X and Y Overthenextroom, theygetsettozero, right, I wanttotake I wanttotakethisroomthatwe'veoffsetuphereand I justwanttomakeitthecenterofthegameworldagain.
I wanttojustputitat 00 soyoucoulddothisexactsamecalculation.
Bye.
Justsettingadjacentoffset X or y two a negativeorpositivescreenHaiderscreenwithrelativeto 00 Sowhat I'm gonnadoisjustset, uh, theadjacentoffsetof X and y ofthenextroom, whichisnowcurrentroomtozero, andit's gonnadrawitrightbackat 00 andthencamera X andcameraWhyarealsogonnabesetto 00?
Solet's take a lookat a fewofthefunctionsthatcomprisethat.
Sogeneratewallsandfloors.
Thisisverysimple.
Verysimilartowhatwe'velookedatbeforewith, like, tilemapsandMario, forexample, wherewejustgofromWhite X andthenwejustpick a random I d ornotrandom I d Well, itisrandom.
I d forsomeofit.
Butsometimesweneedanexplicit I d.
So, uh, remindme, whatdoestheeye d actuallymaptoo?
Uh, whenwere, youknow, drawingtilestothescreenIfwewanttogive a Thailandidea.
Whatisthat?
Whatshouldthatmapto?
Yeah, theframeinthespreadsheet.
That's correct.
Um, itdoesn't havetoforallgameenginesforallimplementations, butit's theeasiestthingtodoisjusttogiveityourtile, and I d thatyoucanthenjustdrawyoucanindexintoyourspreadsheetatthat I d, umitisvery, verysimple.
Lightweight, cleanapproachtomodeling.
Andwecanseehere I d gets I d umafterwe'vesortoffiguredoutwhat I dowewantnowHowdowedetermine?
Like, let's say I wanttodraw.
Um, let's say, forexample, likethistileherenosense, it's a cornertile.
Howwould I Whatdo I needtodotoTobasically a sign I'm gonnadiebefore I evenhavethechanceto, uh, toshowyouwhile I avoidenemy's?
If I wantedtodrawthattopleftcorner.
Uh, what?
Um, I sortoflookingforarestilltakingdamageanyway, relativeto x Andwhy?
Whatam I lookingfor?
What x and y doesthat, Butisthattileneedassumingeverythingstarts 11 onthetopleftandgoesdownThioheightandwidthoftheoveralldungeon.
Whatisthe x y needtobeofthetopleftcorner?
Itneedstobeone, right?
Soifthat's 11 basicallythetopleftcornerthat i d shouldbeequaltothecorner.
Sprite, thetopleftcornerspritespecifically.
WhataboutthetoprightcornerSprite?
WhatshouldtheXBSorry?
Yes.
Withexactlywhat's thewhystillgonnabeone?
Whataboutthebottom?
Leftwithcommaheightandinthebottomrightorsorry.
Bottomleftshouldbeonecommaheight.
Bottomright.
Shouldbewithcomeonheight.
Andsobasicallycheckingthepositionofeachtileishowwecaninferits i d, whichiswhatwe'redoing.
Um, inthesourcecodehere, if X isoneandwiseone.
Okay, topleftcornerandthosethatwe'veputtheseendintoconstantsthatwe'veputin a constantstoppedLuisjustforreadability, sowecaninstantlyseeOkay, I shouldset I d totiletopleftcorner.
It's nottolike 15 or 20 lines, butwe'regenerating, youknow, a bunchofdifferentkindsofentities, becausewhatwe'vedone, wetakewaybasicallytake a randomtype.
Fromthattable, wecreateanentity, andthen, usingwhatwe'vedefinedin a globaltablecalledentitydeaths, wetakeoutwhatsortofmattersintermsofgeneratingeachindividualentity, thecharacteristicsthereof, andwejustputitinsimpledataform.
Simplethingsyoucouldgivethisyoucouldgiveanybodywhohassortofthebasicknowledgeofwhatwe'redoingthisfileandwhatmaybesometexturesandsay, Hey, I wantyoutodesign.
I wantyoutolayoutbasicallyallofthatthat's involvedinwhatmakes a skeletonsortofrentedtothescreenlikegivehim, like, createalltheanimationsforthem.
Maybemaybeskeletonshouldhavehealth, andmaybehealthshouldbeequalto 10 on a skeletonorsomethinglikethat.
There's notreallyanylikeprogramminggoingonhere, butwe'redescribingeverythinginourgameasdata, andthat's importantthingincomplexgamesthathave, youknow, fairlycomplexsystems, butthatcanbemodeledby a someattributes.
Youcanjustdescribeyourentitiesanddataandthenlayyourengine, parsethisinformationandthencreateyourentitiesprogrammaticallyYouallowyousortofshifttheburdenfromtheprogrammertothedesigner a littlebit, andyouaffordyourdesignteam.
Andyouhaveentitiesthatare, maybeyouwantthemsometosetonfire, sometobeelectrocuted, maybesomeyoudon't Maybesome, uh, meltwhentheytouchsomething, create a bunchofflags, create a functionthatparsesthisandgeneratesentitiesas a result.