Implementing a character controller in game engines requires integrating physics systems through proper collision detection, where kinematic character controllers must manually handle collisions via contact listeners and inner rigid bodies to prevent falling through floors, with the physics system's gravity applied to the character's velocity and collision layers configured to allow dynamic objects to interact with static environments.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
FPS From Scratch (C++26 & OpenGL4.6) // Character Controller pt2
Added:Hello. Anyone out there?
Is there like a shadow here? Am I Has my camera moved?
Am I clipping my light? Am I Am I going mad? I've only got I have a second monitor for OBS and chat. And so this is where if I look this way, that's what I'm seeing. So I only got a tiny little window.
Hang on.
Mic's on an arm. So I can bring I can bring the mic with me. Right. How's How's this? Hang on. [gasps] Do I need to zoom in? Am I zoomed in enough? Obviously knocked this somewhere. It's sort of very precariously attached to my wall because it used to be attached to my desk and then whenever I knock the desk, the whole thing would shake.
Okay.
Right.
But now, hang on. Got the back of got the back of this now. I think the zoom is wrong.
Hang on. Get bear with me team while we get this sorted.
Okay, now I've just bumped into the I think he's Is that better?
Move the chair out the way. Right.
Of course. Now, hang on.
Okay, I'm pretty zoomed in on this, but I think that's okay.
Right, that's fun. Wasn't expecting to do that.
It's what happens. That's what happens when you don't stream for when you miss a stream. Everything goes to [ __ ] Hello everyone. You can I've I've not been paying attention. So, feel free to read your own names and welcome yourselves.
Um, only cuz I was trying to sort out the infrastructure issues. Right.
It's hot. I'm tired. Unbothered. Let's Let's do some C++.
Uh the pattern on the wall is just two hexagons. There's nothing nothing there's no deep law. You don't have to read into it. Um it's just the when I bought them, that was one of the suggested patterns and it looked like it kind of filled up a lot of space.
Right, let's see where we're at. So, character controller. I think we got [gasps] reasonably far. Also, for some reason, STO has a really nice like braille, which I really like, like Braille style graphs, which I really like to look at.
And for some reason, that's gone and is now just blocks. But if I run it over here, oh, sorry, not desktop, DTOP. Uh, oh no, it's gone. Fix that later. That's really annoying me. Like, do you I just really annoys me when things like don't work exactly how I want them to.
Uh maybe I should have a bit more um uh leniency on things, but like this this graph really irks me and I don't know what I've done to change it.
So, that's great. Um anyway, right.
I feel like my head is too big in this.
Right. Okay. So, we got this. Then, if we go to the debug camera, we now have our capsule. Okay. Now, yeah, I might need to zoom. I just a little bit.
Okay. Just a fraction out. And then what's this like on the main view?
It's good enough. Good enough.
Uh, okay. So, yeah, we've got a a bean.
I slept on my beans. um for anyone who watches Blue, which obviously I do. Um got a capsule. Uh I think today, so there's a couple of things if I remember correctly. There's kind of shortcuts I took, especially around the serialization because I couldn't bo to fix them.
May have to fix those later. But I think for now, uh I just want to try and get this moving because I think there's kind of a lot of moving parts needed to get that moving. Like we need to [snorts] we kind of have a top level key map mapper thing.
And then we're going to need different logic paths depending on which camera we're on. So we're probably going to need some sort of entity not entity class. What am I thinking of? Like um what does I'm I'm real porn. But do you know what I So that's some sort of like character class and then we can have a debug camera class and then a player class and then each of those will then be active at once and the inputs will just feed into those so we're not moving them all at the same time. I'm sure isn't isn't a real isn't it like like as in like am I am I making this up? Am I have I have I just have I just completely made this up. Um also was that just not showing for anyone there?
Yeah, sorry. Let me uh I just I don't know what I'm doing. Great. I hate everything. Uh okay, fine. This is what we got. Our cats. Uh and we need to be able to move it there. Okay, fine. Uh let's go.
Yeah.
The porn class is the base class of all actors. That's what I was thinking of. I might want an act class. I probably won't call it porn, but this is control by all by players or AI.
So, yeah, there you go. Hello. Uh, wrong button. Jesus Christ. Okay. Right. Um, I think we need to go back to the jolt code here.
Right. And see if we can figure out how they were doing it. So they had uh because we're going to need some way of controlling this at the moment.
So the moment we can get the we can get the position and the orientation of the virtual character controller. Um but we cannot do anything with it.
Yes.
Uh, character can uh, no, where's Sorry, it's been so long since I've done this now. And by so long, I mean like a week. Uh, test framework.
Where was the samples tests? I know they call it tests character character virtual test update we think.
So they blah blah blah blah they call well I think we just call update rather than extended update but uh that's fine.
Where do they do the calculate effective velocity handle input? Here we go.
A cheap way to update the price ground velocity. This the platforms that the character is standing on may have changed velocity. Do I care? We haven't got platforms. Maybe I can just keep this as simple as possible. So determine new basic velocity.
[snorts] So the current I'm going to have only horizontal velocity, right? We're not doing any jumps or anything at the moment. So that's fine. Ground velocity is fine.
But whatever.
Right. All right. So once I've calculated, so I can calculate the velocity, right? That's fine cuz we already do that. Where do I where do I stick the velocity? Where does the velocity go? Oh, you just call set linear velocity. Is that literally it?
So, does that mean if I go back to the code, if I do virtual character controller, can I do character set linear velocity?
Uh, which way? Which which way's away from the so 0.0 f 0.0 f and then what into the camera. Hang on. It's right hand rule.
So it's negative away from you.
Is open jail. My favorite graphics API.
It's certainly the graphics API I know the best.
And I don't have enough experience of any of the others to say whether I have a preference. Oh, he's off. Look at him go.
Kind of feel like I don't know about you. Kind of feel like gravity should have kicked in at some point cuz there's no there's no floor rig bodies here.
Gravity. Hello. of I does one have to manually gravity.
Is it because it's a um Well, it's not technically a rigid body, right? It's uh Where's me where's me browser? It's not It's It's um Oh god, what's the term?
Kinematic controller. So, oh, you do give it an up gravity. Here we go. Just comment. This comment just says gravity plus equals character up rotation times the physics system gravity times the in delta.
Uh I have no I have no opinions on dot because I've never used it. So, how does one how does one character up rotation?
Character up rotation is to match the up vector set by the user settings. I think it's just going to be up, isn't it?
So, do I right wrong button really not having a great time today. Uh, so let's do let's do auto.
uh new velocity velocity equals uh we should talk in terms of our types, right? Cuz that makes more sense.
So, let's do 0.0f 0.0fus 1.0f.
Actually, let's make them go like real slow.
Then let's do new veloc.
Keep going. Three out of 10 new subs.
Exciting.
Good week, by the way. It's been all right. It's been it's been hot and been pretty busy, but it's been okay. Thank you for asking. How about yourself?
Uh, correct. Just keeping you on your toes. Uh, and again, still there. Okay.
Okay. New velocity plus equals I'm going to do vector 3 0 1.0.0 F.
Well, I feel that should be negative times uh I haven't got access to the physics system here, have I? That's so annoying.
So, this is going to need So, hang on. Let's go back to the physics. Sorry, I'm going to be jumping around a lot all over the place today.
So, here's where we update the player controller. So, what does physics system get me? I can get gravity.
All right, but what type is that? That's a vector 3. Okay, fine. So that's going to need to be dependency injected into here. So let's do Nope, don't need that. Do const vector 3 gravity. So I think I think I just sack this off, right? I think I do that plus gravity times.
So if I times it, I do have new veloc.
Thank you. If I so in their code here they times it by the delta time but delta time is a float. So didn't I have to do some shenanigans for this to get it? I need to times it by one over delta count, don't I? So let's do let's do let's do this. Let's do con auto delta float equals 1.0f over delta.ount. Right? So this gives us everything in sort of jolts. In fact, actually let's be more explicit. Let's call this jolt delta because that is what effectively we're doing, right?
And then here we can do jolt delta.
Uh okay. So that so gravity times that and then we can do two native uh new velocity that uh pretty sure native is a thing for vectors. Oh no sorry it's too jolt isn't it?
Oh yeah.
Uh maybe if we need it more than once like the I would argue for a lot of code the correct place for it is right next to where it's needed if it's only needed in one place. Once it's needed in more than one place that is that's kind of my mental process for when to start breaking stuff out into functions. Like obviously if the function is massive you could decompose it anyway but I try and keep stuff as close to the point where it's actually used and then only then start to abstract it out. Okay. So we got that. So let's go to the physiques system uh and then do to native physics already gone. Where did it get? Gravity physics system.
Okay. Gravity too many. What you chat about? That's a spec three. And I have a back three. Let me check that.
We'll see what the compiler has to say about that header file. Oh, yes. Yes.
Yes. Yes. Yes.
Yeah.
[ __ ] right off. Sling just joining us. Jolt is very particular about the order of the header files that you include. So I abstract that all away into one file to manage the misery.
Um and it also has some deprecations in there that it doesn't like. So the problem is though clang D I guess released the LSP is super helpful and every time it sees a new thing it's like you're probably going to want the header for that. And 99% of the time it's correct except for this specific case where I don't want the header cuz the header's already taken care of.
Uh, yes, you're right. I think you're graph bugging me. Might turn it off.
There you go. Gone away. Right. Uh I'm missing a reference somewhere. Just just seemed to spend enough time looking at C++ error messages and you can almost make some order of the chaos some some meaning within the entropy.
Okay, you've just fallen straight through the floor now. Great. So, why is he not kind of the opposite problem now?
Like this these gray lines here is are rigid bodies. So, I'm going to I'm going to have to handle the I'm going to have to manually handle the Right, let's go read some. Right. This is today, guys.
We're reading reading the sample. Uh there's got to be something about collision in here.
So, I don't care about character versus character collision cuz we only have one actor.
There's no floor over there to collide with. I think there is though, isn't there? Doesn't we didn't we my Before I go up on one, let me just check.
Uh no, it's jolt physics.
No, I don't. I Oh, I see what you mean.
No, I think it's I think it's just straightforward to the I do I do see what you mean. Let's Let's prove this out by killing this. Okay, I posit to you this will still fall through the floor.
I think this is the issue with the kinesthetic style character controllers.
We still have to manually tell it about the collisions. I could be wrong. I would love to be wrong.
No, mate. He's still falling. And I think the speed it's falling. I think even if it was clipping through and it was handling that, I think it would pop back up because I don't think it's moving fast enough for tunneling.
But now we know. Correct.
It's the It's the smoking gun, if you will, if you were talking to uh talking to an AI.
Uh, okay. Right. Let's go back to this and be like, "Hey, collision. Don't care about that. Don't care about that character. Don't care about that.
Don't. Here we go. Here we go.
This is contact sync with the character.
Okay, this isn't an assert. So, I think we're getting closer. There's definitely this M character get active contacts.
[snorts] Uh, okay. This might be in one of the many base classes.
I can't remember what this inherits from. Is it character base or is it first? See, this has a character contact listener [snorts] inter character contact added on character on contact solve called here. What's this?
Oh, excuse me. Right.
On common functions recall when contacts are added persisted handle input add character movement setting on contacts are called whenever the character movement is solved and constraint is hit allows to override the resulting character velocity EG by preventing sliding on certain surfaces.
Uh Emory two years. Thank you very much.
Come what what a great achievement.
Thank you very much.
Okay.
Okay.
So, where does one shove the character contact listener?
Because bass can't be aware of it because this is derived further up the chain.
There's definitely like uh I'm definitely missing something somewhere.
Uh I to be honest I have no clue what I'm staring at either. So on contact added is the call back for collisions. Correct. Yes, I think that's the case. I think it is the call back for the collisions. What I'm saying is how is that registered? Like just I don't think just inheriting from this class inherently adds you to the like the physics system somewhere in Jolt it will be expecting a character contact listener of which this is that. So it'll be passing itself in.
Um, hang on.
Uh, will the shape eventually be able to plop onto the floor and roll around a bit? No, it should be locked. It's l its angular momentum should be locked to just the y- axis. I think that's right. Like it should only be able to rotate around the y axis. X and zed should be locked. Otherwise, it will just I remember when I first tried bullet for a university project and I didn't realize this was the case and I attached the camera [snorts] to the to the pill to the to the capsule and then simulated it and then nearly threw up from motion sickness because the the pill the the capsule immediately fell over then started rolling and the camera was just going like so what am I doing with my life?
So, you got this new character virtual, which I don't know. We do do we do be doing that.
I'm just really worried you need to use this character versus character collision for all character collisions.
Do you know what I mean? Like I feel cuz you add the character. Here you go.
Can I find What's What's What What is this?
What is this?
Uh, so this is a character versus character collision simple, right? Sure.
It's It sure see right where's So where's what's this one? It's at home.
Nowhere. Great. Okay. Can you Can't search. Okay.
What is this? Must be self-defined somewhere, right? I don't think they've got that in there.
I could clone the code and GP for it.
Unless it is just in character virtual.
Okay, it'll fine. It is simple collision checker that loops over all registered characters. This is a brute force checking algorithm. If you have lots of characters, may want to store your characters in a hierarch hierarchical structure to make more efficient. Note that this is not thread safe. So make sure only one character virtual checking collision at a time and you add a character virtual.
This just seems like character character.
Here you go. What's this character virtual?
The object usually represents the player. Contrary to the character class, it doesn't use a rigid body, but al but moves doing collision checks only. Hence the name virtual. The advantage of this is that you can determine when the character moves in the frame. Usually this has to happen to a very particular point in the frame.
But the downside is that other objects don't see the virtual character. To make a character virtual visible to the simulation, you can optionally create an inner rigid body. Uh do I need an inner rigid body for this to work?
A character virtual is not this also means that accord.
So do I have a character?
Uh, so I I have a car I have a character virtual right yeah so I think I need to go back to So they actually have an example of this and I think I skipped over it here in a body shape and I want the inner standing shape. So I need to work out what the hell an inner whatever the inner [sighs] goodness right bet it's in here it's always in here right okay mate sure but like where where do you set that here you go if it's a capsule then I create a rotated translated shape settings of another capsule shape. Is this How does this Didn't I already have a shape?
Oh, hang on. There's a difference here.
Hold on.
So they they have both the standing shape and then the inner standing shape.
And the inner standing shape looks very similar.
I would posit almost the same.
Oh, here you go. What's this? They it differs here because after the height standing, they have the inner shape fraction times. So, they make it slightly smaller or larger depending on whatever the hell this is when it's at home.
Uh, this could be literally anywhere.
I can't remember how I found this last time. I think it was wishful thinking because if you click this sometimes the uh sometimes the GitHub tool will help you out and other times it will absolutely not.
Okay, not in there. Character test.
Not in there. Uh it's not going to be in the CP file surely.
That's where it's all used to, mate.
Is this at the top? No, it's I'm just sort of spinning around in circles now.
Where the bloody hell is this?
I could log in.
All of this.
Okay. What was I What was I after? C.
Hang on.
I want the C in a shape. Uh RG uh character base test. I'm pretty sure pretty pretty sure I looked in there.
Pretty sure I looked in there.
Okay, fine. Cool. So, it's 0.9. So all we have to do is now all we have to do is do uh inner inner chap and this will be 20G.
Uh and then this is hang on I know you can't see it. Bear with me. Bear with me. Hold on. Hold on, don't panic.
Uh, this is exactly the same, but at the you put for this character radius here, you do 0.9.
All right, I think that's right. So, you have the inner shape fraction, which is a half. So 0.5 times the inner shape fraction which I've already pulled out.
Then comma the So that's it's either the height or the width. It's making one of them slightly smaller.
Right. Okay. And then and then and then and then how do I where's all this miserable instantiation goubbins?
Here we go. Right. So inner shape. So, and then we can do settings M in a body shape equals in a shape question mark and then settings M in settings M in a body layer equals Uh, what type is this? This is an object layer. So, I think I want static cast.
Jupah object layer. And then I want to do uh that's not how you static cast, is it?
And then I want to do [sighs] Christ. Uh, physics layer static. I don't know how I make it interact with the rigid one with the dynamic ones as well. We haven't got any.
Uh, yes, correct. Could shout.
Uh, I think that's should we see if that blends positive.
Well, I've certainly now got two shapes, so I've made progress.
That doesn't explain at all in the slightest.
No. Again, I'm going to collision. Yes.
So, I assume I still need to do something with the collisions then.
But there's one of these many tabs.
Where's I bet I've lost the tab with that big comment in it.
Here you go. But the downside to make a character virtual visible to the simulation, you can optionally create an inner rigid body through create virtual settings and med shape. A character virtual is not tracked by the physics system, so you need to update it yourself. But like if you just read that comment, right, I don't think I think you could be forgiven for thinking this is just enough because it says to make a character virtual visible to the simulation, you can optionally create an inner rigid body, right? And that's what we did. So my interpretation of that is if you want to make this visible to the simulation, all you have to do is add a rigid body. Clearly that's not right.
There's a but do do you see that is my interpretation of that comment of that documentation right but there is this set listener which is I think someone mentioned this and I might have ignored it sorry set listener so let's go back to so here we go install contact listener for all characters. So I do need this set listener.
Okay.
Yes. Well, I mean like the logic for two objects intersecting is handled by the physics engine, right?
That's what the physics engine does. So again, by opting into that, like my interpretation of the physics simulation can now see your object means it knows how to interact with it. Clearly that's wrong. Okay. But I just Okay. Right. Anyway, so now we need a I reckon this is where we need that uh character contact listener. [snorts] So let's do [sighs] sorry lot sign today.
So let's make this a need to be p lick. Right. I never want to refer to the it probably does need to public uh character contact list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listen list listener help okay I'm hoping that should not blend unless it is a abstract class where there is implementations for all the overridden methods all the virtual methods. I'm hoping it's going to pop up and say you've not implemented these methods.
Sorry. Thank you. You've just missed all that.
All I did was Okay, I think this is going to blend. Interesting. Okay. All I did was make it this. Right. So now we should be able to then do uh character add. No.
Help.
Set listener.
Set listener this.
Okay. Okay. Right. We've construct. So that means then that this must have virtual methods with all defaults.
Do nothing. Okay. Fine. Yeah.
So you got on adjust body velocity on contact validate on character contact validate called whenever the character collides with the body for the first time on contact added. Christ right we're going to figure all this out now.
Uh where where am I using an owning raw pointer? If it's here, it's not technically owning because this is the miserable Jupah ref, which is basically a shared pointer, and I don't really have much of a choice around it. It's it's somehow worse than a share pointer because it's a hand rolled one that uh is slightly mystical to me.
Uh yes, there is there's a test for this. So what we can do is we can now go back to virtual character test and then we can start seeing. So this implements a lot of these. So check if a character is is on charact on contact validate. So we basically going to look at the implement what they do in their test for all of these and how we care about it.
[laughter] I know, right? [snorts] Think how much more efficient Jolt would be if it just had a linear understanding of ownership, right?
So, let me go.
Okay. So, what was the first one?
Assuming they were in order. So let's look at on on contact validate.
Oh my goodness. Right. Okay. Only except back facing contacts if the surface normal which was flipped points outside a cone of 30° from the up axis to prevent unable to stand on upside down faces. This prevents us from sticking to the bottom planes of the steep slope and acute angle triangles that face downwards. But Oh, right. Let's look at the next one. On adjust body loss at least comments, right?
Apply artificial velocities to character when standing on the conveyor belt. I haven't got a conveyor belt. I think a lot of this we can ignore. Like I don't think I care about this unless because this returns a bull. So do I have to The question I guess is what is what is what is this returning and do I do I care about it being not the default? So I think there's going to be a lot of back and forth with uh can I find close some of these down just my head in.
That's fine. That's fine.
That's fine. So, let's go to uh character virtual.
Uh no, wait a minute. I want character contact listener and we are looking at on contact validate. That's not what I wanted.
I am right.
Where did I sit with all the comments?
No, I want what? I don't want a logging.
What? I want the original. Is it just in character virtual? Oh my god, I hear everything.
It's probably a docs page for the summer, but here I am. Right, here we go. on checks if a character can collide with a specific body. Return true if the contact is bad. So presumably I want to always return true.
Oh, and the default is that. So that's fine. Okay. Tick one off.
Okay. Right. Um I use Ellen's a lot especially for like conversations and stuff like that and talking about docs and stuff like that, but I'm not using it on this project because it takes a lot of the to be honest it takes a lot of the fun out of it. Even if it is quote unquote more productive, I think it's difficult for learning. I think it's okay as a tutor if you especially if you prompt it to be like, "Please don't give me the answer, but try and help me get there." That's great. I think if you just ask it for code, your your brain has no reason to retain it, right? If you you learn through making mistakes, right? Because if you make a mistake, presumably you've gone through some misery of that mistake. Then when you learn it, you kind of earn that knowledge and your brain be like, I will remember this so I don't have to go through this misery again. If there's no misery associated with it, your brain has no reason to retain it because and if you always know, if you know the A will always give you the answer, you're never going to remember anything. That's kind of my view on it. Like you got to make mistakes. You got to allow yourself to make mistakes. But am I making a lot of mistakes with this? Right. Next one.
We're going to have to go through all of these, okay? So we can know what we want. So we don't need this. So what I'm going to do is I'm going to top to bottom these. As we find ones we need, I will implement them. So the next one is on adjust body velocity.
These are not in all that is not in here. Great. Oh, it is here. Go. Sorry.
Call back to adjust the velocity of a body as sim by the character can be adjusted. eg implement a conveyor belt or an internal dampener system of a sci-fi spaceship. I don't think I need that. I have neither of those two things. So, uh on contact common not in here. Great.
What common Okay, fine. That's not part of the interface. Fine.
Uh on contact added. I suspect we want this uh called whenever the contact well called whenever the character collides with the body for the first time. So what do they do? So they do on contact common. Okay.
And then in if in character equals then character blah blah blah blah.
So it's basically they so on contact common is their implementation of on contact added.
On contact common draw a box around the character when it enters the sensor.
Okay. I don't have sensors. That's fine.
Not yet. But that is good to know.
Yeah it is. Dynamic boxes on the ramp go through all the permutations. Don't have that. If we encounter an object that the P can push, enable sliding. So, we don't need any of that. [snorts] On contact persisted.
Cool. When the character persists colliding with a body.
They just call on contact common.
I just I don't see any of this stuff that I care about.
Do you know what I mean?
Will this just work now that I've registered a listener? Is that just enough to make it work?
Look at common. That Okay, fine. Let me Let me So, we think Sorry. But we think common does something. So on contact added calls on contact common. And on contact common does what?
Draw a box around the character when it enters the sensor. Don't care. Dynamic boxes on the ramp go through all the permutations. I don't have dynamic boxes on a ramp.
If we encounter an object that can push the player, enable sliding. I don't have that.
I'm just curious.
The fact that it has a listener, is that enough to get it? Well, it must if those are just responding to events, right? It must be able to process those events, right? Otherwise, how would I do you see what I mean? Like, the fact that I've now added a listener implies that I can listen to things Let's let's do let's do on contact added and then log it and then just see there was like a pre wasn't there like a logging one.
But let's just let's just do this for my own for my own sanity. Let's do It definitely doesn't like character contact. Uh, let's go to jolt and then do hash include. I'm going to take a stab in the dark here. Physics collision character character.
Okay, that's pretty sure it does. Pretty sure it does override. Uh, I could be wrong. Often am protected. It's got a different uh protection.
I will check in a minute. I just want to if I can get Why is it I need to know where the hell is that doing up there?
Get off here. Right. Where does this What was it called? Uh I've already Hang on. Wait. Whoa. Whoa.
Already forgot what it's called.
Character contact.
Uh RGen class character contact.
Okay. This is worry that character contract used bloody everywhere.
Well, it's using character virtual.cpp.
So, let me just check what that is doing, although obviously not transitive include character con. Was it what was the type called character contact?
Hang on one minute. I think I've got I think I'm doing this wrong. Let's do this and then do on contact added and then we'll do Wait a minute. That is is that a different type?
Yeah, that's Hey.
Oh, I've got contact common. I've copied the wrong one. Sorry. Absolute fool of a tok.
Uh, hang on.
Uh, GPH those GPH hate everything. Right.
I want a linker error.
We get a link error if you declare an override but don't dep. Yeah. Nice.
Okay.
Uh virtual character controller.
Uh log debug here.
Maybe Okay. Right. Let's see if we can get this triggered.
And now we're in. And all I managed to do is make two shapes fall through the floor.
Okay. I don't think we got anything in the logs there, which is upsetting.
So, why is that not simulating it? Then I'm missing a step somewhere. Do I need to Is that inner body need to be added as a rigid body somewhere? So, so let's go back to here. All right. So, where is this M in this min standing shape? Right.
So, that's restore state. Don't care about that. That's initialized. So here we go. If we set the inner standing shape, which we have, how does one Oh, what's this? What's this? This looks right. Handle input.
Switch. Unless if you switch the stance, which I I feel like that inner shape needs to be poked into the physics system somewhere. Am I right? Am I Am I Am I mad?
Uh RG Min standing shape see this is just assigning it. I don't where does it get because even when you when we create the rigid body right we still have to somewhere create in our body through the interface right you still have to add that body in and I just I can't see where that happens let's follow this right okay let's follow this through.
Let's follow this through.
Maybe there's a kind of set st maybe. Uh I see what you mean. So set I don't think there is. There's any set shape and this just overrides it when you switch the stance. Um right. Let's follow this through. So when I in fact actually let's do this. Let's see if we can do this in the code. Uh uh virtual character controller. I hope this works.
Right. So when we all we do is we create a new character virtual. Right. So let's uh where's the where's the actual code for this? Where do we Where are the constructors?
Controller.
Character virtual. Sorry. Char character virtual.
Character virtual. Right. Okay. See, there's no She does have the physics system here, right?
They call set in a shape when we I uh M in a body shape.
And I give it a layer as well, unless it's the layer that's buggering us up.
I'm pretty sure the static objects are set to the static layer. They have a moving layer which is bit uh uh set they only ah so so they only do set in a in a shape after the construction. So if they want if you want to change from the standing to the crouching position you don't have access to these settings anymore. You have to go via the character and do character set in a body shape. So you only do that if you want to update it after construction.
Right. So where do they use? Right. So where right okay blah blah blah blah blah set mass set max strength create an inner rigid body if requested. So it does create it body create settings body get body interface blah blah blah add body.
So it does get added to the physics system.
I see hello.
So this is this is been added right which means is it the layers is it is that what's is that what's tripping us up when I do What layer is this created with? Crate box.
Uh debug renderer.
It is static.
Ah, when I deserialize them cuz they're effectively loaded. Oh, Jesus Christ.
Hang on. Let's do [snorts] scene.
create rigid body create box static. So is they all get they're all on the same physics layer.
Okay, I think we can roll I'm like 99 I don't think I even use dynamic anywhere.
Oh, interesting.
I only I only my broadface filter only checks for things if they're dynamic.
Oh, plot twist.
Oh, Christ.
So my my thing needs to be dynamic. Oh, what a fool.
Is this is it easy as is it just as easy as doing this? Cuz obviously the rigid body is not going to be static. Why would I ever think it would be? Yeah.
What? All of it took mate. This just works. Absolutely unbelievable.
Oh.
Oh, there it is.
Okay. Still not I was like I think we need to check that that is working.
Uh, I have no thoughts on box 3D because I've not used it yet. I probably in all in all honesty probably won't. Not that cuz I don't not cuz I don't think it's not has the idea to be great or anything. It's just that I'm just very much embed in bed with Jolt at the moment. Maybe on a future project, but I think if I can build out all this in Jolt, there's no reason why I wouldn't keep using it.
So this will return true if either of those objects are dynamic.
Is that not the same? If either of them are dynamic, return true.
Let me just I feel like it's there for a frame as well. Do Do you see that? Like it's Come back. I am slightly faster than gravity. Well, not gravity is in something in freef fall in grav in double check. Yeah, you don't get anything here.
Well, I thought I already had registered a contact listener.
Sorry. Thank you. Uh, I already have registered a contact listener here, right?
We should be calling into this.
I don't know. So there's basically there's basically two potential issues, right?
Um one is that I've not correctly added it to the physics system and the other is that I've not correctly configured collisions within the physics system. I mean they both could be true as well, but those are the sort of the two issues. Uh I haven't no I don't have I don't have listeners on the other objects. I don't think I need them because when we started we did we did have just a rigid body that would free fall.
But do you need to set a listener?
I see what you mean. Is is the point you're trying to make that are they without a listener will they not generate contact events?
That seems a little bit farfetched.
But I see I do see a point. Uh so you're saying something like physics system dot get Uh oh, sorry. Uh interface.get uh set.
I don't know how you would set the listener.
uh I'm happy to try and figure this one out. So, we have the interface and this gets you like position and stuff of the There's no like set as far as I can tell there's no listener in here.
All right.
Uh, all right. Uh, get position. Listen.
Right. So there's no within the body interface which is so far how we've interacted with all the bodies there is no uh listener through that doesn't mean there isn't elsewhere which I think where uh add step listener and uh what's this set there set contact listener.
Uh, doesn't jip H have a Didn't we find this like logging listener somewhere?
Did I make that up?
Character contact listener.
Login. Character contact listener.
Uh, so that needs to be in login character.
Oh, that's in their unit tests.
Gross. I don't think I can uh don't think I can access that.
Uh, don't do this.
Oh, it does not like that. I don't blame it.
Uh, I suppose the actual easiest thing to do is to do to prove this out. Let's do physics system and let's do public jph contact listener which we know I don't actually have to implement anything for and then I can do this so that will give the whole physics system a contact listener.
This is it. This is the stream. Whoa, whoa, whoa, whoa, whoa, whoa, whoa. What have I broken?
is a cuz there's the difference between a character contact listener and a contact listener, isn't there?
This looks like a header include issue somewhere. Oh, is it just general headers?
Yeah. What?
Man, that is an absolute pain in the ass. where the compiler can be like, I don't like this header being here. Not like, here's the cascading set of errors because you put the header in the wrong place.
Something fell through the floor.
I didn't get any logs. So, it was a good idea. I don't think that's it.
The physics system has added the inner rigid body.
So why is it not when I call update?
Why is it not updating that?
What's that random one I put in collision steps?
Oh, my favorite. Finalize contact cach and call contact point remove call backs with two zeros. The absolutely I mean it's doesn't get any better than that.
I think jump layers moving is our dynamic one as well.
Let's Okay, let's let's let's try something wild because I'm running out of ideas. Let's Why can I not There we go.
The capsule does not collide. And that is the problem that I'm trying to fix.
It's like make or make or make or make all over again. Oh [ __ ] I need to schedule some shorts. [ __ ] Right.
Sorry.
Okay.
So, the issue is our layering system because he is he is straight up not going through that. And presumably if I give him a wee little nudge, we will see him fall off the edge of the world.
How I've got the I've got a whole bunch of shorts edited. They're just sitting in the YouTube studio waiting to be given a title and then scheduled. Like I've got I got shorts for days. Okay. Right.
[ __ ] you.
Okay. Right. We're doing it. We are doing it. So the question now fundamentally is what have I done with this uh layering system? So are the layers incor uh why am I watching the cup? Because I do not care.
in the nice possible way. It is not not my thing. The only reason I was in any way even remotely interested in England is cuz I was just thought if we win we might get a public holiday. That's the only reason I cared.
uh because there's a difference between maybe I need to better understand this because there's a difference between object layer pair filtering and object broadphase layer filtering and I'm not sure I fully understand the difference and I'm not sure why I think I have to go back and look at what they do has this got any docks class object concide with a broadphase layer so I I guess the I guess I guess broad phases can have layers as well as objects but I don't what I don't understand is the interplay between them. Can they can they can they exist on different objects? So can I have a static and dynamic object layer but then I can have a physic a broadphase layer where they all exist.
I guess the question is like which of these fixed it?
Yeah, that's what the broadbase does is it does go base uses it internal like fast accelerated hierarchy to get a potential list of collisions with only false positives. So they might not collide.
So, I think you're guaranteed to get everything that does collide, but you might get some extras.
Okay. So, that that seems important.
So, let's revert that and try this one.
In which case, I have never set a layer on on a broad phase as far as I can tell.
Oh, okay. So, they're both needed. Is that Is that what I've experimentally proven?
Both of these are wrong.
I guess it must do these in a hierarchy.
I wonder if it does this first, then this. So, what? So, hang on. Whoa, whoa, whoa.
What is fail to class to test if two objects can collide based on the object layer use while fighting collision pets? So this this one I understand. Okay. And we basically say if either of these are dynamic.
So hang on. Let's look.
Uh, physics layer one.
Physics layer layer two. I may need in here for matter. Okay.
Okay. Usually want objects that don't collide with each other in different broadphase layers. So if I just not added any of these to a broadphase layer, cuz at the moment I just want everything in the broadphase layer, right? There's no reason for them to not be.
I wonder if that's that's probably the optimization, right?
I'm thinking about it.
Okay, so static dynamic. So, it is getting something that is So, it is getting something that is dynamic in there. So, why is that?
Yeah. So I think yes I think the issue is right I think I understand now this allows us to set a a basically a hierarchy of things that should collide so everything will only collide if it's in well you set the rules right so given any two layers we will say where they collide within that layer right I suspect it then calls this and this then does a further check so we want we will need we will by by necessity all static and dynamic objects must exist in the broad phase layer right because the dynamic object might interact with any of them however we don't want to pay the cost of intersecting static with static static with static because we know right that they will never move apart because they're static. So that's when this comes in. So we can basically so this should This should effectively always return true, right?
Because there we're going to only have one broadphase layer, right? We're going to shove everything in that. And then within here, we basically want to say, okay, if only if one of them is dynamic, should you actually continue? So, I don't I really don't understand why this is now not working because this basically says always return true. And here we're saying here we're saying if E isn't dynamic.
But let me let me run it let me run it with the um logging so you guys can see.
So that that chips off down there.
Now if we go up here look object should collide static down.
Right. So [sighs] there are some static statics and sometimes dynamic static because this is what we want, right? We don't want all these static statics to be colliding with each other. So only if either of them are dynamic should we return.
God bloody damn it. Sorry. Right. See static damage static damage.
But there are some static statics which I suspect are the static objects in the same broad phase or at least been passed through because of that true.
But we don't care about those. We only care if either of these is dynamic. So that's the bit I'm missing.
Why is this not This suggests to me then that something is mis layered. Something has the wrong layer somewhere because if we say if we say always return true, always handle every single collision, it works, right? So what we're basically doing is at some point this is this is incorrectly returning false. Right?
That's the character layer static.
I Oh, yes. Well done.
These should be dynamic, shouldn't they?
Oh, yes.
Think you might have solved it.
I remember it's like why am I putting static here?
Me the fool, not you the hall.
Okay. I think I think he walked forward there and then fell off the edge.
Uh utils.
So, let's just see if this works.
What this?
We may Okay. Right. We're there.
Let's commit that.
That is a commit. So, let's do I think this is a bit of a miserable like one commit which is pretty much just like uh add collision support uh collision handling to virtual character controller.
Nice. Okay, we're getting there. So now what I want to do is I want to attach the camera the want to attach the player camera to the rigid body. Okay. So let's do physics system.
So this is going to need a auto character controller.
uh virtual character controller something like that.
Do I need to do I ever need to have a const version of it?
No. I think physics system is always non-const. I don't think there's any way you could really get hold of it. Oh, because you access it through the the service allocator. Service locator doesn't really really make sense anyway.
What do I call it? It's like character player controller obviously.
Uh, I'll change that to steady controller.
All right. Okay, that's cool. I've never modded a game.
That sounds really interesting. Uh, all right. So, let's go to main. Not been here in a while. Uh, let's do where we do the physics system.
Probably don't even need this anymore.
Get rid of that.
Uh, in fact, I think we can get rid of a lot of the extra fluff that we added. We don't need this anymore.
Okay. So, where do we have the physics system? So that's there. So I think I can do auto player controller equals physics.
I think this reference will will still be valid even when I move this into the service locator.
Uh no, I've not heard of that. But it sounds interesting.
Uh okay. Okay. So then after all this is done, we want to before we update the physics, we want to do scene dot gh that's where we need to start pulling out the cameras, I think, cuz I only want to do it if I've got the player camera. I think I can don't if we're going to do it tonight, but I think next stream is definitely going to be a big refactor.
Yeah, exactly. Um, I'm just going to do this anyway for now. So, set position to be uh player control. I just want to see if this works.
Player controller.position.
So, this should now move us along when the game runs.
Uh, no, I don't really care. And that's supposed to play. Not my thing.
Uh, what what have I done? I've missed off a uh Oh, I bet it's off the of the anonymous name space. Yes, it is. Okay.
Classic.
Like that. Do you reckon like that?
Looking good.
Looking good. So, when this starts, we should just move forward then. pull through the floor. Then I'll remove that code. But at least we're kind of there.
Uh, we've got collision detection for the capsule working. And hopefully now that I've attached the player to it, we should walk forward and then fall through the floor.
Game play.
Also, like my other character has no choice but to just tag along for the ride now. [laughter] But I still can move a little bit.
Okay.
Get rid of that.
Uh, okay. So, we can me just uh Okay. Expose player control from phys biz physics system.
Yes, I know. Yeah, we can adjust all that later. I think half an hour, right?
I think we should start on the refactor cuz it's going to be quite big. I think what do I think? I think we want more abstraction. I'm not even joking. I generally think I want more abstraction.
I think I want some sort of actor class and that could have player or the free cam implementation.
Okay.
And then both of those, one of those will only ever be active at once. Okay. We can just have we can just allocate both of them and then we can just have a pointer to one of them and just switch between them.
We will give it an update method with the current charact which will then allow it to decide how it's going to move. So the player can respond to ward and the the free cam can respond to ward K qe. So it can move up and around.
It will then need some sort of update method and that's where in the player one it will have also be constructed with a reference to the um player controller and that's where it will set the position to it.
Yes. So the free cam one will just use the input and set the position manually because there's no physics. the player one will translate that to a linear velocity, set that on the underlying controller, and then set the camera to it. So then each actor will own a camera. Is that right? I think that's right. Because I think even if we had like an AI, like a like an enemy actor, we might want a camera on it anyway, so we could debug render from its point of view or use that for maybe occlusion checking and stuff like that. So, and then we'll have to ham that into the renderer. All right. So, I think we can start basically abstracting this out now. So, as always, the the question will be where do we put it?
Probably core.
I think core is going to be about as good as it's going to get.
So let's do e source core actor.h.
It's helpful for me just to start interfaces is the hard part, right?
Everything else just typed on the keyboard. So let me I also really want to refactor the um the key input. I wonder if I just do that first. So at the moment at the moment we have key state which is a unordered map which is a little bit I just don't think it's great.
Like that feels to me like it should be a just a uh just bits, right? Like a bit mask of which ones are currently set.
I wonder if I just abstract that out first and then we can just pass around that.
I think it's used to bit set right because Right. Let's Okay. Interesting.
Let's do E source core.
Uh oh, actually or maybe events keymap.h cuz it kind of fits in with that anyway.
Yeah, exactly. Yeah. But so I think right okay let's this is this is fun.
This is fun.
I think we do this header only as well.
I think most of it can technically be constra uh let's do class key map right so effectively what we want is uh auto uh constra auto set and then that should take a UFPS key.
Might as well make this hardcoded on my own types, right? Hash include uh events key. All right.
So, set key state, right? Think that's Yeah. Uh no, not keys. uh event.
All right.
Cuz this says where it's the up or down and what the key is, right? So we b say this will process a key event, right?
Okay. This will process that. And then we can do constra auto is set. And this will just take the key.
There's no point passing the whole thing in key. Key key. All right. And that'll be a bull const. And then this will be a void, right?
So key is this enum obviously doesn't start at zero and we don't actually we will need to scale this so that I can add more keys without ever having my design goal is to be able to scale this so that it doesn't matter what's in that enum reflection Right. Let's do bit set. All right.
Uh stood bit set like some number.
Right. To be determined at compile time to be determined at compile time.
Map. Oh, hang on. Right. Okay. Fine.
Okay.
Right. Wait, wait, wait.
Right, getting excited now. Right, let's do hash include meta. Right, let's do name space imple.
Let's do constra auto max val or size T.
Okay, let's do return stored max. Oh, can can we can we can we can can we but but can we do stood meta enu in enumerators of right uh reflect UFPS key right pipe two stood views transform.
So this will then get a auto meta info return the two underlying splice the e back.
What do we think?
Uh, where's the underlying in utility? I don't think that's my issue.
So, can we go through all the compile time? Compile time. Go through all the enumerators of the key. convert them to their integral type and then pick the max of them. And then that means we can then do uh implements.
Oh, this is now much more fun than whatever I was going to do.
Let's just do uh key state. Let's do auto key map equals uh UFPS key map.
Maybe unused.
These are like weird errors with nowhere near where I am. Why is this What were the errors? Hang on. Sorry. I didn't realize I was on a roll there.
Size versus size team. Fair. Sure.
You're missing it, right? Sorry. Oh, yes. Sorry.
And I'm missing a like that.
Thank you.
That would explain the his errors because they were still still.
Hang on. Wait a minute. That that that Oh, the dynamic array or whatever it is.
Uh, stood static array, isn't it? It doesn't like this. Here you go.
Here we go.
E is not a Oh, no. No, no, no, no, no, no, no, no, no, no, no, no.
You can't have constra. This only works at conextra time and arguments are not function arguments are technically not constra.
I think what we need to do is probably use some sort of boomeral loop.
uh auto min sorry max equals stood size t right well sorry it'll be a modern age one so we'll do template 4 constra auto e in the meta enumerators of um reflects E and do if max is less if max is greater than splice E max equals uh hang on const auto auto val equals the two underlying splice E and do val max equals val.
No, because you don't know if this you can't guarantee the first one starts at zero, right? Otherwise, you would just do stood range of size of the enumeration.
The issue here is that uh key doesn't start at zero and you can't guarantee it will. So you have to go through each one and find which is the maximum one. Also they're not I don't know what these values are. They could be smaller or greater than this. I have to go through each one and splice the VA splice the meta info representing the enumerator back to value space so I can keep track of the maximum. I think I think that's correct.
Well, obviously not in this case cuz it's all gone bang not constant expression. Oh, this was where I need that uh stood. Is it like define static array?
There's some magic that makes this work, right?
No. But then how do I index into it if I'm given?
Hang on. There's no way this is going to work.
Oh.
Anyway, what I'm saying is when I come to set right this key, if I'm given like this, what what index do I pick? The easy thing is just to pick this index, right? And just make it big enough whereas then if I just make it big enough like I don't know also I just want to write some reflection as well.
uh main uh player controller.
Also, I reckon we could do something funky where we scale it back to zero. So, we we cuz obviously if the first value is say the first value there is ox 48, you're never going to fit anything in those first 48 bits, which is a bit of a waste of space. If we know the if we know the minimum and the maximum that's word the fourth bunk is the fourth in the hi the yes but what I'm thinking now is we could create a relative index uh if max sorry you are correct That should it shouldn't matter if I create the minimum and the maximum then whatever I could set this to be max minus min which would be the absolute number of elements and then I could just subtract the min at compile time off of each of them.
In fact, would you ever need to know?
Would you ever Sorry, I'm getting bit ahead of myself now. Would you ever need to run time know what the key is or was it always going to be I just need to check if A is pressed? Like could that be templated on that?
Do you see what I mean? Like when when would you ever be like like roll the dice and turn that number into a key and check if it sets? Like surely the code's always going to be if this specific key.
Oh, am I I'm probably giving Harand an absolute aneurysm doing all this, but like is that not better?
This has to be runtime, right? Because you don't know what the key event is going to be a priori cuz that's just going to pop out of the event handler, which might mean it doesn't work anyway. But this I think if you templated this it would be about as fast as it could be, right?
to check if it's if you allow the user to change them. Oh. Oh, what a great point. You're right. If the user remaps it, does that intriguing.
Okay. I had not considered that. And do I want to consider it now?
What does it mean for the user to remap it? So, if they want it to be the letter T instead of W, I would have to look that up and it would have to be dynamically resolved because I'm not going to recompile the game just for them with that key. Okay, fine. We'll keep it runtime.
That being that being said, I still feel like what I still I still don't understand how the counting numbers is going to work. So when I get key H here, right, how do I translate that into the index it's in within all the arrays without reflecting out again.
But I think what we can do is we can compress this space, right?
Uh hello Uh if min is greater than val min equals val right so that will give us the minmax range.
of the enum.
Okay. So then this will be constra auto uh size t uh const min max equals min return maxus min. So this will allow us size.
So, does that work?
Okay. And then what we can do is we can do constra or const expert auto to index UFPS key. Okay. Right.
And then do that that return to under lying k minus min. Right? So that will give us a zero index into the thing.
Right?
So then when we do set we do uh const auto auto index equals imple to index event key turn type on. Oh yes you're right. I mean it will it will do it but let's be explicit.
Okay.
Okay. And then we can get the ind. And then we need to do uh how do you set what's the bit twiddling math for setting a bit to a specific value?
Uh oh. Was there Oh, yes there was.
Sorry. So sorry I missed that. Uh thank you Jason. How very kind of you. And I'm sorry I nearly missed that. I'm super in the zone with this which is a terrible excuse. Uh C set bit to value. I don't want to toggle it. I don't want to flip it. I'm going to set it to a very specific value.
Uh, so I think I do map equals No, that's No, that'll only do I need to say if I'm setting or clearing it and then just do that on an if.
Yeah, but that sets it to what? Why? But what by set I mean set it to one or zero depending on what I want, right?
I think I might need to do just change the one.
Well, no, cuz zero.
No, that won't work, right? Because if I do, what you're saying is do that, right?
But if I change that to zero, zero shifted to the left is is always zero.
I think what you have to do is if event state equals key state is down then we do that else I want to do map I want to clear it right so uh and equals uh tilda one index.
We might be able to combine those, but I think that's what I want.
Uh thank you very much.
Uh and then I just do return map uh index That's all we need, right? I think that encapsulates. And then all we can do is we can just pump events into this, have them update whatever's going on, and then we can just query it to be super Oh, hang on a minute. No, I made a mistake here. Oh, no, wait a minute. No, two index automatically does adjust for it. That's fine.
I should probably write some tests for this. I might do that first thing next stream or uh off stream. But let's let's just wire this in just to check it doesn't explode.
So when we get a key event, see all this all this gubbins is going to go away, right? And we'll just do uh key map dot set uh arc.
Yeah, I think if if this doesn't go bang, then I might just write some tests because it's just it's just checking stuff, right?
Oh, is there a map set?
I don't often use bit map. You might be right. That might actually be better.
In fact, actually, does the square bracket work?
Uh, it probably doesn't return you like a weird proxy object like Bull does. You might be right. I think it is probably set.
There is set set bits to true or given value.
Set pause value. Nice, nice, nice, nice, nice. So what we can do there, we can do map set index uh event equals key state down. Nice.
Much easier. That's much nicer and it's constra so you know we can do all this all this runtime input handling at compile time.
Oh, that was fun. Bit reflection. Nice.
We're there. We're doing it. Uh, that crashed. That did go bang.
But why?
Uh, I got off by one error somewhere.
I had two items.
The maximum will be Yes.
This needs to be plus one ZU.
Uh, don't think I built that.
Yeah, you can find my do files. I think they're mostly up to date. I have been tweaking it a little bit recently.
Um, and they might not be pushed up, but most of it's there.
Nice.
Back in business.
Cool. Okay, I'll write some tests for that. That was I think that I don't know. I think that's kind of kind of nice. Uh I really wish this could be like a stood algo or something, but it's still got um template expansion in there. So, still did some meta some reflectioning. I'm getting [clears throat] I'm getting a little bit more into the mentality of reflection now. Like I'm starting to see I've started to recognize some of the patterns. I'm starting to think more about like what I can use it for. I starting to and problem I'm going to overuse it and everything because I think it's incredible. But I'm start I'm in that mindset now where I can like oh yeah I think I can solve that with reflection which is nice.
Um and stuff like that is so nice to be able to do that. like this is I think this is really I'm really pleased with this. This is a nice little fun bit C++ this.
Okay.
Didn't get very far though, did I? Key map. Uh key map.
Uh integrate integrate integrate into Jesus Christ. Main uh three. Let's do sorry I let's do some miserable merge cuz I have multiple branches in flight uh stream 48 I didn't want to rebase because I would lose the tags whereas normally I would rebase right stick that in the githole right cuz I fixed the build it was I fixed the CI build I had some issues with that so I fixed that on the old physics branch where I'd already branched off to do the character controller So, um, I had to merge those back in. And like I said, normally I would rebase, and it was a clean merge, so I probably would have cleanly rebased, but I risked losing some of the tags, which I don't want to do. So, that is more important. I probably should push those tags up. Anyway, that's pretty much all I've got, me thinks. Um, looks C++. Uh, other than that, thank you very much for uh choosing to spend your evening or your time with me. I very much appreciate it. Um, new video soon. I'm working about halfway through at the moment. It's it's C++ video, so not too much no reverse engineering or very minimal. So, uh, should be a bit of fun. But like it's just in this heat, like it's been a real slog.
Um, a real real slog. So, I'm slow chipping my way through it. Right. Anyway, I think that's all I've got. I'm have a beer. Thank you very much for spending your time with me. I very much appreciate it. Uh there's a discord. You should come along. It's great. Other than that, uh I'm planning on streaming Wednesday the but I am traveling a bit for work at the moment. So that all assumes I can get back in time. Other than that, I'll see you all and
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23

Steam and Xbox Just Dropped The Hammer On PlayStation
OhNoItsAlexx
9K views•2026-07-23

Americans Confused in Australia for 17 Minutes Straight
IWrocker
17K views•2026-07-23

LIVE NOW! Cellular Structure and Functions | Complete Cell Biology Lecture | Anatomy & Physiology
MukhtarAliyu-t7m
387 views•2026-07-23