[video output=day506 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Improving Camera Motion" vod_platform=youtube id=MDeoneIezno annotator=Miblo]
[0:00][Recap our new entity grouping functionality and set the stage for the day][:"entity system" :speech]
[1:59][Show off our orphan–cat groups][:"entity system" :run]
[3:02][Create a special camera-triggering entity region, introducing AddConversation() and GetCameraOffsetZForCloseup()][:camera :"entity system"]
[13:09][Toggle on the entity bounds :"debug visualisation" in UpdateAndRenderEntities()][:"entity system"]
[14:08][Check out our entity bounds :"debug visualisation"][:run]
[15:38][Make PlaceOrphan() position the orphan facing downwards][:"procedural generation"]
[16:19][Announce the upcoming Tau vs Pi rant][:mathematics :speech]
[17:02][Change PlaceOrphan() to add a conversation rather than a cat][:"procedural generation"]
[17:30][Find that the conversation boxes are misplaced][:"entity system" :"procedural generation" :run]
[17:48][Fix AddConversation() to correctly position the entity][:"entity system"]
[18:10][Find that the conversations are correctly positioned][:"entity system" :"procedural generation" :run]
[18:39][Recompile in debug mode]
[19:15][Step in to UpdateCameraForEntityMovement() to find that we never get to the special :camera case][:run]
[21:12][Make AddConversation() create a larger collision box][:"entity system"]
[21:41][Step in to UpdateCameraForEntityMovement() to find that we now trigger the special :camera case][:run]
[24:19][Make GetCameraOffsetZForCloseup() zoom in closer][:camera]
[25:05][Try out our conversation zoom][:camera :run]
[26:14][Make AddConversation() offset the :camera northwards][:"entity system"]
[26:44][Try out our offset conversation zoom][:camera :run]
[27:37][Plan to improve the :camera code: damping hopping motion; alpha clipping interpolation; reintroducing debug camera; computing :lighting for the entire visible area][:run]
[30:28][Harmonising the alpha clip and :camera movement interpolation][:research]
[34:11][Mathematically tie together the alpha clip and :camera position interpolation in UpdateCameraForEntityMovement()]
[43:41][Try out our newly harmonised :camera][:run]
[45:11][Fix UpdateCameraForEntityMovement() to use the target :camera position directly if it's close enough]
[47:40][Try out our harmonised :camera][:run]
[48:50][Try out smaller values for the AlphaMin and AlphaSpan][:camera :run]
[52:50][Reduce the AlphaMin and AlphaSpan in PlayWorld()][:camera]
[53:04][Plan to damp the :camera Z motion][:run]
[56:32][Only moving the :camera when the player has moved far enough, on each axis separately][:run]
[58:42][Augment game_camera with a MovementMask for UpdateCameraForEntityMovement() to modify the camera's position][:camera]
[1:00:20][See that our :camera is unexpectedly working][:run]
[1:00:48][Use the computed TotalDeltaP in UpdateCameraForEntityMovement()][:camera]
[1:03:19][See nothing, as expected][:camera :run]
[1:03:30][Use Camera->MovementMask in UpdateCameraForEntityMovement() to move the :camera above a threshold][:camera]
[1:06:35][Try out our :camera movement threshold][:run]
[1:07:08][Increase the :camera movement threshold in UpdateCameraForEntityMovement()]
[1:07:37][Try out our :camera movement threshold][:run]
[1:08:26][Investigate our threshold and :camera movement masking][:research]
[1:14:29][Add :camera data to the :"debug system"]
[1:16:31][Find that the :camera's Y values are already wrong at startup][:run]
[1:16:54][Print the TotalDeltaP after doing the Hadamard product with the MovementMask][:camera :"debug system"]
[1:18:55][Traverse the orphanage, watching the :camera data printout][:run]
[1:22:20][Interpolate the :camera when the target position is below 0.01f in UpdateCameraForEntityMovement()]
[1:23:21][Find that the :camera position interpolates forever][:run]
[1:25:57][Fix UpdateCameraForEntityMovement() to only interpolate the :camera when the target position is above 0.01f]
[1:26:36][Find that the :camera interpolation is discontinuous][:run]
[1:26:44][Increase that target distance threshold in UpdateCameraForEntityMovement()][:camera]
[1:27:30][Try out our stabilising :camera, still with slight wonkiness][:run]
[1:28:01][Remove that target threshold, and reduce the deceleration of our proportional derivative controller from 6 to 2][:camera]
[1:28:31][Try out our :camera to find it overshoots][:run]
[1:28:36][Increase the deceleration of our proportional derivative controller from 2 to 3][:camera]
[1:28:38][Traverse the orphanage to still find overshoot in the :camera, increasing the deceleration value to 5.5][:programming :run]
[1:31:05][Reduce that deceleration value to 5.25][:camera]
[1:31:19][Try out our :camera, and consider making the MovementMask signed][:run]
[1:33:14][Let the :camera smoothly change direction in UpdateCameraForEntityMovement()]
[1:35:48][Try out :camera direction changing][:run]
[1:36:13][Reduce the :camera speed threshold in UpdateCameraForEntityMovement()]
[1:36:22][Try out :camera direction changing][:run]
[1:37:09][Cold set the :camera's velocity when it is close enough to the target]
[1:37:24][Try out the :camera to find that the special camera gets positioned incorrectly][:run]
[1:37:55][Make the special :camera set the Camera->MovementMask to 1, 1, 1]
[1:38:23][Try out the special :camera][:run]
[1:39:50][Q&A][:speech]
[1:40:27][Make ExecuteBrainHero() position the glove with the hero][:"entity system"]
[1:42:49][Find that the glove stays with the hero][:"entity system" :run]
[1:44:25][@culdevu][Q: I'm still not sure I understand the reason why you don't store the "actual" position and smoothly scrolling between tiles, and the "animation" position doing the bouncing? The bouncing should only have to be dealt with during render and can be derived from the "actual" position, and so you don't have to store it anywhere. Am I wrong about that?][:camera]
[1:46:57][@davechat][Q: What was the plan for :lighting on the sprites?]
[1:47:53][@saidwho12][Q: Is the variance in :lighting just a side effect of the random sample?]
[1:48:17][@robotchocolatedino][Q: Off-topic but how do you stay motivated on long projects like this? I usually would lose interest much earlier, and am wondering if there are techniques to want to keep working for on the same game for many years[ref
    author="Jonathan Blow"
    title="Techniques for dealing with lack of motivation, malaise, depression"
    publisher="YouTube"
    url=https://www.youtube.com/watch?v=i7kh8pNRWOo]][:health]
[1:52:00][@saidwho12][Q: How big is [~hero Handmade Hero]?]
[1:53:36][@very_mediocre][Q: Do you ever get burnt out? What does it take for that? Have you noticed a change in your mental stamina as you've gotten older?][:health]
[1:55:54][@fishrock123][Q: How long does a full rebuild take?]
[1:56:50][@pythno][Q: Motivation: I can recommend your chat about the imposter syndrome.[ref
    site="Handmade Chat"
    page="Imposter Syndrome"
    url=https://guide.handmadehero.org/chat/chat012/]It helped me a lot. I used to have way too high expectations of what I can do in a day. I reduced that expectation and set myself smaller goals for each day. Way easier to even start then and I was surprised how quickly I got way more done than I initially wanted to do][:health]
[2:00:17][@xxthebigfoxx][Q: Do you ever experience having no idea on how to approach a specific problem and have that negatively impact how productive you are? Any tip on how to deal with it?]
[2:03:56][Roll it up for 2018][:speech]
[/video]
