[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Multithreaded World Simulation" vod_platform=youtube id=tWzslFE9Qvg annotator=Miblo] [0:35][On two-hour blocks enabling a more continuous workflow] [1:43][Run the game and set the stage for the day] [2:48][handmade_world_mode.cpp: Consider reworking UpdateAndRenderSimRegion() for state visibility minimisation] [7:54][Run the game and consider how we want UpdateAndRenderSimRegion() to operate differently in the debug and the regular view] [11:32][On when and why to pass in a superset of arguments to a function] [14:56][handmade_world_mode.cpp: Introduce CheckForJoiningPlayers() to contain the player joining code from UpdateAndRenderSimRegion()] [18:06][handmade_world_mode.cpp: Consider how to split up UpdateAndRenderSimRegion()] [21:45][handmade_world_mode.cpp: Break out UpdateAndRenderSimRegion() functionality into UpdateAndRenderWorld()] [23:31][handmade_sim_region.cpp: Consider how the simulation and the packing sides are two different functions] [24:47][handmade_sim_region.cpp: Rename BeginSim() to BeginWorldChange() and EndSim() to EndWorldChange()] [25:50][handmade_world_mode.cpp: Introduce new, higher level BeginSim() and EndSim() functions, and Simulate()] [32:57][handmade_world_mode.cpp: Make UpdateAndRenderWorld() call our new functions] [37:52][Run the game to see that we're still getting the same results] [38:26][Consider reworking the passing of input to ExecuteBrain() and Simulate()] [41:48][handmade_entity.cpp: Introduce DEBUGPickEntity()] [50:04][handmade_debug_interface.h: Add MouseP to the debug_table struct and introduce SET_DEBUG_MOUSE_P() and GET_DEBUG_MOUSE_P()] [53:44][Run the game to see that's all good now too] [54:13][Q&A] [55:03][@asafgartner][Can you try compiling with debug off?] [55:41][handmade_world_mode.cpp: Enable DEBUGPickEntity() and DEBUG_PLATFORM_GET_MEMORY_STATS() to be compiled out] [57:39][@badflydog][CTime stats. I know I know. It's irrelevant for the code] [58:31][Run CTime] [59:48][@chaoscom][What does the "..." do in the define?] [1:00:06][handmade.cpp: Demo varargs] [1:09:26][@flirtychair][How about documentation? I see you don't have too much comments in your code] [1:12:45][@tomisqi][I sometimes receive comments from colleagues during code reviews that I should put long pieces of code into functions for "cleanliness". What parameters go into your thought process when deciding if a piece of code should be placed under a function? How do you make the decision?] [1:18:16][@lvias][How much code is debug code vs real code?] [1:20:15][@uplinkcoder][Expand the files and take the diffs?] [1:21:14][Restart, recap the first block of work and set the stage for the second block] [1:23:14][handmade_world_mode.cpp: Delineate the primary and non-primary region simulation routines in UpdateAndRenderWorld() and consider how to thread them] [1:25:15][Run the game and consult the profiler to see the expense of GetClosestTraversable()] [1:27:34][handmade_render.cpp: Recap how RenderCommandsToBitmap() creates work orders to distribute to our threads] [1:30:13][handmade_world_mode.cpp: Introduce DoWorldSim() in order to thread the simulation] [1:32:32][Note the fact that the arenas are not multithreaded constructs] [1:33:53][handmade_world_mode.cpp: Make BeginSim() take a TempArena that we pass in, to enable it to be multithreaded] [1:36:23][Consider reworking memory allocaton in terms of multithreading] [1:40:47][Blackboard: Memory and Multiple Threads] [1:46:33][handmade_world_mode.cpp: Make DoWorldSim() allocate memory that exists only for the lifetime of the work] [1:50:31][handmade_world_mode.cpp: Enable UpdateAndRenderWorld() to create world_sim_work orders] [1:56:06][Run the game and consult the profiler to see a lot of debug events being generated] [1:57:32][handmade_world_mode.cpp: Toggle UpdateAndRenderWorld() to take the multithreaded path, :run the game and consider why it doesn't work] [2:00:21][handmade_world_mode.cpp: Consider why Simulate(), ExecuteBrain() and UpdateAndRenderEntities() take the WorldMode] [2:02:46][handmade_world_mode.cpp: Remove AddCollisionRule() and ClearCollisionRulesFor(), and prevent functions from unnecessarily taking the WorldMode] [2:07:13][handmade_world_mode.cpp: Make Simulate() take a particle_cache] [2:08:44][handmade_brain.cpp: Make ExecuteBrain() take a random_series Entropy] [2:09:53][handmade_entity.cpp: Make UpdateAndRenderEntities() take the TypicalFloorHeight directly for now] [2:11:46][handmade_sim_region.cpp: Prevent BeginWorldChange() and EndWorldChange() from taking WorldMode, and consider how better to deal with the camera] [2:15:03][handmade_world_mode.cpp: Make DoWorldSim() lock a mutex around BeginSim() and EndSim()] [2:18:21][Run the game on the multithreaded path, and investigate why the World is null] [2:18:38]["The world is null... the world is null!"][quote 534] [2:19:52][handmade_world_mode.cpp: Make DoWorldSim() call Platform.CompleteAllWork(), run the game and consult the profiler] [2:21:56][Consider how to improve this multithreading of the simulation, with a few words on functional programming] [2:23:42][todo.txt: Update the TODO list] [2:24:42][Q&A] [2:25:15][@Kknewkles][(vicariously asked via @Miblo) o7 Casey! Two questions: 1) Have you finished Sausage Roll? I have! >:D 2) I have been Shilling Knight for you to play Shovel Knight, and now I have to add Undertale to the list. That game a gift from gods on high] [2:26:17][@a_pulsing_mage][Isn't simulating the world in several threads, can't that make the game non deterministic? Isn't the point of the RNG having a starting kernel for deterministic play for competition and stuff?] [2:29:14][Blackboard: RNG in Handmade Hero] [2:32:32][@thegeekpirate][When do you go back and complete "TODO" tasks you've given yourself in the code? Is each one going to be completed before you're done, or are they simply wishlists?] [2:33:14][@sumsar10171][Is it important for a game programmer to have a portfolio in the same way artists do and, if so, what would be important to include?[ref site="Molly Rocket" page="HandmadeCon 2015 - Mike Acton" url="https://mollyrocket.com/news_0035.html"]] [2:34:53][@garryjohanson][In a tight inner loop do you think these memory copies for the temporary scratch memory could become an overhead concern? If I understood the stream correctly, that is] [2:35:31][@longboolean][Currently what is the behavior when walking several rooms over, into another chunk?] [2:36:13][@williambundy][Save scumming?] [2:36:21][@jim0_o][Will there be streams from the job fair people?] [2:36:48][@marcramhim][What's the relation between IQ and success at programming?] [2:37:20][@ginger_bill][Off-topic question which can be answered later if necessary. I've been developing a new programming language to replace my needs for C/C++ and pretty much every other language. The main areas of research for me at the moment are: Metaprogramming, SSA optimizations, Concurrency. You being a metaprogramming "expert", other than Compile Time Execution (CTE) that is Jon's language, what other forms of metaprogramming would you like?] [2:37:50][@williambundy][Sorry, it was in context: if I open a chest, and don't get what I want, reloading a save game and playing slightly differently might get me a different RNG for the chest] [2:40:36][@ginger_bill][Will the game have different "levels" like the Binding of Isaac, or will the entire game be a single "level"?] [2:42:13][Wind it down] [/video]