Main

Olafur Waage C++ and Game Development Programming Talk

In this presentation, @olafurw explores the dynamic world of programming, focusing specifically on the versatile language of C++. Drawing from his extensive experience in the gaming industry and as a Senior Software Engineer, Olafur takes the audience on an engaging journey. During the presentation, Olafur generously shares code snippets and explained optimization techniques, providing practical insights and highlighting tools to improve code efficiency and performance. Blueprint of important topics: * Understanding L values and R values in C++ * Introduction to the std::move function * Demonstration of the copy constructor and move constructor * Efficiency and memory management in C++ * Importance of cache memory in performance optimization *Structuring data in memory for performance * Understanding the layout of code * CPU operations * Instruction packing and reordering * Triviality in C++ * Playing games programmatically * Deterministic games * Approval testing * Running games without graphics * Game loop Olafur Waage Github : https://github.com/olafurw #opencv #opencvpython #cmake #vcpkg #cplusplus 00:06 Introduction 07:48 Part1: Compiler explorer 16:07 Part 2 : Value Semantics 19:50 Constructors 20:45 std::move 32:45 Part 3: Cache 43:36 Cache Speed 55:40 Demo 1 59:25 Part 4 : Triviality 01:16:01 Return Value Optimization 1:20:58 Part 6: Misc 1:39:55 Game hacking 1:40:09 level 1 Doom 1:48:42 Level 2 Bejeweled 3 2:06:57 Level 3 VVVVVV 2:26:23 Github Links 2:26:54 End

Messi Sensei

22 hours ago

microphones here and I have microphone there I've never been so microphoned in my life but uh so I will yell and if you want me to yell more you can just tell me um yeah this applies so if you can't read the code up there that's the worst case scenario and I will explain also code that's fine uh so if you want to move forwards maybe not that many seats you can that's fine if you move around during the talk that's okay also that's fine and if you like this idea please steal it you don't even have
to credit me all right cool sold um so I'm going to be annoying for like a hour and a half I hope that's okay so um kind of tricky to find a name for this kind of talk because this is like I'm going to try to give you as much information as I know people are at different like programming levels some may be newer some maybe more like knowledgeable so It's tricky to find out like where should I put the line so I just it's miscellaneous things that I find neat about C++ if you all know them I'm ve
ry sorry if you don't and this is too much for you I'm also very sorry okay we sold good this is my face this is my name I'm a senior software developer a company called fact lines and if if you type those names on most social platforms I'm there you can find me and you can yell at me on the internet that's also pretty cool people do that so if you want to do that you can do that uh I work for a comp on fact lines we deal with the exciting world of uh sustainability in supplier networks and also
EU taxonomy in law so for you gaming people this is probably very exciting but hey I went from gaming to this so I mean this is interesting just differently um so maybe for some of you who is this person on stage this is a photo of me when I was younger um M hatb joke anybody no okay uh I worked in ATC systems so Air Traffic Control uh programming air traffic control systems for about a year and a half um that's also a very interesting business but for a completely different reason uh I'm in th
e Kake Tower if you ever been to Kake so we got to to experience the tower and and see all that kind of stuff and like those Classic Movies we had a because there was an incident happening at the airport while we were there so uh there were two US Jets they were doing a practice run and one of them broke in some way so they had to do an E he Landing so there's like a helicopter flying over and and doing all all sorts of things so after everything was landed and everybody's okay and safe the heli
copter did a buzz over the tower which was kind of like one of those movie moments and I'm like trying to find my phone like trying to record but no too late too late and yeah I was in the gaming industry for seven years uh plus one for you if you can find me in that photo I'm in that photo somewhere this is the uh so I was working for Ubisoft Ubisoft massive this is the release of the division one so this is part of the team and also like the other teams that were working on other games I was m
ore in the back end like all the systems that make all the games work so I usually say I worked in gaming I worked on all the games and also worked on none of the games because I wasn't directly on a game but I was basically for every game launch and all the backend systems and friends and invites and downloads and achievements and all this kind of stuff a lot of server stuff uh and I also I also do this once in a while uh so I was a consultant in Norway which is why I came here first and also d
o these kinds of talks uh so I I'm a professional Yeller I yell at people so it's been a theme for the last couple of years for me to have like one of those I don't know hipster philosophy quotes in the beginning of all talks so this is one of them before beginning a hunt it's wise to ask someone what you're looking for before you can begin looking for it right so before you start your schooling your education you need to ask someone what you should be learning and knowing and this is of course
we need a poo I recommend going looking for wi the Poo quotes because they're all philosophy quotes this is all just I I'm certain that if we need the poop book it's just a philosophy book for kids so yeah okay so ramble ramble ramble here's what's going to happen uh I'm going to ramble about C++ for a while so who here likes C++ yeah who here is an expert at C++ yeah I don't think anybody is I don't think BR na is uh I'm going to show you some features and I'm going to show you in my opinion so
me best practices uh I'm going to need something from you in turn in turn uh I want you to listen of course I want you to take stuff in like you do and uh I also want you to ignore my advice yes to a point so I want you to be here I want you to listen to see all these things and I also want you to say yep screw that guy right because there is a reason for this it's kind of a weird philos like philosophical no psychological reason for this thing because I want you to make mistakes I want you to m
ess up I kind of need you to make mistakes right why which one of the which one of these do you think is more effective I'm not going to do thing which I'm going to do why because some dude at school told me not to some dude at school told me this is not a good idea right or I'm not going to do thing why because I've been there I saw it I messed up and now I have an emotional connection to this right how often have you like like talk to your classmates and be like oh I had this bug let me tell y
ou a story and they go on a very emotional rant about that bug right and then the next time you spot the bug coming you're typing away you're doing something you're writing something and you're like oh wait I've been down this road it's a painful Road I shouldn't go there right so in order to be a a good programmer you do this about a thousand times for about 20 years and then you're okay right see okay so like yeah I I can show you cool things how many of you can remember all the cool things I
show you right but when you make mistakes then you be like ah I now have emotional connection so this is why like yeah we're going to have some fun I'm going to show you some neat things but hey I'm I'm entertainment right I'm I'm something to show you right I need you to make the mistakes so because you're in school this is the place to make mistakes right make them all you can there's a second thing I need from you I want you to be pragmatic this might apply to only some of you because some of
you are like like oh I want to be really nerdy about all this Tech stuff I'm going to show you some stuff if the stuff I show you is not a direct solution to your problems please ignore right this also applies to when you continue learning and learn about this new cool feature in the language or some other language right if it's not a direct solution to your problem please ignore because Tech yeah is neat I like Tech I like to be nerdy about tech stuff programming is neat guessing you're you're
know you know about this kind of stuff r space for Loops uh the idea is what is the generated code nothing because I have optimizations on there you go there you go the idea with the tool originally was to ask the question is this going to cause more code to run or less because this was a new feature in C+ 11 I think um and he was working in a high-speed trading firm and with a highspeed trading firm you need to squeeze out every single bite and every single cycle there's an interesting uh fun
fact about like these high high speed trading companies um at least for some of them uh because they need to do these analysis and and make these decisions and then once the correct decision has been made they make the trade and they do this like thousands of times a second but that means that 999 times out of the Thousand they say no to the trade and then one of the time they say yes and make the trade that means that the hot path of the code is the not trade and the cold path the stuff that's
not in the cache is yep no does not because bigo is about scaling like uh if you have data and then you're using um uh basically you have a list and you have a list of lists and you're checking both of them for every item and then every other item this is about um because when you're executing code and we'll go more into this in a bit later uh if you recently executed it it's in the cash of the CPU so the trade code is not recently in your cash because it's running so rarely that's the important
one right that's the thing that should run as fast as possible so for some of these firms they always do the trade but for some of the trades they want they want to say no to they just don't send them over the network so the code is always being executed but the network traffic is being blocked not the code traffic so there kind of these weird optimizations that people do so they are very interested in like is this versus like a regular like this one like this stuff is this better or worse am I
adding more code to what I'm running right so tool was originally made to go here and look at this Loop and see like oh is this better is this adding more or less code so here in this great part here that's a part of the loop we don't we don't have to go into this but if you want to look at assembly this will also explainly to you so if you Mouse over here it will tell you what it does very cool tool you can pick a from a compiler many many compilers pull a bunch of options so yeah this is a wo
nderful tool it will also optimize things for you if I do do like I can show you a quick thing [Music] uh so I make a vector uh it's empty has nothing in it or I can just do it like this and then I ask for the size so if I compile this I have a PCH of code right but if I optimize this no Cod because the compiler figures out that oh you're not actually using any of this and I know that this Vector is empty and you're asking for the size of it so just exor eax e ex is zero that's what it does xori
ng a number with itself gives nothing so that's where it goes we get it quicker so this is compiler Explorer this will be very useful I will show you I we will go back to this I will also show you a screenshot from this so we'll see that the other one is CPP insights you can just just get from there from clicking here this is another tool oops accept sure um the idea here with this tool is when you write code a lot of the code that you're writing um actually isn't the code that's then executed s
o again in this case this is not the code that's actually being executed this is the code that's being executed but things like if I go go back to the Coro X stuff I have this Loop over here and I return stuff if I run this you'll see that this isn't the code that was actually made because this a lot of this code here isn't the thing that compiler compiles first it get transformed into other code and then that code gets compiled so a range spaced for Loop is a regular for Loop but you get a begi
n and end iterator to the vector and then that's the one you're actually executing so usually what we call syntactic Sugar so this is convenience for this because who wants to write this right a lot of this is because it's like technically correct so this like G cxx normal rator like it doesn't a lot of this doesn't matter because this is technically what's out being outputed but yeah so this is what's interesting with this tool and we'll see a bit of it later okay any question so far any though
ts comments that jokes no cool y since uh that range for Loop compiled into that big block is that is the range face then less efficient than the normal one uh so the range one if we go back to this and run it here this is the same as if you would do U Auto begin is stuff. begin uh and then I think it is for it don't do anything if no you could do it is begin if it is not equal to stuff. end it t++ uh and then you would have to do uh something like this so you're not using numbers or indexes to
iterate through you're using iterators so I get the begin iterator from the vector and then I use that as the first one I think I do this um and I say as long as I'm not at the end iterator make the iterator go forwards right that's what this one here is doing you can see that's a a begin an end and an operator Plus+ here operator Plus+ yeah another question m is there any reason to use itat yes um iterators I I would recommend to use iterators outside of indexes um unless you actually know the
inside structure because going to the next element might not be the next one in the list so for example if you use a link list which I don't recommend you do but if you use a l link list or if you use a map for example the next one in line isn't the next one in memory right so it's the container that tells you that if you want the next one I know where it is because I'm the container and these are not expensive things absolutely not like again if you're thinking about like performance and if if
a Thing If expensive or not measure right and what they found like you think of the highspeed trading firm the thing that really wants things to be as fast as possible they use this because it doesn't matter it it turns out to be nothing right all right we good good go back to here so value semantics is the next part I want to talk about so let's talk a little bit about values stand up so have you been taught L values and R values right little bit so this is going to be a crass course good so th
ere are two ideas in C+ plus well there are more but let's start with two there's an R value and an L value an L value is something that has a memory address you can it's it's somewhere in Ram basically but an R value is something that is temporary either a literal like just the number 10 if you type the number 10 somewhere or it's an expression like a plus b a has a memory D B has a memory dust but the result of a a plus b is an R value because that's that idea is temporary it's going to go som
ewhere it's usually going to go to an L value but that idea is temporary same thing if you call a function the function has a value it's returning a value but the thing you're going to assign to the variable while it's alive there is an R value so again yeah we're talking about this the thing has a memory address is an L value and the thing on the so it's the left hand side and the right hand side thing it's a nice way of thinking about it there are more values and C FL nerds really argue about
these kinds of things there's like a a diagram of like a PR value and a GL value and like uh like no start with this thing with memory think that's temporary you're good for now so you we see the stuff on the bottom I hope so uh I have a class I'm going to call it loud because it's a loud class oh yeah for those who I don't know how new people are stru and classes same thing there's no difference uh so I have a class called Loud and I want to make it call A and B and then the class itself has a
Constructor and instructor and when I construct the value I just print out loud and then what the value is and when I construct it I say loud with what the value was all right so these classes are actually very helpful for you to learn how the language works because when a Constructor is called and when a Destructor is called it will print out so you can see the order of things that are happening okay so who can guess the order of this application we make A1 and B2 so interaction what's going to
happen yep construct out will yep in what order will it destruct uh that's I don't know so you're right in the first part so we say loud one loud two but then we distruct two and then destruct one so when objects are created they are created in order but when they are destructed so when the scope exits that they live in they will destruct in reverse order yeah that's because they're on the stack yeah they're on the stack so you push onto the stack and then you pop from the stack this is also he
lpful because two is created later and it might use loud one right so if you want to destruct it you want to destruct the usage of loud two first and then loud one so that can be helpful as well okay everybody got this cool so I'm actually calling that Constructor with an R value so I'm saying that the line one uh A1 a in B2 the one there is an R value that then goes into the stru The Constructor loud in value and that then it turns into an L value and then I'm using it right so we have these di
fferent value categories why don't we give the control to the programmer of which value category we want to use so this matters when objects are be being created from like not that they are being constructed this is matters when they're being created from other objects if I'm constructing from an from an R value I might not create uh I might not care too much but this matters when objects are being created from other objects okay so who here sort of stood move oh we have scattering of hands so t
his is a a funky function that yeah even even people who call them self experts use wrong sometimes so for many it's a mysterious function but it's actually pretty boring because the classic joke for St move is that St move doesn't move that's the that's the classic one good one liner there like another joke about C++ is C++ is really good at naming things wrong or getting the wrong initial name for things so if you see a thing that's called something that's probably not like vector why is a dyn
amic array a vector like for me a vector is like a direction especially for you like game people like that's a direction like yeah doesn't make sense so stood move we can think of it as a signal to the compiler that the value you gave it is going to expire soon okay we aren't going to use it going forward and whoever is going to receive the value can steal it and anybody who is trying to use the value afterwards it's been moved that's not allowed so this is why it's called move semantics or valu
e semantics so the only thing St move does is that it turns a value into an R value see I love that ah I love those moments love those moments or to be more precise it makes an x value I think of it as an R value but if you want to be technical it's called an x value or expiring value because it technically still has a memory address it's still there but it's going to expire soon so uh this is CPP reference a screenshot from that um I recommend that site if you're searching for anything it's ver
y techy it's very like standard e and it can be like it's it's a an acquired taste to try to read it and this is like a nice screenshot from it because it's very like text heavy and and but uh yeah good so using a value after it's been used with stood move it's not recommended right I like to think of it as like a zombie it used to be a human it still kind of looks like a human but please don't interact with it that's not like yeah don't do that uh and again the techie unless otherwise specified
all standard Library objects that have been moved from are placed in a valid but unspecified State they say it's still the object is still there but yeah don't we don't make any guarantees about the the state of the object uh again meaning the objects class in variance hold and preconditions and that kind of stuff so you can still kind of interact with it but don't trust anything that is that it's uh doing so don't trust the zombie so okay so you so demos too many things open uh here what I say
part two example one and I have the terminal part two example one so here I have the loud class and I also have so I have in line uh five I have the Constructor we just print out loud in line eight I have the copy Constructor you should have seen that one I think so the idea here is just I'm given another class of my same type I would like to copy whatever they have they will still be alive and then I will copy whatever they're doing and then in line 12 we have a move Constructor so the move Co
nstructor is what I'm being given is temporary and I'm allowed to steal from it that's the idea the the thing that I I'm given is going to expire it's not going to live anymore uh it's very morbid to say talk about it this way it's G to Die the thing is uh so I'm I'm allowed to do whatever I want right uh and then I have the the the structor and then I have a value so I have the same before I have line 24 I have A1 line 26 I just make a value and I give it over uh in line 29 I'm making C by by c
opying B and in line 30 I'm making d by moving from a right so a I'm saying a is going to expire so basically anything like using a here is not recommended because it's been moved from so that's the idea so if I run this terminal example one so who can guess who wants who wants to be brave and make a guess what what will IP put here if I can I can show you so we're making a loud a then in 27 we make a b 29 we make a c and 30 we make a d nobody Brave ah shame here we go so I can keep it like this
so we make a loud one we make a loud two so that's 24 and 26 that's we saw before uh then we have 29 we copy loud two because C is equal to B so we're copying it in 30 we move loud one that's the move here and then we're destructing well we're destructing in a weird order at least looks weird right we say loud one one is destructed first because that's D because it copied from a right and then the l two loud two because there's copies of B and C and then loud one which is the a from before welc
ome and I can show you that if I when I move it I can say l value is equal to zero because it's going to expire I can do whatever I want with it so if I run this you see that a has not been modified because D was allowed to do whatever it wants with a because we are telling the compiler move whatever a is into D and after that a is gone right that's the only thing you kind of need to know about move and kind of these move semantics and again it's not move syntax it's not like it's semantics and
that's the important bit here uh I think I also had y theoretically does this mean that if we have like several classes and we do what is not recommended and have several of them then uh have like the the x value Constructor using a does that mean if we change a using one of those Constructors we'll change the a value in every single verion it depends on the order it's being executed but you can think of if I go back to here once this line here has been executed then you cannot trust a whatever
a is is unspecified right so if anybody else if I say loud uh we it the E yeah and not if I do this this is not allowed like it will compile but this is not what you want this is not the idea you want because again now after it's been moved you're doing it with a zombie okay the same thing here oh not this whatever this is same thing here this looks fine I think it will compile as well but again you're dealing with the zombie once it's been moved don't trust it there might be stuff there there m
ight be values it might look okay but it might work differently between compilers it might do different things uh if you just change the surrounding code so again this is not why it's move syntax it's semantics it's once you've done this don't trust what's there right so that's more of the idea and I can show you a more concrete example I'm GNA not going to keep that because that's not good what if instead of a value like I I had an INT as a value right what if I have a vector which is a standar
d container so they have implemented all this stuff for us so again I have value uh I'm just resizing I'm just using the size of the vector as the as the value for myself that's fine uh I have the The Constructor I have the copy Constructor so here in the copy I'm actually copying the vector I have a vector of some values I'm copying it to another one but here because this is the move Constructor I'm allowed to behave differently because the stuff on the outside is going to go away so I can do d
ifferent things because here in the copy Constructor I'm not like as you see it's a const I'm not allowed to change L which came from the outside I'm only getting a copy only getting a reference to it a con reference to it so I can copy which is expensive but if I know that whoever is on the outside doesn't need this anymore I can steal it so a values. swap is actually very efficient because the only thing it's doing is swapping out the pointers inside there's no copying done you're actually get
ting the actual Vector from the outside so if you have a vector of one thing or a vector of a million things this is the same size so if we're talking about the Big O for example this is Big O one so this is O of n this is o1 because it doesn't matter how big the vector is swap is always the same size the same speed okay and this is the same thing here we get the same thing okay any thoughts yep seems good and useful if you're trying to write efficient code right because that means you don't hav
e to copy the that means you don't have to run the Constructor for some object to I will show you more cool tricks later there's more cool tricks with this later and like you're you're in the industry of making games there are parts of your game that really need to be be efficient like this thing here here whatever you're doing like the main Loop or some like you have 16 milliseconds it needs to be really efficient so you need to think about these kinds of like you need to design it in a way whe
re you're taking advantage of all this kind of stuff right but there are other parts of the code that doesn't need to finish within those 60 milliseconds like like a button being clicked or or some background task or whatever is happening right like adding up an experience value like okay fine but like initializing a new level or uh dynamically loading stuff based on where you are in the level right that needs to be really fast so you need to think of these things okay cool want to see more cool
stuff yeah good I don't have any no I'm kidding so cash um this is going to be more of a rambly rambly rent so let me see modern CPU not only have memory caches but they have multiple layers of memory caches and the idea is simple let's put some of the data we think the program is going to use closer to where it's being used and when I say closer I mean yeah physically closer right so I have some data in Ram I think I'm going to use this bit of data let's put it near the CPU it's the idea is as
simple as that right so you'll have Ram but then there's usually a shared level three cache that's used by the whole machine then each CPU or core might have a smaller level two cache and then an even smaller and even closer level one cache and these are in like kilobytes okay so how do we know what data the program is going to use and this is the a classic example of of of ram you have a list of things list of values uh so imagine this is Ram we have some values there and this is your CPU and
within the CPU there are other slots which are called registers and these are the slots that are actually using the value so when you if you looked at the assembly code there was like an add something something where you're loading that from is from the register it's not from the Ram or even the cash it's always from the register so it always needs to go to the register do the work move from the register move into the register do the work right that's your work desk the cach is the next desk ove
r right so I would like to load this five cool I put it in the register from Ram I do some work to it turn it into a one and then put it back into RAM right cool so from CPU to Ram it's about 100 NCS roughly I'll show you more numbers later on but if you can think of that as like 100 n seconds so what if we have a level one cache is actually closer to the CPU and what computers actually do this is called locality of reference when you want to load the number six it does not load just the number
six it loads a block of memory around number six right because it's likely that after you've used the number six there you would like to use number seven after that so think of Loops think of arrays and vectors it's a classic like I'm going to make a for Loop I'm going to use value one and then when I'm done with that I'm going to use the second value in the in the vector so once you've loaded the first one the second third fourth fifth whatever are probably already in cash so you pay for the fi
rst one which is why things like linked lists are not great because you load the first one the computer will load a bunch of stuff around it then you want to access the next one it's somewhere else in memory you don't know where it is so it will load that so you always take a cash Miss it's called and when we load six and do whatever work we want to do and then we want to load seven and seven is already there that's called a cash hit it's there so we load all of them in I put five in I do some w
ork to it I put it in the cache and I save it there and then I would like to load six but ah it's already there cool I can do something to it so L1 is about an NC these are tiny numbers right this is not much y don't um you can do tricks if you know exactly what CPU you will be loading right if you're on exactly this CPU with this instruction set and compiling with this compiler yeah you can do tricks absolutely and again this is the nerdy nerdy bit of it like oh what what if this thing what if
that thing but think of this generally as like I want stuff to be next to each other right yep you say oh yeah yeah yeah I'm just giving you a scale yeah all of these numbers are probably outdated and like this if I would measure this number would not be the same from one run to another as well so just to give you a sensor scale there was a joke by one of my professors that kept saying if I could make a PC out of just cash I would but you can't that's just a just a size thing I would I would rec
ommend looking up like IBM PC diagrams of like seeing cuz they are literally like you have the core and you have everything and the cash is like in the core it's like there so it's just part of the circuitry of the actual machine and usually if you're like buying a machine and it will tell you like oh the cash size is 8 Meg or whatever that's usually what you hear nowadays that's L3 usually don't see L1 and two uh specified unless you go into like the specs then you'll see L1 and two because the
the L3 is the one they can sell like oh it size 16 Megs of cash like okay cool yeah okay yeah and then you have 32k 256k 8K like it's just sense of scale like the level one is very small but still like it's pretty and usually some machines also have like a a separate data cach and a separate instruction cach like your code is in one cach and your data is in another cash I think AMD does that a lot okay oh yeah some numbers just a sens of scale uh yeah you have CPUs and then the cash is just the
re L2 is also somewhere there and then three is shared between all of them kind of the if you want a mental model this is fine this will get you pretty far okay so why does this matter again we're doing game stuff here's a zombie talk about zombies before and this zombie has a position X and Y they're somewhere on the grid and I have some code I have a for Loop here I'm moving the zombies around and and another joke is it's X movement and Y movement so they all move the same right no okay fine f
ine so if we think of like we have memory some memory addresses and we can think that 142 and 12 is one zombie 11 and 19 is one zombie 521 and 72 is another zombie so we have three zombies there because that's how this is laid out if you if you have a vector or an array of these this class they're just right next to each other like literally and there's no space there's no extra junk there's no stuff right it's just there okay but then you're like ah it's really nice if zombies have health right
that's kind of need zombies to have health because we're going to shoot the zombies and then right because then you're pushing you see the 11 so now in in CX 100 we have the health right so we have the same position and now we have the health so you that class is taking up more space even though in that very important loop we're never using the health and if we think about the locality of reference back if I would like to load 0x 092 to get the x value I'm loading Into Cash 96 and 100 because t
hey are next to it so I am technically loading the health Into Cash every single time and then you keep growing the class right you have a you have the model or the AI controller or whatever right you keep doing this y yeah or you can it sometimes a thing I see sometimes in games is you might have this class and this is fine like it's the zombie but then you want to do zombie movement like oh I would like to process all of the zombies and make them do the movement instead of using this class to
do the movement you might take the hit of copying the X and Y values to A siie movement class that only has the X and Y values then use that class to do the movement and then take the hit of copying the data over back because once you start copying it over that's going to go into cache it's actually pretty quick then you're going to do the loop that you that you've measured this slow like you've noticed that this is slow you do the thing then you copy the data back over yeah here's the thing no
there's another trick that people sometimes do if they have a linked list of things it is just an example of why the cash matters so much right that I seen examples where if you have a linked list of like a million things or something and you want to Loop through the linked list and then you might say like ah we need to sort the linked list and to sort the link list you need to go through all the elements and and do all this kind of jumping through hoops like a lot of cast misses that are happen
ing when you're sorting a l link list it's faster in some cases to take the link list copy it over to a vector sort the vector and make a new linked list then to sort the linked list because the cash has such an effect on this whole thing like again we go back to if I can make a my computer just cash I would right so this is the counterintuitive thing but again if I go back to the things I've been saying measure if you don't see if this takes a nanc and nobody cares and this is instant leave it
alone right but if you see that the problem is here the problem is that this class is too too heavy and we're only using this then you can try copying the data over using only that copying it back and you can't see an improvement on that y cool so cast is fast and I'm Bound by programmer law to show you this again these are just number for scale so don't take exactly the numbers as as as as goel but L1 cast reference half an N L2 is seven m m reference 100 sending 1 kiloby over a gigb network 10
,000 uh reading 4K from a solid state disc 150,000 reading one mag sequentially 250 read one one mag from a a dis a million disc seek 10 million and sending a packet from California to Netherlands and then back 150 million so 150 milliseconds okay again scale think of scale right and humans are really bad at this because how much bigger is a L2 C Cast reference versus as sending a packet right can you can you see the scale because if an L1 cast reference is a heartbeat so I'm going to scale thin
gs up right so now it's a half a second okay that means an L2 is 7 seconds or like a stretch main memory reference is 100 seconds you're going to make coffee so would you rather have a heartbeat reading a value every heartbeat versus reading a value and you have to make coffee every time you read a value right sending a a one kilobyte packet that's 3 hours you can watch Oppenheimer recent references here huh read 4K from a disc that's 42 hours it's a week can getaway right read one MEC 70 hours
read one me from an SSD that's 277 hours that's a twoe vacation versus a heartbeat right disc seek 115 days that's a semester plus a twoe vacation that's what you've been doing now all semester plus a twoe vacation if you want to read from disk which you do every day you always reading from dis right but that's just showing you how fast the L1 cash reference is sending a packet that's four years nine months you can earn a degree you can start a family you can start your career that's sending one
packet right so again humans are really bad at this so if if there's one thing I want you to take away cash good brand bad right good so again instead of every time you want to read a value you have to make a coffee and then you're allowed to read the value but you can otherwise always read it right I mean you do this every day like if I if if every time I wanted to to switch a slide I would have to walk over there right versus doing it just here this is the important bit but that also means th
at you need to know the structure of your code the layout of your code what is where right and again and again if you're not seeing the issue it's fine just measure it always measure it yeah we want stuff in our cast we also want to be aware of our memory is laid out yeah what I said so here's another visualization of this kind of stuff I have a zombie I would like to move the zombie there it's usually done by moving X and Y right and this is the zombie value and there's somewhere in Ram uh so I
'm going to show you some assembly assembly is so I would like to load memory add us 100 into a and a is one of the registers the has this hypothetical CPU cool that's an instruction we can do that and then okay there supposed to one ex there yeah and then I modify it and I write it back okay then I want to load four I increment it by one and I store it so I load one of four in I add one to it and I store a in 104 right and then it increments by one so we have this bit of RAM and we have a bunch
of zombies somewhere right so if you're doing this in a loop again and again and again you're loading the number adding one to it storing it you're loading the number adding one to it storing it that's what the assembly like if you writing it this out assembly you can think of it like this this is the thing that's happening right so what if I could reorder it but that doesn't work because I'm always loading into a and in into a that's not great so I need to load into different registers okay so
first I load everything I need to load load from 100 104 108 112 okay cool I have all my data and then I want to add all the numbers cool I've done the work I want to load things back because now you group things into this is the thing that takes time because this is the memory load so again if you think of the scale because the work is basically instant and again this is expensive so you've group the expensive the cheap and the expensive okay so this is not just a blank this is a blank piece o
f paper if you want to make a hole with a hole punch who's used a hole punch recently that's the thing I have used like oh you're in school okay fine yeah sure you make people do hole punches that's not fair so you make one hole punch right you make the machine and do the one hole punch and you use two like this right right right no okay you might use if you want to do two you might use a two like this right okay cool so you bring the item you bring the tool you do the work and then you put it b
ack where's the analogy here right because what if you want to do this and use the first tool you have to use a tool and then use a tool right but what if you had this tool you bring the paper you do one clunk you've done all of them who sees where I'm going with this yeah yeah so your CPUs are kind of neat so instead of doing this we load and lay out the data so I lay out both the values I'm going to load for and also the operation I'm going to do so I'm going to load from 100 into X and I also
want to load the value one into X1 so I basically laid them out as the data the operation the data the operation right and then I do hold punch and then I store the values back and this if you have a zombie you have an X and Y I would like to go through all the zombies and and add up all the movement like the loop that I'm talking about this is sometimes the assembly you'll get so you're doing the load you're doing the expensive thing and then the operation is one operation and then the store i
s one store so if people have been talking about like MMX or uh yeah it's called xmm there these are features in modern CPUs where it can the compiler can figure out that the work that you're doing is similar work right next to each other so the compiler will not create the initial assembly it will figure out that oh you're actually doing this kind of operation of loading performing the same operation on a list of things it will try to pack these things together to do one operation on it that's
also the another benefit of using data structures that are next to each other it's not only the cast that you're bending benefiting from you're also benefiting from the compiler saying oh that means that I can line the them all up together and do one whole punch right so yeah do that okay how are we on time good only one hour we're here for four right no no I don't have content for four hours uh so part three part two right this usually what movies do right so CPU so what the CPU is then doing a
nd this is very again very generalized they need to fetch the instruction that you want to do you need to decode that line of assembly that you have they need to execute that line of assembly whatever that code bit of bit of Machinery needs to happen you need to then access the memory to either save or store or that kind of thing and then you to write back the value that you you had so fetching decoding execution memory access right back this is the thing that the CPU does for just one line of a
ssembly every time so if I want to add five into a we have the instructions and we have units of time so I'm even more abstract this just unit of time so we need to fetch that cost of one unit cost us one unit of time I need to then decode that's another unit of time execute write memory right right so it took us five units of time to do this so if I want to then save whatever a is into P do I then need another five units of time and then another right that means that the fetch part of the CPU i
s Bored for four cycles and then it gets to do one work then it's boarded for four Cycles so instead they pack them together this is also why like when people talk about executing code on your CPU that things are done in a strange order because because while it's like while we're decoding A5 we're fetching at ba while we're executing A5 we're decoding ba right thankfully when we're executing ba we're writing stuff so like the order is weird there uh and then we can have a third one and so forth
and so forth so this usually called instruction packing I think it's called you want things to be as tight like there's no gaps because what can happen is you can have this is usually called a bubble so there was a stall or some other bit of insruction happened like it's never this clean it's never this beautiful right even if your CPU is at 100% it's not like this right and what it can also then do is it can reorder it can figure out that ah because uh ba a b depends on a I can actually do C9 b
efore ba because there's no dependency in there so you can you can create this dependency hierarchy of all the execution graphs and whatever it's doing and find out that oh this bit of code can run when whenever because it doesn't depend on anything and this bit of code depends on some other stuff so that needs to run first and then I need to run my code right so it's just a li mental model for you and then you have that in a package that's a core and then you have many cores and then they can d
o their own thing right so again another mental model for you okay part three example one most asleep yep there we go that was ah yes this one this is a fun one um if I go here so here's my caveat for some of these examples um I've only tested them to be true I don't know if they work all the time because with a lot of these like optimization things they might do one thing on one machine and then I'm doing it on another machine they might behave differently so Cav attempt or that kind of stuff u
m but here's the idea I have a vector of data and data is a bunch of integers and then the value that I want and then a bunch of integers so it's just some stuff before and stuff after so I'm kind of polluting the cache right and then I reserve a bunch of things I Loop through and save the value and then I have a clock and I would like to sum up the value I like add them up together so in the loop I'm only accessing value but because of the cache I am always loading these these arrays here as we
ll so they're always being loaded Into Cash uh the CPU might spot what I'm doing because there's another type of optimization where uh it's not loading the thing you have in Cache I think it's called spatial uh uh don't remember the second part spatial because noticing that I'm reading a value and then then I'm reading a value 11 Parts over and then 21 and then 31 so I might know no is that and then load those in cash but we'll see uh so it's at the clock I'm just taking the time that it takes t
o load so if I run this took 45 milliseconds let's run it a couple of times 41 44 and then I can comment out this yeah so H so instead of taking 45 milliseconds to do the work it took 2 milliseconds to do the same work so it's a bit of difference again this is an example exaggerated example but this can impact your code that this kind of of behavior can sneak in and and make your thing slower um okay I run that again with the thing in 43 yeah because I'm always loading the thing okay any questio
ns thoughts cash good cash good yes cash very good so this can be boiled down to a few tips so generally favored data structures that are aligned lineary in memory array and vector and again I say generally favor okay generally avoid data structures that are not like link lists okay and accessing one data member of a class will also load some of the other data members into the cash okay it's like a tldr good thoughts no that means you're all experts right yeah um this is a a more of a a passion
thing for me this can matter this is not as big as cash but this can matter and this is more of like an interesting C+ plus thing uh so again this is not as big as cash but this is interesting so there's a technical term within C++ that talks about triviality uh it can affect you and not that many think about it or talk about it um and it does not mean trivial as simple it does not mean like easy to read or easy to understand it it is a technical word within the specification so it only means so
mething within the standard oh I had a demo immediately all right fine fine yes this one okay so most of this code doesn't matter it's like a timing code this is the thing so I have a user and a user has a account ID as a profile URL Company ID email and password right this a classic like uh some data class right and then the only thing I have is a Destructor that does nothing seems fine right Destructor does nothing I mean what can it hurt for shadowing right then I create an array of users cre
ate some users I Loop through this is just for timing purposes and then I would like to copy this Vector this Vector that I created here from the outside I'd like to copy it and then do some work I I would like uh do stuff right but I don't I don't need to do stuff for to demo this so this is just to prevent optimiz uh the compiler from optimizing this away because I don't want to have like a bunch of code that does the examples so think of it as I made a vector and then I copied it right that's
common thing right we we have some data I would like to use it I'm going to copy it maybe because it's coming from another thread or something I'm copying it and then I'm going to use it and then I'm just printing out the timing right good so let's go to part four example one right example one so this takes so the average copy time is 0.006 right that's per copy and that's the average I've taken all of them average them out I've done this like a million times or something so the average copy is
not that much but again this is per copy so every time you're doing it you're taking one of these hits let's take out the destructor so 0.02 instead of 0.06 that's weird right that the structure didn't do anything why what's happening H what Chang yeah I I took out the destructor yeah but theor doesn't do anything weird so ah I'm going to do the whole thing there okay that's fine uh uh uh yeah here's another one uh I have a player right the player is a The Constructor has some items has gold He
alth whatever has damages and positions and whatever I do Collision checks I make a bunch of players I Loop through all of them I check if they're colliding and I count how many are colliding that's the only thing I'm doing uh and then I have damage type which is something I have an item which is something and a random position which is random right good uh uh uh this should take I think it took 11 seconds see how good I am at remembering 8 seconds okay oh yeah no this is example of the cach sor
ry it should up been the other one so I'm going to take out everything so we just have this there you go yep yep yeah yeah this is this example should have been in the other one other yeah yeah there's a mistake on my end this example should have been in part three but I'm just showing it now so so we can have it uh so with this one example one let's go back to that one What's Happening Here is triviality is the idea that um you can take a class and if you're copying it to another place you are
allowed to use mem copy which is a very fast copy function they will take the bites the actual just zeros and ones from this location and copy them over over to the other place and a class needs to be trivial which is a certain specification for this to matter and by just adding a Destructor or a copy Constructor or a copy assignment operator for example um the class is no longer trivial and you cannot copy it with mem copy because the compiler sees those functions there and if those functions a
re there it they have to call them so we can no longer take the actual zeros and ones actual leral zeros and ones and just copy them to another location in memory we have to construct every object and call all of the functions because the class is no longer trivial and there's a bunch of uh classes even like standard Library classes that will make your class no longer trivial like if you have a stood string then your class is no longer trivial if you have a vector and your class is no longer tri
vial if you have ins and arrays then your class is Trivial and there are ways to test if you want to go into that maybe later um there is uh a check to check if um you can check if a class is Trivial at compil them so you can check for those things but this can matter if you have a class like a data class that is being copied all over the place and and being moved around your your codebase all of the time and it has like a string or a Destructor or something like extra then you can have a big pe
rformance it and we actually had an a performance h and a thing like this where we had a class that just had two it in it which were the two people talking in a conversation and anytime people were talking these IDs were copied over all over the place and someone added as a Destructor to that class which wasn't needed and the system went down because the performance hit was so high that yeah you brought the system down by doing this so this can matter it's not a big as you saw from the timing th
ing it's not a like a factor of two or whatever but it's it can matter so if you can keep yourself trivial make it toal yep let's say that in our we have to have for some y uh how about if we make a new class with the rest of the and our main class has a point to that class yeah you can do that yeah yeah there's an there's an EDM as well it's called pimple where the implementation and the interface you use are different uh so you can have that if if and again measure uh where you can have like t
he heavy thing the thing that's actually costly to copy have that Su P trivial and then you can have a pointer to it or a vector of it or something like that that's fine like you're taking the hit on the main class but the actual copy is fine yep yep the thing with Vector is because it's U it's a pointer and two or three iterators that's the only thing inside a vector then it points to somewhere else it needs to have a Destructor to be able to delete that dynamic memory and because it has the st
ructor it can't be trivial but array it's just it's just a list of things right after each other like uh an array of int two is the same as having two ins and someone said that um you actually gain value from having uh if you want to have an array of two things you actually gain information because now you also know the size because the size is baked into the class it's not in the type that's another benefit you have yeah you get the size for free so another General hint if you want a list of so
mething and you know the size don't use Vector use array and if you want to use a vector and you kind of know the size like oh it's like it's going to be 100 or 500 right you roughly know the size uh Reserve that memory like do like actually do like if I yeah like I'm doing here instead of resize do Reserve like this uh because if you don't do that the array the vector is empty and then you add one item so it allocates the one item and then you want to add the second item it creates a new Vector
internally with size of two copies the first item into the new one deletes that and makes the space for the second one and then when you want to make the third one it makes a new one with four copies the two over makes a space for the third one and then when you add the fourth one it's free when you want to add the fifth one it makes a new Vector of size eight copies the stuff over so by just adding five items you've actually made four vectors so even if you like roughly know like uh it's at le
ast 10 right it probably in the thousands but it's at least 10 right making a reserve a little bit it can actually benefit you again measure measure this is I want to resize yeah okay cool that was trivial trivial moving data we are good and yeah and not that kind of move um generally when you're write in code you would like to isolate work into functions right yeah yeah you should uh it improves readability testability and general sanity of everybody around you don't think that writing a functi
on cost you anything if you're going to use it once it's still okay to write a function I have never seen a a actual big performance uh thing that says like oh it was actually costly to have a function like I've once seen kind of an example but but that was like a dynamic like allocation of a function that wasn't the calling of a function so think that calling a function is expensive um so that means that sometimes you create the data in the function and then return it out right you can you can
think of this code right so I have Main and I have a function called create value and then I have a value and I return it right good general idea and I have this function create value um the result is 10 but if the input put is more than 10 I increment those together and return the results this is just some like the function doesn't matter it's just some some logic right if something I return a different value than the other value right everybody good good so what if it's an array because this t
his nobody worries about this yeah you just get the inth out right it's four bites nobody cares what if it's an array so I'm doing the same thing I I have a function instead of an in I have an array of 10 things if it's greater than one I change the first value to increment okay and then I return the result is this bad is this good this this fast this is slow what's your instinct when you see this what's you're like oh no or is it like that's fine yeah person personally what about impersonally u
m I would imagine that the if statement prevents the comp from paging information yeah again this is a good good cut feeling because when people see this they're like oh yeah not a problem because it's the for those who don't know how return values are done that it's a it's just a slot that's allocated in in in the stack and then this is written into that slot so we have an array you just the slot is bigger it's just more you write into okay so you you huh bigger MH or sometimes he can be like t
his slot is a pointer that points to another point in the stack and yeah it's but mental model it's not bigger uh so okay so what if I print out so here in the C outline I'm printing out the memory address of result and here I'm repenting out the memory address of value so what do you see in this result out there tell me tell me what's happening here any thoughts yeah yeah it's the same memory address why why is the array in there the same memory address as the array out there that's weird becau
se even if even if it like would happen to be in the same place when you call a function there's more stuff on the stack that you have to pop so they wouldn't align up it's because in the way I wrote this function the compiler noticed that the return value is always the same variable so instead of creating that that variable up there at the top it doesn't create it it uses this one so when you call the function when I say result zero input I'm not modifying the array up there I'm modifying this
one right that's weird right that's only because the only way to return out of this function is is with the same variable so there's only going to be one variable that goes out of this function and it only one variable that is going to be assigned to so why bother making that variable up there let's make it out here so this breaks if I do this if in this case it should be an empty array but in the other case it should be array with stuff in it now you see there's a different memory address becau
se it's not the same variable being returned so it's called return value optimization or sometimes called copy elision C compilers are allowed to do all sorts of optimizations and one that can impact how you write your code is called copy elision or return value optimization so in general the C+ plus standard allows compiler to perform any optimization providing the resulting executable exhibits the same observable Behavior as if all the requirements have been fulfilled it's called the as if rul
e as if so there are many types of rvo return value optimization but the one you would probably hit the most is called nvo named return value optimization and a quick way to remember it is if the same variable is the only thing used in a return statement of a function okay so in this case do we have rvo and rvo yes no two hands three hands yeah yeah we do because it's always the same variable that's being returned do we have an rvo yeah yeah you you can modify it so if in this case if I create a
a vector and I put stuff into the vector but then something happens if something it doesn't matter what it is so if something happens I want to back out I want to undo I want to give the user back an empty Vector right you can still clear it that's fine you can modify it all you want as long as the same variable is in the return value that's fine so who has used the St optional St optional so St optional is basically like it's called a maybe type so data is some class we have but optional is a
container that contains our class or maybe not yeah so instead of returning a a null or a zero or whatever you can return stood optional and then you can ask on the outside is there a value here and then you can get the value out this is very nice this is very and all the same optimizations happen here so instead of a vector of things you can have a thing or maybe not the thing right and this is very good because again we make a a data we create a data but then and oops something happened then I
want to return a null optional I want to return an empty yeah is that similar to yeah yeah very similar and you can ask like has value and get the value out and yeah so here we don't have n rvo because we in one return we return a stent null op which is some other thing and then the other one we turn result so we don't have it so instead you can do this you set the the value but then then oops I I I regret you can say reset and then return out so you then get a null out so there is a caveat tho
ugh uh be careful with returning references so if you have a value then you create a new variable which is a reference to another one and that's the one you use throughout the thing it doesn't work you to create a variable and use that don't use the references because they can break it um this only works because we're replacing the return value slot it's return value optimization it doesn't work with the references so here for example I have the same idea I have an array and I'm printing out the
memory address and then I have an array with some stuff in it and then I have a result which is a reference to the array the data array and I print out those two memory addresses so those two refer to the same memory address but on the outside I don't get that one because the compiler sees that oh what they're actually returning out is result which is a reference so I'm not allowed to do it okay makes sense and and the the memory model you can have is like it's return value optimization so you
might think like okay that doesn't impact me but if you use a structured bindings with a structured binding if you have a pair you can break out the pair into two variables so in this case you say like hey we have an X I print out the memory add address I I return X and then I to the data this also doesn't work because a structured binding you make a variable and then you get a reference to the two things back from break everybody well rested four more hours to go right no so I have a little bit
of left here uh and then I I have a talk of them previously which is more gaming related which is way more silly so we're going to have a bit more fun afterwards and uh we'll do some game hacking who's ready for that yeah yay hacking so um this is like more misk where I couldn't like find because all of this have been like like like please think of cash please think of like triviality and think of your classes and like I've been going over like this kind of stuff there are other hints and tips
and tricks that couldn't like fit into a whole category so this are like yeah MK um try to use standard Library containers and classes when you can uh it might again we have the the pragmatic brain and the nerdy brain like the nerdy brain wants to implement Vector again the nerdy brain wants to create their own like sorting algorithm or whatever but yeah try to use the standard Library containers and classes uh when you can uh try to use the stack and not the Heap when you can again if you have
to use the Heap that's fine for dynamic memory but try to use the stack when you can uh if you need to use dynamically allocated memory use things like stood vector and stood unique pointer who has used unique pointer yeah good yeah yeah so okay so you've been learning about normal pointers unique pointer cleans up the memory after itself so you don't have memory leaks and there's no cost of uh like it's just same cost as allocating the same as using it but you just get the clean up for free uh
and you use uh St move to move it around if you want to give it to a class I can show you um there's another another one called share pointer uh share pointer counts how many other instances have um access to it and when the counter reaches zero when it wants to be destructed then it deletes the memory but only use sharp pointer if you're actually sharing like between threads or between things like if you're actually sharing ing the data between things then you can use share pointer try to use u
nique pointer when you can uh so here's for example here make unique I want to make unique in 20 so I make a unique pointer this is a pointer on the Heap I have some data and then I want to use the data I want to send the unique pointer into that function I need to say it to move into the function because that's how unique pointer works is only one scope is allowed to own the data at a time so if I want to set it somewhere to another scope like a function I need to move it over there but that al
so means because we talked about move earlier now using data after this in result line is not recommended because this function now owns the data and when the function exits then the data is deleted not when the not when the main exits and then I can use the data or do something with it and I can D reference it like a normal pointer okay and then you can't use data data here it's already gone okay so this is very very useful uh so I'm guessing you've been learning about like new or I don't know
malok what you been learning yeah uh don't matter M yourself let the language structures do that for you like use unique pointer use Vector use like those are allocating memory for you Constructors and destructors are your friend and if a theu is causing problems like in a loop then move the object one scope higher because the structor cost time they take time to to execute like any code you need to deallocate the memory but if that is costing you time like you you're allocating the memory you'r
e doing some work and then in at the end of the loop you're deallocating the memory and if that is the part that's costing you time move it out of the loop so the work in the loop is the work that is being used um who has heard of and place back in a function cuz you have a vector you do push back right so there's also a function called imp Place back so if I have a player XR coordinate I have a vector of players and you can do this of course players push back and I can make a player right I can
construct a player with the 10 and 20 this works you can say and place back player 2030 but that's not what in place back is for in place back is to do this where calling in place back is actually calling the Constructor of the function so instead of because you might be creating the value here so if this is expensive you're creating it here and then you're copying it into the vector so you're doing it twice like you're creating the R value and then copying it over why not just create created i
n place M place again it's awful name I don't like it but so it's being created in the vector when it's being added so you don't have to worry about that allocation so that's a useful one that's why there's two of them this push back which is you take an existing value usually an L value and you copy it in and place back you construct it there yes same like the players push back player 1020 and players in place back 2030 it's the same thing th this here acts like the Constructor there's a there'
s a compiler not a compiler there's a language trick there's a I don't remember what it's called U there's a thing within the library where you can call the Constructor of the object or you can make it look like the you calling the Constructor of the object so they look the same that was what you were thinking of right no okay but yeah and place back creating it in place um so I have a thing I save some data okay I have a Constructor I have some data the number and I I create it there right seem
s normal so far right and then I do this inline in operator parenthesis and then another parenthesis for the value and then in that function I return data plus value this is called a call Operator you can have an addition operator you can all sorts of operator overloading that's happening there's also the call Operator which means I can use thing this object like a function okay so you can create these if you have a class and you would like to use the class like a function you can overload the c
all Operator okay so what's interesting about this well who has used lambas in C++ yeah so here I have a lamba it's a thing I have the so lampda you have the capture I'm capturing data from the outside this is the argument to the Lambda and then Theta and then I call the thing right because that's how lambas are implemented it's a class that's overloading the call operator and then I have the Constructor and I have data this is the same thing so this is Lambda this is how it's implemented this i
s why tools like cpv insights are important is they allow you to see see the underlying thing that's happening so Lambda isn't anything magical it's just it creates this kind of thing it creates a class called Lambda 418 we can figure out what it's called 418 you can't actually call it and name it but uh because it's on line four and 18 characters in that's it okay uh so a couple of years ago I asked Twitter to give programming students some advice I got 709 replies everyone from students themse
lves to the principal software engineer at C plus for Google you want to hear some advice no okay no so don't worry they were nice so become obsessed with testing your software revent finding ways to write code verify how code should behave do it at every layer can write pervasive fast and reliable tests and run them continuously all right fight for Simplicity it' be a huge fight every time whenever you do it would be a benefit if you win the wins will usually be invisible and uncelebrated but t
hey are worth it be intentional about the levels of obstruction in your in your design don't design components to be reusable in general if you can't see them being reused again pragmatism when designing for reusability constrain your solution don't make it too General right that the class that can do everything like no they can do the two things play have fun do stupid things follow advice explore your own ways and also ignore advice yes but yeah reflect and think and why does it work so yeah m
ake mistakes please read code this is a good one too cuz yeah you're going to have to read a lot of code in your life best way to do good design through seeing lots of different ways how to do things don't worry about architecture at first analysis paralysis paralysis is real uh you'll don't know what good code is After experiencing a lot of bad code he says different code but I know he means bad code uh try to make the simplest solution that could possibly work don't consider efficiency Orly qu
anitative characteristics except small and dead simple code get it working and then so again measure measure measure just get it out there and then measure because so often I've been writing code I'm like oh I'm worried about this kind of optimization and then I just try it and like no it just it doesn't matter doesn't actually matter so do top down coding on the way down and bottom up coding on the way back up this more of a joke I recommend his talks tony1 he when he talks he doesn't talk ofte
n at conferences he has a lot of videos on YouTube uh he's very strange cuz he doesn't like doing the same talk twice so once when he had to do the same talk twice he made the whole talk rhyming so the whole talk is one big poem yeah he's great uh yeah so and then I of course did some analysis um 131 out of the 763 tweets uh talk about people so 17% of all the advice are about humans and people and peers and friends and like collaborating uh 10% % are about basically like learning or practicing
13 of them will literally never stop learning uh 27 talked about mistakes and failing 29 talked about fear or being afraid and scared 34 talked about tech and algorithms and focusing on the big picture and 33 are about personal health it's uh get sleep eat eat healthy take care of your body even if you feel fine so yeah and you can if you want to look at the thing it's just all over program advice it should be there yeah it's from a few years ago it's almost five years ago now when Twitter was r
elevant yeah yeah when it was Twitter back in my day yeah it's my face again okay so before I go on to the silly talk any questions thoughts comments rants that jokes no you're experts in everything now right yeah good Okay who wants to be silly who wants to do some game hacking yeah good good uh how much time yeah I think we do it I might go over a bit fast but uh we'll see uh nobody cares nobody cares oh yeah I like this one too people say nothing is impossible but I do nothing every day which
is again wi the pool yeah I have a questioning like us instead of the right uh I came here I was at uib and there are uh programming features in like the efficient algorithm subject taught us to care more about like the uh Big O time of a of your code instead of the micro optimalization which seems to be your approach for this thought right yeah so there was T to use he inad stack because on the heat you can access immediately like directly instead of having to go through the entire stack no yo
u can you can access the stack immediately you can access the stack immediately that's same time there's no difference if you have a stack or Heap they're all the same Ram it's all Al Ram stack is here grows down Heap is here grows up it's all in Ram and the program scope is here so if you want to access the value you can access it the same way uh the only the only thing with the stack is the stack is limited in size so it only grows to a certain size and then you can that's why you have stuck o
verflow because it's a certain size but the Heap can grow and grow and grow because it can grow from here and then it can access memory elsewhere but uh it the reason why I'm focusing on this is this is the stuff I keep seeing like thinking if algorithm is Big O of N2 or if it's Big O of n log n or something like how like I think I've like done Big O analysis at work like three times but the amount of times I've seen this kind of stuff break systems because they're not thought about is way more
way way more so again measure and like yeah don't use silly algorithms but like the hot path of your Loop like the thing that's running again and again and again versus like oh I'm I'm loading something and I'm doing it optimally like what's the time scale here how often are you loading the optimal code versus how often is your very silly little Loop that's incrementing the the where the player is moving how often is that running right another way to think about it is there was a talk from a few
years ago that thought like think of your the execution of all your code as like a bunch of like zeros and ones and a zero is the hot path is being run which is the one uh zero is the hot path is not being run one is your hot path is being run like the main Loop that's always looping and think of the grand scale of of that all the zeros and ones how how many are them how many are zero how many are one it's mostly one right most of the time your code is running it's running that little Loop that
's happening so if you can optimize that that might be your biggest gain right another think we thinking about it is thinking of entropy take those zeros and ones and use a wind siip on it how well is it zipped because if it it sips together like 90% that means that it's 90% one or the same information so it's always the same thing happening so think of it that way if you code it's a mix of things happening okay yeah sure think of what you can optimize but most of it is that Loop so especially i
n games because in game yeah you have objects you need to do something to the object you need to take the state and then build the commands to draw it and then send the command out take the objects update the objects build the commands send the mod right you're doing all the same thing is that Big O of what like no it's O of n going through the objects or when building the commands s they month right you might do some like path finding okay because in the update of the state of the object you mi
ght do some pathfinding and that might be like okay you need to think about am I using a star am I using optimizations right what am I using so there you might think about it but generally no okay good so who am I nobody cares so a good way good way to describe this talk is a bit of silly fun uh some real life use cases um this is for like a general audience so you might think about this kind of stuff but yeah uh yeah this might apply to you as well um I've done a previous talk this is like from
a couple years ago that was way more serious than this talk and it was about how humans learn information and how humans remember things and in that talk I said unfortunately in this case there's considerable evidence in many situations that this strategy the one-hour lecture is rather poor in 1971 they found that lectures like this to learn things is not good 71 think about that and we're still doing it a lecture May Inspire it might motivate it might inform but it rarely fulfills the principl
e for Effective learning it is certainly inadequate for developing high level skills what are we doing right what are we doing we've known this since the 70s yeah so I cannot in good consents make a talk after I found that out trying to teach you something right so instead I made a silly talk which is this talk so warning I will do stuff to video games in this talk if you're going to do similar stuff to video games I'm asking nicely only do this to single player non online games okay Pinky Promi
se yes thank you it's not something crazy but I feel I need to add this warning so playing games is great but I'm also a programmer how can I add these two things together well you can make games which is what I did okay but now what because games are just applications so what can we do to control those applications remotely what are the different challenges you'll face when trying to interact with complex software and can this be applied to interacting with other software so because we're talki
ng about games we have to have game terminology this is level one what if the game I would like to play programmatically which is what I want to do supports playing it programmatically right out the box what game do you think that is yeah yeah programming games programmatically mean that the way direct the game is cod I can code and I can take the output of the code which can be some bytes or whatever I can give those to the game and the game runs it Doom yes Doom supports playing it programmati
cally kind of but yeah so who's played Doom anybody yeah there we go I don't need to explain doom doom is a 1993 first person shooter and it also kind of redefined a few aspect of about video games the look at field online multiplayer game modification and video game speedr running who who here watches speedr running yeah good crowd I like this crowd when I do this at like normal conferences there's like two people so I cannot go over everything but I'm going to look at the last one because when
ever there's a timer people try to be the best people try to be the fastest that's just human psychology and doom is no exception so anytime you finish a level you'll get this how many kills how many items how many secrets and the time it took you to beat the level and the time from the developer and I love the screenshot because they finished the level by finding all the items and all the secrets by killing nothing yeah it's a good one so here it took one minute and 16 seconds and the developer
took 2 minutes and 45 cool and people are still trying to this day they're still trying to make Doom go faster so the first level is finished in 8 seconds in in 2019 and you can see those files there's files over there E1 M1 P89 8897 zip and what about that file right it can't be a video file because the game came out in 9093 so if you download these files you notice that they're actually pretty small few kilobytes they're called demo files LMP for lump but they're usually called demo files and
they contain what input the player pressed every single frame of the game so here's the header of the file the version of the game what vers what the expansion pack and other flags that might affect the thing and then for every frame every line of that file is are you pressing forward to backwards are you strafing are you turning and any interaction you're doing every file every line go again and again and again and then if I record my play through and then I give it to you you play it what you
're actually just playing is you're doing the inputs again my inputs so there's a tool called XD and here are the lines moving forward strafing Etc turning left and I can then play out the game you can see if I back up you can see all the values changing direction position that kind of thing it's kind of cool so this is possible because Doom is deterministic Doom is a single threaded application where every single entity on the map patiently Waits their turn always in the same order some more co
de it's Doom source code if you want to read game source code is weird it's very weird to look at and when they want to do something random they just pick a number from this list so if I want to do something random I get the first number zero cool and I do whatever that is some enemy wants to do something random they get the next number eight they do something with that that everything in the system is using this list and they're always using this index it's a single threed application and the r
andomness is the same so if I press forward on this Frame and I press shoot on the next frame I will pick a number 109 and that will be the damage I did whatever that means but if I press shoot on the frame after I might get a different random number this is why the frame by frame matters so then index that's incremented and the next entity will get the random number and the entity doesn't just mean like enemies it can be like the door making a sound or if you shoot the wall it will have like a
little puff of smoke how the puff of smoke smoke looks it's different so what if you wanted to take doom and convert it to C+ Plus or some other language so Doom is in C originally so this was started by Jason Turner have you do you who knows C++ weekly on YouTube oh you need to watch C weekly I recommend that it's like bite-sized videos about one C first topic like 5 10 minutes talk about one thing and he's an expert in that field so it was started by Jason Turner to convert Doom to C plus and
then continued with uh from ptia o and then I was dragged into that as well so if you're taking a big code base like doom and you're changing things and you're modifying things how do you know that the changes you've made haven't broken in the game because okay you could you could play the game you could write some tests but how do you know how do you know know well we have the tool in our hands right now so there's a thing called approval testing it's a methodology where you focus on the output
of the code that you're running right think of it like a GI div so the program outputs something you write the new version you get the output put you do the diff is the diff the same because if it's the same then you're likely to have the same application so this is useful when you want to do a complete rewrite or if the original Source isn't available so you can run Doom demos so they will run to completion and you can ask it to give the start output as a text file so you'll get this little th
ing E1 M1 map one took 51 seconds killed uh five six enemies found this many items found this many secrets so the demo played the game and this was the result if I then go and change the game refactor it change the function something right and I run it again I get the same results I'm more safe in knowing that it's okay right and then if I have a lot of these i' be more I I'd feel better about the changes that I made so so if I play this Dem on new version I should get the same results another t
idbit the game doesn't need to render on the screen because as you know rendering is just the it's just the visualization of the state so we can add a flag to the game where we just don't run the graphics we don't even need the graphics card We Run the game in the command command line this also means that I can run the game as fast as possible because we just need the demo to run through because the game is a the terministic system it's always going to give us the same results I can just run it
as fast as possible so even it's a six-minute demo it's going to run immediately so putting one and one together we can play the game using a known good version collect a bunch of startat outputs save those start output into a folder with all the diffs Run the game with all the flags get the output do a a diff of the output which means I can run to many kit actions so here is a build of the game running on auntu Windows 64 Macos 11 windows 32bit and I have all the builds the demo check is here t
ook zero seconds because it's immediate it passed everything is okay here's how it looks for those who play Doom get like the Doom shareware yep and then all green then I can go again I can more do more changes do the build see if everything's okay do more changes to the build right cool yeah one more two more yes converting it to plus because you can see so a lot of pointers lot of manual memory management sorry so once more more games level two what if the game you want to play doesn't have th
e support that Doom does B who's play B who's played Candy Crush it's kind of the same game yeah so but J is a match three game you pick a gem move it left right up or down and you can join them together if you get a three of a kind you get a bonus you get a four of a kind yeah etc etc after match has been made those gems drop they go away and the board drops down simple enough right so I would like to make an application that plays P dual 3 for me automatically so we make that yeah so the plan
of action is pretty simple first we need to figure out what gem is where then we need to pick a good move from that state of the board we need to move that Gem and then repeat right who's ready yes so it's a C++ project C++ C make VC packets and open CV open CV is used to grab the the screen and then I use some image analysis open CV is a computer vision Library if you haven't used that it's a very good one pretty old one but it's pretty good so what s is where the game actually look looks like
this if you're playing it it's like low res but uh I'll make the screens speaker for you so each gem is 64x 64 pixels we know that that's the same that means that and the board is always the same size and the board generally doesn't move so it's always the same place so it's a nice little static screen that means that at 261 pixels and 37 pixels that's where the board starts so I can offset from there to try to detect what gem is where from that information I know where each cell is I might not
know what gem it is but I know where in the picture it is actual pixels but how do I know that this is a green gem so any solutions yeah know you knowx thatx Rel time for that's exactly what I did let's take the center pixel of the gem and check the RGB colors yeah there's a problem with that if you click the gem it spins so the center value changes damn doesn't work yeah Che for only once check it for once yeah so you like have a state there's another problem in that is when things move and lik
e resolving you don't know when they're done CU if you match at the bottom which is matching at the top it takes longer to match at the bottom so you have to like wait and sit but yeah you could um so since I'm using open CV to do the pixel detection and that kind of stuff let's use it's a computer vision Library they have a thing called template matching so you can give it a template a photo and then you say where in another photo is this template that seems to be exactly the thing right so her
e I have a photo of Messi playing some football and then where in the bigger picture is Messi's face so where the brightest white is that's where the picture is so Messi is here or Messi is here and since this is statistics like where the other values are it's less likely where Messi is right so you pick the highest one and that's the center right seems perfect right because we have these shapes we have these colors like this is unique for us so this would be great uh so I have a b and I have th
e matching who can see the problem yep oh ah yeah so I kept it open and the game was giving me a hint it's like hey if you move the yellow one that should be good so it gave us like a little arrow around the yellow to be like hey you should move this one which changed the template for the red one above it so that doesn't work but we have the threshold I can adjust how how aggressive do you want to be at at finding it so then if I change the threshold it I play the game a little bit more it's thi
nk thinks this orange one which is like glowing special whatever it thinks that one is the red one and no matter what kind of threshold adjustment and changes I did I never found any good ones and then I was trying to figure out like why like this should be easy like they're so separate from each other the issue is a lot of these algorithms make the templates black and white which is our main advantage our main advantage is that there's colors the shapes are some of them are different but some a
re like kind of similar right so that's kind of ruins the whole thing for us this why this these things are happening so let's go to back to the idea of color or to the idea of H instead of RGB we can use H saturation and value so H for those don't know it's basically where on the color wheel you're pointing to right are you in the greenish area or you in the purplish area right so and then also I grab a 32x 32 Center area of the gem and I ask op CV for the average color of that area so when I c
lick it it's turning but the average color isn't changing that much and it's still pointing in the greenish area right so I check against where it's pointing I also use the RGB to help like differentiate but uh yeah so I went through and I played the game and I checked I printed out the Hue saturation value for all the gems and all the situations under all conditions they're like on fire and glowing and whatever yeah and I have a chart of where their minimum Hue is and their maximum Hue is for e
very color have the blue orange red green Etc and you see for example the green one is really separate from all the others the orange and the yellow kind of overlap but this should be okay the blue one is kind of safe but the uh the red and the purple kind of overlap sometimes but we can use the RGB to help us there as well to disambiguate so I made a really complicated function that takes in the hug saturation value the average color and I ask if the Hue is over 85 and less than 115 then you ar
e blue if the Hue is yada yada I I've trimmed the function a little bit but uh this is generally what it is because then I can disambiguate if you're here I know you're red if you're here I know you're orange and this works even if you click the thing cool that was one where's number two yeah they account for coverups that change the color you can actually see that in a bit uh because it does move but making a fail move only takes like a half a second second so then it can if it's like moving or
or messing up yeah problem so when I was doing the um like there's a thing I didn't show in the chart that I also I know that purple 146 149 is purple but purple shiny from 121 to 144 is also shiny uh so it's like I'm taking slices out I know that for a fact that if you're like this you're either purple purple shiny which might not be all purple shiny purple shiny H might be other values but then I start after I do purple there I might do red and red fire and then I do the rest of purple shiny
because I know red is like this so I slice it like that so that works there's couple of cases where it's like it's not sure and there's some cases where it like loops around cuz it thinks it's two colors but it's good enough but yeah I get the values so pick a good move what does it mean to be a good move and again initially I was thinking like cool algorithm deep learning minmax something cool like that but after the whole color F go I thought like hey let's try something let's try something si
mple wow very dry a let's try something simp simple there we go and I actually was so I just started playing the game which is a great excuse to start just playing the game and I played the game for a couple hours and uh I had an idea I still haven't recommended it it's good there aren't actually that many moves like if you think of move as in like this these this is the setup like there are gems of a color here there's another Gem of the same color somewhere else and I want to move it in a dire
ction like the colors can change but the action itself there AR that many so can we just map them out so I made the system where we have ABC and there's an X which is the thing we don't want so I have I want to move C towards AB so we have ABC so in this case the yellow one is in the way I want to move the C over right so I make a a vector a pattern so I have a so everything the origin is a then B is x - one C is x - 3 it's a horizontal 3 I and the solution is what is the vector operation I want
to do so I want to plus one to the 3 so the three is minus two so that means I need to move in that direction I give it an ID and I give it a value the value is uh then used if I have a bunch of solutions because when you look at the whole board you might get more than one solution I want to pick the high value one so I can sort the list and then I put it back onto the list so here I'm using a place back wrong look at that ah nobody's perfect and here's another one more complicated so I have AP
and E and then C there in the corner I want to move C in so it's a corner five I all the points and the C is minus one in the X Direction and I give that a higher value because if I detect this one and also the other ones I want to do this one cuz this gives more points and then here's the last one and there's 32 of them which AR that many and also nice round number right so which move should I pick because on the board we might have many well you have a high value move so we're going to pick t
hat one but what if you have two moves that are same let's say the only ones we have here are these two the green one and the the purple one which one of the should I pick y yeah because when you move the lower one it creates more incidental moves that might happen because once they drop down and settle you might get more matches on the way down cool now it's time to move the gem and this is the simplest one there's a Windows SDK called Mouse input and I basically want a function that looks like
this I want to click somewhere and I want to go somewhere else click and drag start an XY end an XY so um for fun if you want a function that converts from absolute to screen coordinates you have to write a function like this I'm just showing you to because I'm going to use it a few times but I'm just converting coordinates so I get the position of where my where I should be where I should click on I click I move no I yeah I move it there I click I get the position of where I want to go I move
it there I release that's the function go to the place click the mouse button down find out where I'm supposed to go go there release the mouse button simple again this is like a com interface very common in Windows not very nice so who wants to see a demo yeah demo so I have the game here I not played for 17 hours play new game good let's see if it works no not open the solution sorry is it in no update that's weird fun who didn't pray to the to the demog Gods always always the case let me see
while I'm looking at this any thoughts questions all succeeded maybe I can just where is this uh no I had it uh already built so that was the thing we see [Music] B out I think build deug is it there yeah B old there it is see so sometimes it does this it's very fun so to fix that let it finish that's another thing if you're debuging stuff like this um hey got it okay now it goes um yeah well some sometimes hit a look like that um if you are debugging a code like this and you let it run and it's
code that takes over the mouse you can't do anything I can't run I can't move the mouse because the mouse is being moved by windows so I have to wait so you have to have like a kill switch or something to to do that one more time there you go so you need to run I so I have it now for the demo mode is I only let it run like a 100 times or something like that uh because otherwise it just yeah I I think because so for the last demo let it I think I know why it's doing that uh the thing is it's too
fast that's the issue and also you can see that P allows you to move two at once uh yeah yeah yeah yeah okay uh yeah because last time I did the demo I uh someone asked in the audience what happens if I don't because there's another reveal I make it sleep for like half a second or like a few milliseconds because it actually is too fast it's too good at this if I build it again it's too good kind of uh let me see second there we go less confused l confused good because yeah if you look at the re
sult it's it's technically correct yeah yeah not always perfect but good yeah prior it rather line is there a move yeah there's a move thereally it should probably prior horizontally it it should have picked this one the green one yeah yeah so why exactly is this happen I'm not sure so here I had to do it quickly because otherwise it text the mouse over but yeah good all right so again you see it's perfect it's awesome it's the best but yeah okay last level level three who's ready yes yes yeah w
hat if the game has none of this yeah it's not a simple game it's not a simple State it's not a board you can look at so V who's played this yeah you're probably the the audience that has most hands up that I've ever done for Theo usually like one person like yeah I've heard about it yeah I think I've seen huh I think I've seen this G yeah it's a good game you should play it so it's called VV VV VV V I'll just call it V for now because yeah so for those who haven't seen it it's a platformer game
uh with the gimmick of you don't jump you flip the gravity that's the kind of kind of the idea this kind of little demo GI so you can there's like temporary platforms you flip the of course Spike bad Spike always bad and you collect these shin Chinese and you also have to save your crew mates in space and yeah fun game um so V does not have buil-in support for giving the game inputs uh it does not have a simple game state in that sense because we're moving between levels and that like a can do
col detection and that kind of stuff uh and it's actually pretty fast-paced and you need to be pretty accurate not like the b b demo where you can go in a loop forever right so the idea right was to be hacker man was to do some cool hacking stuff what ended up happening is I was more this guy right so you kind of know this you know the game Loop games applications you get the user input again this is a talk for General audience so um so if you caveat with a game Loop getting the input from the u
ser there might be no input uh when you update the state the updating the state can take a long time it also can be multi- threadit and when you're drawing that can also be multi R it so you know this right who doesn't know this good they thought you well good this doesn't take time it depends it depends yeah you have 60 milliseconds if you want to have a 60 FPS game this one of the ways to do it is this at least once every 60 milliseconds if you want to have a a game State updating every 60 UH
60 uh frames and then you can draw as often as you can that's one way to do it you can also do VC and all these kinds of other things and an example you don't have to go through this you have a loop you have a timer I can process the input and if I owe time so if I if I'm in debt if I haven't updated the game state in the past 16 milliseconds that means I owe time I can update the game State and decrement how much I owe and then I try to draw as often as I can so this is just one way to do it so
that means that your game State always updates at a fixed pace and when you draw as often as you can you can also have Dynamic here but this then the issue here is that depend that it depends on the computer how fast the computer is and you don't want that good so uh V actually has a few advantages and why I picked the game for this project uh it's open source so you can go and check if you want to look at the code for it this is part of the game Loop if you want to look at that U that volatile
always annoys me but it's there it's very strange volatile uh they also have a delay for there for Sleep uh it's single threaded as well which makes the project a bit easier to work with and it has a bunch of customization options there's like an advanced options here and I can if I tole it to 30 FPS in 30 FPS the mode uh the game runs a input check for the keyboard input for the user it runs a game State update and then it runs a draw then it does one one input input check one update one draw
always which is really beneficial for what we want to do so here's my plan launch the game as a post child process of some loader so the game the memory of the game is inside the loader so the loader owns the memory and then inject a dll into the game process hook the function that creates a d text device in the game get the address of that device intercept the game's draw call to call our draw call first and then before each frame we send our keyboard inputs sounds fun we came hacker man yeah s
o in the loop I'm hooking here in the draw call so I intercept the games draw call function to send and keyboard inputs to inputs to Windows we could hook here we could hook in the processing of the input but we actually want to draw some nice deug UI so it's good to be in the draw section because we have the actual rendering device so we can put our debug UI on top of the game which is really nice so some of you might think wait that's illegal I really like how high dep this image is because th
is is a meme from like 2006 or five something it's from Red versus Blue yeah and like red versus blue was never this high def back in the day so someone remade this yeah but yeah this is illegal windows will say operation did not complete successfully because the file contains a virus yes I cannot run this even in the command line here's the thing I cannot run this in release mode I can run this in debug mode it only works in debug mode apparently another hooking tool that you can use Works in r
elease mode but the one I have for the demo uh only works in debug so you will see the debug version but that's fine but yeah when you are working with this kind of stuff and if you're Googling for this kind of stuff most of the help and most of the people who are helping you with this kind of problems you have are cheating forums like Counterstrike aot forums and that kind of stuff so yeah uh I use DeTour for Microsoft that's a library to help you uh basically re uh rewrite the functions to whe
re they go for those who haven't done this kind of stuff the idea is that you have a function that you would like to call someone else has a function the idea is that you will get the memory address of their function and you store that memory address you re basically rewrite where that memory address should point to that function memory address point it to your function you can do stuff here you call their function you can do stuff here and then you return the original value so it's a detour so
your function is called you still do the work that was originally asked off from the function so it doesn't it looks like the function was called but your function was called you did some other stuff and then you called the function it's called a detour uh for those who have't work with DLS uh if you make a dll you don't have a main you have a dll main and the reason why there's a different main is that the dll main can be called multiple times and you have the reason of why it's being called so
you can initialize some values I can initialize the detours Library the reason could be when you're being attached so the dll is being attached to a process I can do some work I can call and re rewrite their function and when I'm being detached I can put the function back to make it look like I wasn't there so yeah and like with any research and any any kind of stuff like this you of course go and see has anybody done this and a lot of people have done this but I found this project by Tom gasco
in from many years ago 12 years ago where they were basically only overloading the draw call in this library and this was the basis for a lot code U that I had and it says whoops forgot to commit a new class at the top yeah I I know that feeling so thank you Tom so I have a class called hook process when that's starts uh I will get the name of the the dll that I would like to inject and I would the mode of the process that I would like to start and I started suspended and if a process is started
suspended it's there the memory is there but it is not allowed to execute yet so it just sits there uh I create the process with those commands and I inject the dll so detour create process with dll again why I use the library because it's just a on line call uh I then resume the game the game can call and then I wait for the game to exit and then I can have some helpful output so this is the loader that's kind of the only thing it does starts the game uh paused injects a dll the dll gets to ru
n gets to do its thing once the D has done its thing the game is resumed so the game can can continue so what is the dll so when I'm being attached to the game I call hook create device just a function called hook create device and if you're doing this kind of stuff message box is a really helpful thing because sometimes you can't debug sometimes you can't put debug Flags or or because it's another process being run so and it's also kind of tricky to do printf because the dll is doing the printf
like where is that going to come out so you can do message box pop up a max box so you can know when things are happening uh and I don't do anything for the detach because I don't here so when that runs I can get a message box that says hello hook so I'm now hooked into the game so when the game starts it wants to create a d taex device and once the game has created their D taex device they'll use it to draw stuff to the screen so I want them to create my direct text device so when I start I cr
eate a directex device just to get where it is in memory so I will get actually the virtual function table of the datex device which is that that nice d d reference there and then I release the device because I just need to know where in memory the direct text device is because I want to rewrite where the functions are so I know who who has played with virtual function tables yeah so if you have have a class that is a basically like a dynamic class that can have different U basically different f
unctions based on uh yeah different functions and different functions what you call it in the beginning of the class they have a virtual function table which is where the function is in memory because the function isn't on the class the function is somewhere else so this is the virtual function table is in the beginning of the class and I know at offset 16 bytes and offset 42 bytes that's where the create device and end scene functions are so I can change them so I store the original create devi
ce which is somewhere in that memory and I say that my create device is there instead so the memory that had the create device object now points to my function so when the game wants to create a device they call my function so we've spawn the game we attach the DL sorry we hooked the create device and now when the game calls create device they call our function and then then we need to rewrite the end scene function because we need to create the device first be before we can overwrite the end sc
ene function so this is the create device function uh I actually just call the original create device uh function because I want the the device to be created so I want to be nice uh some error I again I rewrite back the create device so if anybody else is creating a device that's okay and then I overwrite I get the virtual function table again I overwrite I store the original end scene and I overwrite the end scene with mine so now on this specific device that the game created I have my end scen
e function so game is running and game rendering hooked so now every time the the game wants to render something on the screen my function is called first so to wrap it up not much left what time is it yeah uh here's my n scene function it just get a device I call the original n scene function and I can count frames I can have a variable that counts the frames and then I can say on frame one so we have the same Windows API thing like before but instead of mouse we have the keyboard now I press t
he space bar and on frame two I release the space bar and this works so I can exactly frame by frame tell the game to do specific things which means I can create a very complicated format so I read some file data from a file I have data like this so big s means I press the S button on the keyboard little s i release the S button from the keyboard right so in frame two I press s on frame three I release s on frame eight I press D on frame nine I release d right and these frames I don't do anythin
g and then for each one of them I press those actions I do those actions so that means I can play V frame by frame once to see demo two people okay yay so I have the loader oh we have sound again mhm yes which means if I I can slow the game down because what if I put a sleep function in the draw call you can see in the corner I'm on frame whatever this is how many milliseconds the frame is and I can slow it down even further one frame at a time this is how I built the file to play it because I k
now that on frame 216 I should do something right I had a question in the back at a hand somewhere yeah so is this the process of yes yeah no not that I know of uh and a lot of these I talk a bit about a bit later uh a lot of these use emulators and in the emulator they can do the stepbystep frame by frame thing so the emulator support it but this game isn't running an emulator so I can't do that um you could make machine learning we could yeah because the output file is just an output file and
I can also Run the game as fast as I want because it's again deterministic so here's the one that gets a tricket so I love this one uh yeah because yeah yeah so uh you're in game development I'm guessing you've heard of coyote time right when you leave a platform you can still jump a frame or two after you left the platform so here we are and oh okay pretty close up not good enough and then no it's okay and then I love this one the last one because so the game allows you two frames after you lef
t the platform to still jump which is pretty good uh and this is for the people who have played the game uh there's a challenge in the game called called v v v which is because you can't jump you need to flip the gravity that means that you're like on the behest of whatever is above you but what if above you it's a big Gauntlet of spikes that you have to go all the way up top and then all the way back down just to get over a little little uh little box because you have and all the way back down
uh and then just because there's one box is there because it can't jump over it one more time and then yeah good cool so let me see yeah uh it's a bit thing at the end yeah games are neat it's fun to play with them um this is a silly thing when you have an application and you don't have the source code there's always way to interact with it automatically AKA you can still test so this has been a talk about test you should write more tests cuz you can uh for those curious uh tasvideos.org for to
speedruns for those who are interested in that kind of stuff um they have a lot of emulators and plays and and games you can play with uh for people who are interested in Doom there's a d DSD archive Doom speed demos archive uh a lot of the edge cases for Doom I actually got from them like demons infighting and that kind of quirky to so if you're curious about that DD archive there's also the classic Doom archive uh if you want to look at that kind of stuff uh the code it's all on kup if you wan
t to look at it so my kup we hook my K up vual player and the Doom is on Patricia's kup yep no yeah level four then here you go to get you going because these are good questions because you're like wait what if what if like so yeah good to be curious that's my face again there you go thank go [Applause] I need I need five questions no 10 questions no any questions that means you're experts you know all this good yeah I have one question regarding the example you show with par doing the fing and
execution uh is that roughly what a thread is uh yeah yeah yeah so and also there there's talks of like that you have a CPU and they have many cores and cores can also have threads uh it's just the idea that like there's an there's a thread of execution that is happening so if you make a thread um there's always never a guarantee like where it's run it's just the idea that it's being run somewhere right um sometimes when you make multi- thread applications it's nice that you're always on the sam
e thread but sometimes also you don't care you just need your data to be running somewhere right yeah um what is meant with like the L1 and L2 cach being let's see if I can get a size they're actually in the CPU it's in the the secetary yeah part of the secetary is the cas so they're they're actually

Comments