[video output=day502 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Adding Stairs to the Generator" vod_platform=youtube id=tJlhy8qUgEk annotator=Miblo]
[0:00][Recap and set the stage for the day][:speech]
[0:55][Set up to continue working on the :camera, scrolling and zooming][:run]
[3:45][:Camera: Scrolling in large rooms][:speech]
[7:15][Enable GetCameraOffsetZForDim() to follow the player in large rooms (17×13 tiles and up)][:camera]
[9:06][Try out our scrolling :camera][:run]
[10:02][Treat X and Y separately in UpdateCameraForEntityMovement() to make the :camera scroll in long, thin corridors][:camera]
[11:26][Gauge the width of our first corridor][:camera :run]
[11:45][Adjust the :camera distances in GetCameraOffsetZForDim()]
[13:35][Try out our freely scrolling and room-focused :camera][:run]
[15:00][Adjust the :camera distances in GetCameraOffsetZForDim()]
[15:35][Try out our freely scrolling and room-focused :camera][:run]
[15:55][Prevent CreateOrphanage() from sticking a person in the main room][:"procedural generation"]
[16:18][Traverse the orphanage into the large main room and out to the forest][:camera :run]
[20:06][Reduce the ray count to 1 in ComputeLightPropagation()][:lighting]
[20:22][Traverse the orphanage discotheque][:lighting :run]
[20:46][Increase the ray count to 8 in ComputeLightPropagation()][:lighting]
[20:50][Traverse the orphanage, noting that we'll need a further-reaching :lighting solution][:run]
[21:31][World generation: Stairwells][:"procedural generation" :speech]
[24:54][Allow GenerateRoom() to colour-code our entities][:"debug visualisation" :"procedural generation"]
[25:18][Check out our room connections and stairwell locations][:"debug visualisation" :"procedural generation" :run]
[26:50][Make PlaceRoomAlongEdge() expand the area of stairwells, introducing AddRadiusTo()][:mathematics :"procedural generation"]
[31:36][Check out our expanded stairwell][:"debug visualisation" :"procedural generation" :run]
[32:37][Articulating the direction of stairwells][:"procedural generation" :research]
[35:50][Augment gen_room_connection with PlacedDirection for PlaceRoom() to set, introducing GetOtherSide()][:"procedural generation"]
[40:26][Introduce GetRoomConnectionTo()][:"procedural generation"]
[47:44][Set up GenerateRoom() to handle stairwells][:"procedural generation"]
[48:40][Traverse the orphanage to see that our stairwell generation didn't work][:"procedural generation" :run]
[49:12][Add Save / Load Startup Location buttons to our :UI, introducing CameraEditor()][:camera :ui]
[53:38][Reorganise the asset editor :UI][:"asset system" :camera]
[57:10][Check out our :camera :UI][:run]
[57:56][Scan through our stairwell generation code][:"procedural generation" :research]
[59:25][Step in to PlaceRoomAlongEdge() in the stairwell placement cases][:"procedural generation" :run]
[1:01:35][Move the stairwell connection code from PlaceRoom() to PlaceRoomAlongEdge()][:"procedural generation"]
[1:04:38][Investigate the Intersect() call in PlaceRoomAlongEdge()][:geometry :research]
[1:07:15][Make PlaceRoomAlongEdge() generate room connections][:"procedural generation"]
[1:09:26][Traverse the world to our successfully generated stairwell hole][:"procedural generation" :run]
[1:10:10][Make GenerateRoom() create traversable stairs in their stairwells][:"procedural generation"]
[1:20:19][Try out our new stairwell][:"procedural generation" :run]
[1:20:46][Adjust our stairwell in GenerateRoom()][:"procedural generation"]
[1:22:17][Try out our new stairwell][:"procedural generation" :run]
[1:22:58][Make GenerateRoom() compute the depth of the stairs based on the tile depth][:"procedural generation"]
[1:23:54][Step in to GenerateRoom() to see what's going on with the stairs][:"procedural generation" :run]
[1:25:15][Check out our deeper stairwell in-game][:"procedural generation" :run]
[1:26:23][Investigate our inability to traverse deep stairs][:movement :research]
[1:29:14][Allow GetClosestTraversable() to pick locations further below us][:movement]
[1:31:12][Try to get a handle on our stairwell traversal][:movement :run]
[1:32:11][Toggle on the traversable :"debug visualisation" in UpdateAndRenderEntities()][:movement :programming :run]
[1:33:41][Make GetClosestTraversable() consider traversable tiles 0.5f below and above us][:movement]
[1:35:14][Make CreateWorld() place the hero at the forest entrance][:"procedural generation"]
[1:36:30][Try to launch the game with the hero placed at the forest entrance, and crash in GetHashFromID()][:"procedural generation" :run]
[1:40:13][Add a ClippedZ traversable_search_flag for CheckForJoiningPlayer() to pass to GetClosestTraversable()][:"procedural generation"]
[1:41:32][Find that we now start at the forest entrance][:"procedural generation" :run]
[1:41:42][Make ExecuteBrainHero() pass TraversableSearch_ClippedZ to GetClosestTraversable()][:movement]
[1:42:11][Find that we still cannot hop down the stairs][:movement :run]
[1:42:30][Increase the Z search area of GetClosestTraversable()][:movement]
[1:42:53][Try to perform looped live code editing to debug our stairwell traversal][:"input recording" :movement :run]
[1:44:00][Set the FrameArena to PlatformMemory_NotRestored to fix looped live code editing][:"input recording" :memory]
[1:45:52][Try looped live code editing][:"input recording" :run]
[1:46:13][Change the FrameArena to be cleared rather than ended][:memory :"input recording"]
[1:47:36][Try looped live code editing and crash when clearing the FrameArena][:"input recording" :memory :run]
[1:47:56][Refrain from setting FrameArena to PlatformMemory_NotRestored][:"input recording" :memory]
[1:48:23][Try looped live code editing and again crash when clearing the FrameArena][:"input recording" :memory :run]
[1:50:39][Investigate our looped live code editing bug][:"input recording" :memory :research]
[1:59:05][Make Win32AllocateMemory() and Win32DeallocateMemory() respect the PlatformMemory_NotRestored flag][:"input recording" :memory]
[2:00:49][Find that looped live code editing works, but that we are leaking :memory][:"input recording" :run]
[2:01:51][Change the FrameArena to be allocated separately][:"input recording" :memory]
[2:10:06][Find that looped live code editing works without leaking :memory][:"input recording" :run]
[2:10:56][Record a loop trying to traverse the stairs, and break into GetClosestTraversable()][:"input recording" :movement :run]
[2:19:03][Consider simplifying the problem][:movement :speech]
[2:19:43][Try adjusting the stair depth in GenerateRoom()][:movement :programming :run]
[2:21:56][Find that a stair height of 0.75f combined with our Z randomisation can prevent us from traversing them][:movement :programming :run]
[2:23:07][Find out what TileDim.z gets set to][:movement :"procedural generation" :research]
[2:26:39][Make GenerateRoom() and GetClosestTraversable() handle stairs with our understanding of the typical floor height][:movement :"procedural generation"]
[2:27:10][Traverse down our stairs successfully][:movement :"procedural generation" :run]
[2:27:38][Increase the NearClipPlane in UpdateAndRenderWorld()][:camera :programming :run]
[2:30:55][Change UpdateAndRenderWorld() to set the Fog and AlphaClip based on the world Z][:camera]
[2:31:43][Check out our fogging and alpha clipping][:camera :run]
[2:33:25][Adjust the :camera in GetCameraOffsetZForDim()]
[2:34:18][Try out our adjusted :camera][:run]
[2:34:47][Adjust the AlphaClip in UpdateAndRenderWorld() and toggle off the traversable points :"debug visualisation"][:camera]
[2:35:55][Consider that to be pretty good][:camera :run]
[2:36:53][Q&A][:speech]
[2:37:25][Disable the moonlight in ComputeLightPropagation()][:lighting]
[2:37:38][Traverse the orphanage without the moonlight][:lighting :run]
[2:38:17][@pa1les][Q: Hey [@cmuratori Casey], I'm trying to load the "Complete set of V0 HHAs" data set with the latest GitHub [~hero Handmade Hero] code, but it doesn't work. It runs in an access violation in Assets->Tags\[AssetTagIndex\].ID == Tag_BasicCategory. What I'm doing wrong?][:"asset system"]
[2:39:23][@kaervin][Q: What's the status on the RAD debugger?]
[2:39:34][@hexd0t][Q: The head just clipped into the wall, if I saw correctly. Do you plan on doing Z-buffer tricks to keep sprites from being hidden by 3D geometry?][:rendering]
[2:40:22][Temporarily make PushSprite() apply some Z-bias][:rendering]
[2:40:34][Show our Z-bias situation in-game][:rendering :run]
[2:41:38][Crash in BeginWorldChange()][:run]
[2:42:03][Increase the size of our entity_hash array][:hashing]
[2:42:54][@pythno][Q: Can you explain the difference between HeapAlloc[ref
    site="Windows Dev Center"
    page="HeapAlloc function"
    url=https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapalloc] and VirtualAlloc[ref
        site="Windows Dev Center"
        page="VirtualAlloc function"
        url=https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx] and for what scenario they are appropriate?][:memory]
[2:46:26][@messatsugoshoryuu][Q: What kind of allocation do you use for assets (stack, heap, etc)?][:"asset system" :memory]
[2:47:00][@0lpbm][Q: What does the "OnLamp" variable represent?][:lighting]
[2:47:20][Temporarily enable the corner lamps][:lighting :programming :run]
[2:48:29][Close it down][:speech]
[/video]
