64 posts
How exactly does player state get parsed?

I'm reading all the Brain structs/funcs. Please tell me if I'm understanding this right.

ExecuteBrainHero() will filter controller input, then it will do a lot of 3D calc with entities in the vicinity (sim region) to see if there has been a hit etc.

What is confusing me here is where [what is the?] the state of the hero is stored exactly. The controller input could have been null from previous loop? And yet if(Head && Body) do stuff, but isn't this always true? Also there seems to not have been any use for the dt in the signature of the function. Is that supposed to filter controller raw input repetition? Or is that for time step in collision somehow?

In layman terms, how is the "jump -- > not jumping" sort of logics going on (if any)?

cheers

Mārtiņš Možeiko
2357 posts / 2 projects
How exactly does player state get parsed?

When you say "controller input could have been null" you actually mean input values are 0 because nothing is pressed/moved on controller? Because pointer will never be NULL there - game always passes controller structure to ExecuteBrainHero(). But if user does not press any buttons and not move analog sticks, the input values will be 0, and that is perfectly fine - code won't do any movement/action if not needed. They way calculations are written they take analog stick value as "amount to move per time unit". If amount is 0 then it won't move. Just like when speed of car is 0, the car does not move.

Some of hero state is stored in GameState->ControlledHeroes array - one per each controller. You can find definition of this array in game_state structure inside handmade.h header. And some of hero state is stored in brain / brain_hero structures from handmade_brain.h header - that deals with entities.

if(Head && Body) check is just sanity check if entities are actually loaded. It may be that this code is not needed anymore? Or maybe it is planned that hero can lose body in some action/event? Not sure, I don't remember exactly why. But both of those - Head & Body are always created added in AddPlayer function that is called from CheckForJoiningPlayers.

Hopping logic happens inside if(HopRequested) statement. You can see there logic determining where it wants to go and sets MovementMode on Body. This movement mode is executed as part of generic entity code - doesn't matter hero or enemy or otherwise. Look in UpdateAndRenderEntities function from handmade_entity.cpp file.

64 posts
How exactly does player state get parsed?

When you say "controller input could have been null" you actually mean input values are 0 because nothing is pressed/moved on controller?

Yes, misused jargon :)

Some of hero state is stored in GameState->ControlledHeroes array - one per each controller. You can find definition of this array in game_state structure inside handmade.h header.

Actually there is the declaration there but no explanation. E.g. no idea what

struct controlled_hero
{
brain_id BrainID;
v2 ddP;
};


is by just looking cuz no idea what logic does it serve? I'd say player is just broken down into these and each update potentially separated? Waht is ddp?

Look in UpdateAndRenderEntities function from handmade_entity.cpp file.

Thanks, this is making more sense now.

Simon Anciaux
1184 posts
How exactly does player state get parsed?

I believe ddP is the second derivative of P (position), so it's the acceleration. dP being the velocity.

64 posts
How exactly does player state get parsed?

Hey folks thx for replies.

He's doing all the states as 'actual' physics?

Like

b32x HopRequested =
(!Dodging &&
(Body->MovementMode == MovementMode_Planted) &&
(ddPLength > 0.5f));


where

v3 ddP = V3(ConHero->ddP, 0);
f32 ddPLength = LengthSq(ddP);


So basically this is saying "this movement is a jump [request] because hero moved with acceleration > 0.5 game 'units' " (Im just ignoring the other 2 requirements cuz they are obvious). And the rest there looks like just checking if hero can land/go to the place xyz etc.

So everything will be like physics rules scattered in those functions? Whats the episode this gets explained?

Why not something like

switch (state)
{
case State::IDLE:
{
if (control == Control::MOV_LEFT || control == Control::MOV_RIGHT) {
state = State::WALKING;
return;
}
///...
}


What's the limitation?

Mārtiņš Možeiko
2357 posts / 2 projects
How exactly does player state get parsed?

If you have access to HH source code on github, you can go there, open file you're interested and press Blame button. That will show exactly on which commit each line was changed - so you can open that commit & see the day number for episode.

There is also https://github.com/HandmadeHero/annotated_cpp repository that makes this process a bit simpler - it contains all source code + link on each line to exact episodes on which days this line was changed.

64 posts
How exactly does player state get parsed?