[video output=day537 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Filling Areas Around Rooms" vod_platform=youtube id=FJBoPGFRhY8 annotator=Miblo]
[0:01][Set up to start something new: tag system clean-up, ground cover, :lighting and world fill generation][:"asset system" :"procedural generation" :rendering :speech]
[3:02][Demonstrate the need to surround the world with an apron of non-dead space][:"procedural generation" :run]
[8:36][Reacquaint ourselves with the world generation code][:"procedural generation" :research]
[11:42][Introduce gen_apron and gen_apron_spec structs, for the world_generator to contain][:"procedural generation"]
[14:47][Reacquaint ourselves with the GenRoom() function][:"procedural generation" :research]
[17:13][Introduce GenApron() based on GenRoom(), for GenerateRoom() to call][:"procedural generation"]
[18:31][Consider associating aprons with rooms][:"procedural generation" :research]
[20:32][Augment get_room_spec with a gen_apron_spec, for GenerateRoom() to set][:"procedural generation"]
[24:57][:Run the game with no adverse effects][:"procedural generation"]
[25:15][Introduce GenerateApron() loosely based on GenerateRoom()][:"procedural generation"]
[28:47][Determine to perform a spacial query of entities, to prevent GenerateApron() from clashing with existing entities][:research :searching]
[31:10][Set up GenerateApron() to generate a piece of apron where OverlappingEntitiesExist() returns false][:collision :"procedural generation" :searching]
[44:25][Implement OverlappingEntitiesExist()][:collision :searching]
[48:11][Consider removing all the world_position nonsense][:"procedural generation" :research]
[50:15][Finish implementing GenerateApron(), and make CreateOrphanage() initialise an ApronSpec, introducing GenApronSpec()][:"procedural generation"]
[54:38][Check out our world's above-ground apron, to find that it is being over-generated][:"procedural generation" :run]
[57:13][Make GenerateApron() set collision volumes to facilitate the prevention of collisions][:collision :"procedural generation"]
[59:39][Find that the apron is being less over-generated, but that we are not seeing its :collision volume outlines][:"debug visualisation" :"procedural generation" :run]
[1:01:46][Temporarily toggle of PushCube() in UpdateAndRenderEntities()][:rendering]
[1:02:12][Check out our apron's collision volumes][:"debug visualisation" :run]
[1:02:50][Enable GenerateApron() to expand the Z-depth of its query regions, relative to the :collision volumes][:searching]
[1:03:51][Find that our expanded query region failed to prevent over-generation][:collision :"procedural generation" :run :searching]
[1:04:26][Toggle on PushCube() in UpdateAndRenderEntities()][:collision :"procedural generation" :searching :programming :run]
[1:05:10][Temporarily make GenerateApron() use the expanded QueryRegion as the CollisionVolume][:collision :"procedural generation"]
[1:05:22][Find that our expanded collision volume seems to prevent over-generation][:collision :"procedural generation" :run :searching]
[1:06:32][Let GenerateApron() set the CollisionVolume as normal and expand the QueryRegion's Z-depth in both directions][:collision :"procedural generation"]
[1:07:44][Find that the apron is no longer being over-generated, but that we are colliding with the room volumes][:collision :"procedural generation" :run]
[1:10:26][Prevent OverlappingEntitiesExist() from considering the room volumes, introducing IsRoom()][:collision :searching]
[1:11:54][Find that GenerateApron() is now generating pieces within rooms][:collision :"procedural generation" :run]
[1:12:38][Let OverlappingEntitiesExist() consider the room volumes][:collision :searching]
[1:13:15][Hit and investigate the VI == BaseIndex assertion in PushQuad()][:memory :run]
[1:15:33][Step in to PushQuad() in a debug build][:memory :run]
[1:16:53][Fix PushVolumeOutline() to reserve enough space for the twelve line segments][:memory]
[1:17:14][Find that we no longer hit that assertion][:memory :run]
[1:17:44][Make GenerateApron() produce a flat, i.e. non-varying, apron][:collision :"procedural generation"]
[1:18:49][Find that our apron resides just below floor level, where it should have collided with the floor][:collision :"procedural generation" :run]
[1:19:24][Try to make GenerateApron() elevate the apron pieces upwards by half the wall height][:collision :"procedural generation"]
[1:20:06][Find that our apron still resides below floor level][:collision :"procedural generation" :run]
[1:20:25][Investigate our room-relative placement of the apron][:collision :"procedural generation" :research]
[1:22:47][Determine to respecify Z == 0 as the lowermost part of the room volume][:geometry :run]
[1:24:01][Make GenerateRoom() set the MinRoomP.Z to 0][:geometry]
[1:24:45][Find that the world still seems to be generated plausibly][:geometry :"procedural generation" :run]
[1:25:39][Change GenerateRoom() to position the rooms' min corner at 0, 0, 0][:geometry :"procedural generation"]
[1:34:59][Find that the walls remain centred][:geometry :"procedural generation" :run]
[1:35:23][Replace the MinRoomWP and MaxRoomWP in GenerateRoom()][:geometry :"procedural generation"]
[1:37:26][Find that all is fine][:geometry :"procedural generation" :run]
[1:37:32][Make GenerateRoom() factor in the -HalfTileDim to the ChangeBaseP][:geometry :"procedural generation"]
[1:38:00][Find that our rooms are tightly bounded][:geometry :"procedural generation" :run]
[1:38:09][Simplify the positioning of entities in GenerateRoom(), removing and replacing all calls to PlaceEntity()][:"entity system" :geometry :"procedural generation"]
[1:46:06][Find that we have reintroduced the half-tile offset for the walls][:geometry :"procedural generation" :run]
[1:46:45][Change GenerateRoom() to offset the room boundaries, and not the entities, by the HalfTileDim][:"entity system" :geometry :"procedural generation"]
[1:51:01][Find that our rooms and entities are positioned as desired][:geometry :"procedural generation" :run]
[1:51:11][Further simplify GenerateRoom(), removing variables and introducing GetTotalVolume() for it to call][:geometry :"procedural generation"]
[1:56:58][Find that we are still okay][:geometry :"procedural generation" :run]
[1:57:18][Simplify GenerateRoom() further still, introducing a version of ChunkPositionFromTilePosition() that takes a gen_v3][:geometry :"procedural generation"]
[2:00:29][Traverse the world with the determination to continue with the apron tomorrow][:geometry :"procedural generation" :run]
[2:01:40][Q&A][:speech]
[2:02:04][@vapenir][Q: Why have a separate "apron" concept instead of just generating "rooms" on the sides?]
[2:03:58][@longboolean][Q: Will aprons be underground and ground level only, or will you also have sky aprons for upper levels like in the case of a tall tower? You could have clouds, or birds or something. Might look neat with multiple layers, thicker clouds as you climb, etc.]
[2:04:51][@xdunex][Q: How to link a third party library like glfw3.lib, any suggestions on where to read about it?[ref
    site="Handmade Hero"
    page="Episode Guide"
    url=https://handmadehero.org/watch#EpisodeGuide]]
[2:07:03][@roam00010011][Q: Environment is very sterile because all placed static entities seem to be snapped to grid. Maybe vary the offset randomly from the tile center? Also the random height difference between floor tile could be severely reduced (who made that flooring, it's a hazard)][:"procedural generation"]
[2:07:54][@centhusiast][Q: Will you also replace XCount with Dim.x in the GenerateApron() function as you did with Tilecount.x and y?]
[2:08:22][@vapenir][Q: Have you ever used Sony's (SN Systems) debugger for PS3? Someone on Handmade Network called it the best debugger they'd ever used, but didn't really go into detail about what it did right]
[2:09:47][@centhusiast][Q: Have you had any unpleasant experience with the debugging on Linux?]
[2:10:03][@xdunex][Q: Was the old Dune 2 game made using GDI or OpenGL?[ref
    site=YouTube
    page="PC Longplay [086] Dune II: The Building of a Dynasty (Part 1/2)"
    url=https://www.youtube.com/watch?v=EiJLOjeyDxs][ref
        site=Wikipedia
        page="Mode 13h"
        url=https://en.wikipedia.org/wiki/Mode_13h][ref
            site="The Atrevida PC Game Programming Tutorials"
            page="Introduction to VGA Graphics Programming Using Mode 13h"
            url=http://www.atrevida.comprenica.com/atrtut07.html][ref
                site="256-Color VGA Programming in C"
                page="Double Buffering, Page Flipping, & Unchained Mode"
                url=http://www.brackeen.com/vga/unchain.html]][:api]
[2:17:45][Peruse the code for FLIER.CPP and PARTICLE.C from the Bonus Pack, drilling down into double buffering in DOS Mode 13h from XMAIN.ASM[ref
    site="Metropoli BBS files"
    page="/unpacked/software/programm/asm/gvectors.zip/"
    url=http://ftp.mpoli.fi/unpacked/software/programm/asm/gvectors.zip/][ref
        site=x2ftp.oulu.fi
        page="/pub/msdos/programming/xlib"
        url=http://ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/xlib/00index.html]][:api :research]
[2:29:36][@abarishu][Q: You are surprisingly correct on those DOS VGA programming topics. "Vanilla" mode 13h was not double buffered][:api]
[2:30:12][Wrap it up][:speech]
[/video]
