[video output=day539 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Capturing Source Information for Memory Allocations" vod_platform=youtube id=WHjbH_5Cl0w annotator=Miblo]
[0:01][Recap our new world apron and the tiled nature of our game, and set the stage for the day][:speech]
[3:23][Demo our world apron, and set up to tackle our world solidity issues: :lighting and ground cover][:"procedural generation" :run]
[8:11][Transient vs persistent state in the context of :lighting entities and placing ground cover][:"entity system" :run]
[15:35][Plant trees in the apron, introducing AddTreeTags() for GenerateApron() to call][:"entity system" :"procedural generation"]
[21:18][See no trees in the apron][:"asset system" :"procedural generation" :run]
[21:31][Systematise entity generation for both traversable and non-traversable locations, introducing GenEntityAtP(), GenEntityAtTraversable() and AddInanimate()][:"entity system" :"procedural generation"]
[34:11][See our forest of trees in the apron][:"entity system" :"procedural generation" :run]
[34:23][Change GenerateApron() to plant a tree on one random tile out of three][:"entity system" :"procedural generation"]
[34:48][See our randomly distributed forest][:"entity system" :"procedural generation" :run]
[35:04][Prevent AddTreeTags() from picking DarkEnergy, Fall and Damaged trees][:"entity system" :"procedural generation"]
[36:01][Check out our less variable forest][:"entity system" :"procedural generation" :run]
[36:16][Consider preventing GenerateApron() from placing trees right next to rooms][:"entity system" :"procedural generation" :speech]
[37:34][Note our need to light the sprites, and to prevent trees from penetrating walls by placing them carefully][:lighting  :run]
[38:54][Make GenerateRoom() use our new AddTreeTags()][:"entity system" :"procedural generation"]
[39:36][Find that we're still generating all types of trees in our (non-apron) rooms][:"entity system" :"procedural generation" :run]
[40:11][Fix GenerateRoom() to pass the correct argument to AddTreeTags()][:"entity system" :"procedural generation"]
[40:39][Check out our winter trees, and see one tree in each room placed underground][:"entity system" :"procedural generation" :run]
[43:16][Try preventing GenerateApron() from placing trees][:"entity system" :"procedural generation"]
[44:00][See our sunken trees][:"entity system" :"procedural generation" :run]
[44:07][Try preventing GenerateRoom() from placing trees][:"entity system" :"procedural generation"]
[44:48][Still see our sunken trees][:"entity system" :"procedural generation" :run]
[45:07][Try preventing GenerateRoom() from placing lamps][:"entity system" :"procedural generation"]
[45:24][See no sunken trees, but still an errant entity in one room][:"entity system" :"procedural generation" :run]
[45:42][Try preventing GenerateRoom() from adding tags to pending entities][:"entity system" :"procedural generation"]
[46:05][Find that our sunken entity has disappeared][:"entity system" :"procedural generation" :run]
[46:42][Fix GenEntityAtTraversable() to only call Creator() once, and let everyone place their entities again][:"entity system" :"procedural generation"]
[47:24][Find that we have fixed our errant entity placement][:"entity system" :"procedural generation" :run]
[47:43][:Caching ground cover in addition to lighting][:speech]
[49:56][Begin to cache ground cover, augmenting the entity struct with a newly introduced ground_cover][:caching]
[54:32][Gauge the :performance of copying our larger entity][:caching :run]
[57:19][Consider adding finer grained :memory usage information to the :"debug system"][:speech]
[59:58][Illustrate where :memory statistics may reside][:"debug system" :run]
[1:01:29][Reacquaint ourselves with the :"debug system"][:research]
[1:04:02][Add a debug UI hud for the :memory data block][:"debug system"]
[1:04:17][Check out our sketched out :memory viewer][:"debug system" :run]
[1:04:41][Add the AssetArena to our :memory data block][:"debug system"]
[1:07:49][Consider adding "total space" to our :memory viewer][:"debug system" :run]
[1:08:14][Toggle on DrawArenaOccupancy() and reacquaint ourselves with it][:"debug system" :memory]
[1:13:11][Criticise the overly generic nature of our :"debug system"][:speech]
[1:14:38][Add to the :"debug system" purpose-built support for :memory tracking, including HANDMADE_INTERNAL versions of our Push*() functions]
[1:36:16][Find that we've broken nothing][:"debug system" :memory :run]
[1:36:22][Toggle off HANDMADE_INTERNAL and fix compile errors][:"debug system" :memory]
[1:37:48][Crash ~4coder upon writing "#endif HANDMADE_INTERNAL" in handmade_import.cpp][:admin]
[1:38:09][Continue to fix compile errors][:"debug system" :memory]
[1:39:20][Crash on the call to GetFontInfo() in InitializeUI()][:"debug system" :memory :run]
[1:41:00][Investigate the assertion hit in GetFontInfo()][:research]
[1:49:41][Step through AllocateGameAssets() in HANDMADE_INTERNAL][:"asset system" :memory :run]
[1:53:12][Step through AllocateGameAssets() in not HANDMADE_INTERNAL, to see that we do not load all the asset files][:"asset system" :memory :run]
[1:57:10][Fix AllocateGameAssets() to loop over all our allocated asset files][:memory :owl :programming]
[1:58:09][Find that the non-internal build now works][:"asset system" :memory :owl :run]
[1:59:37][Q&A][:speech]
[2:01:02][@Brian][Q: Why do you delete the pdb's before each build? Have you found the compiler having issues or leaving junk if you just let the compiler deal with it?]
[2:03:53][@macielda][Q: In that system, do you have to transform all Push*() functions into macros?][:language]
[2:04:10][@lucid_frost][Q: What are some better alternatives to things like #ifdef's that a :language could provide?]
[2:04:34][@macielda][Q: So all functions that allocate any memory need to become macros if you want to keep track of where the memory was allocated?][:language]
[2:04:44][@ivereadthesequel][Q: How much more stable has ~remedybg gotten since you started using it on stream? Were there any particularly big issues that caused you trouble that have been fixed in that time?]
[2:05:22][@victorn][Q: Do you think using tests would have made it easier to find the code paths that were broken with this refactor?]
[2:06:36][@macielda][Q: Is that why you put all Push*() functions in the same file?][:language]
[2:07:06][@Brian][Q: If you didn't do code-reloading, like say for release, would you still have the platform exe, and a separate dll for the game code?][:"hot reloading"]
[2:08:55][@uplinkcoder][Q: The caller location is a many-to-one mapping which is why languages generally don't do it. You could, but it means complications for the runtime / code-generation][:language]
[2:10:43][We're done with questions][:speech]
[/video]
