Old Man Yapping: The Real Job of a Programmer

Поділитися
Вставка
  • Опубліковано 13 січ 2025

КОМЕНТАРІ • 91

  • @sway6911
    @sway6911 23 дні тому +13

    "I was thinking about the problem instead of solving it..." the best quotes always come from some guy gesturing with his beer.

    • @cdarklock
      @cdarklock  23 дні тому +3

      Programmers love problems. We like to just jump in them and wallow around, but that doesn't actually accomplish anything.

    • @skilletpan5674
      @skilletpan5674 23 дні тому +1

      Coding is easy. Doing it in a way that isn't horribly inefficient or convoluted is hard.

    • @cdarklock
      @cdarklock  23 дні тому

      @@skilletpan5674 Absolutely. Striking the balance between them is the REAL problem.

  • @tasnimulhasan196
    @tasnimulhasan196 23 дні тому +23

    nice posters dawg

  • @vadiks20032
    @vadiks20032 22 дні тому +1

    3:18 i think we should notify God gameobject of it and magnetize the player to experience for laughs! imagine the slingshots
    also, i've went through similar problem once and i somehow came up with the idea that its easeir for me for player object to do it rather than object itself. i don't know why. i think i even made player call the collider's script function, but in opposite way its probably more optimized? but in example with player and EXP you wouldn't really have to call the experience orb's function, you'd just read the amount of xp it gives and add to player

    • @vadiks20032
      @vadiks20032 22 дні тому +1

      also IMO the real job of a (beginner) programmer is also figuring out the libaries and tools they use. like, a game engine creator is supposed to know either opengl, directx, or vulkan (in this case also gotta know how different GPU's work and differ). windows.h, xcb,x11,wayland for linux, whatever adroid uses and whatever macos uses and iphone

    • @cdarklock
      @cdarklock  22 дні тому +1

      @@vadiks20032 Absolutely. Knowing your library is arguably more important than knowing your language, because a proper library could be called from any language.

    • @cdarklock
      @cdarklock  22 дні тому

      A lot of it comes down to what your engine/library is doing for you, and what you have to do yourself.
      I'm fairly uneducated about what Godot can do in an arcade context, because all my work with it to date has been on clicker/spreadsheet games that are essentially just big UIs with a "click me" button in the middle; when it comes to something like "figure out how far it is to that thing over there and move closer to it," my impulse is to pull out the trig functions, but Godot actually has a fairly heavyweight Vector2 class that will do most of the lifting with the DistanceTo() and MoveToward() methods.
      A lot of the learning curve is taking what I already know from coding on the bare metal and using other frameworks, and adapting it to how Godot works - which is, thankfully, unlearning a lot of the "why did they do it like this" garbage because the Godot team tends to think and ccde more like I do. When I go in to test how something works, because it is the thing I want to do but I don't know how the team has implemented it, more often than not I find that it's the way I myself would have implemented it. I'm used to thinking "well it SHOULD work like this, but how DOES it work" and the answer is generally something weird.

  • @samuelbanya
    @samuelbanya 23 дні тому +8

    Wrong, all we have to do is to maintain some shitty CRUD app

    • @cdarklock
      @cdarklock  23 дні тому +3

      Been there. It gets better. I mean, you know it can't get worse

  • @Mario-qr5qm
    @Mario-qr5qm 23 дні тому +7

    Clicked for the posters, stayed for the old man wisdom

    • @cdarklock
      @cdarklock  23 дні тому +2

      Well there's certainly an old man, not so sure about the wisdom

  • @skirmisherssouthport5056
    @skirmisherssouthport5056 23 дні тому +4

    You pick the method that requires the least amount of work on behalf of the processor. If every object has to interate over the entire enviroment to see if a player is near this is going to take a long time, as oppossed to creating a list of influenced objects near the player which requires one pass.

  • @justinhawkins101
    @justinhawkins101 23 дні тому +1

    Keep at it man and keep us informed I’d like to test out what you’re working on.

  • @cba46
    @cba46 21 день тому +1

    God send video. I spent a week crying on how to scale my squares and chess pieces together. solved it in 30 mins today just re reading the examples

  • @theloststarbounder
    @theloststarbounder 13 днів тому

    Make it a world class to deal with items and NPCs moving, as well as applying buffs/debuffs and so on, so that player updating in a class can be independent from the other items/NPCs

  • @ddBenny
    @ddBenny 23 дні тому +3

    This is what the Ballmer Peak feels like 😆

    • @cdarklock
      @cdarklock  23 дні тому

      Oh, you have no idea. I got really hammered once in the 90s and wrote a program that used matrix algebra to embed a CRC-32 into its own data stream (I used to get really into this kind of copy protection and DRM shit), which is pretty cool, but... I don't know matrix algebra. I don't know how I wrote this code. I was never able to make sense of it and my comments were - as you might guess - not very helpful.

  • @hylomane
    @hylomane 23 дні тому +1

    The hardest part about programming is dealing with the assholes at work.

  • @DM78
    @DM78 23 дні тому +2

    Have the player do a radial collision test on the objects in near enough vicinity to have them start moving toward the player, then call a function on each of the objects to perform the movement and/or pickup. That way, you're only working with a small set of your possible objects within the quadtree and not "the whole world"

    • @cdarklock
      @cdarklock  23 дні тому +1

      I mean you're still searching the whole world, you're just sorting your objects into a quadtree to optimise the search. There are lots of ways to optimise the search.

    • @skilz8098
      @skilz8098 23 дні тому +1

      Exactly my thoughts!

    • @skilz8098
      @skilz8098 23 дні тому +1

      @@cdarklock Kind of, but you can mitigate some of that too. Sure, the player might have a bounding sphere, but they also have a viewing or looking direction, as well as a heading or trajectory direction. Their moving direction and the edge or curved surface will intersect at a given point. This point is a reference point and from there, we only need a subsection of that sphere. It could be either a cone or a semi sphere (probably closer to a cone) and from that we really only need the exterior surface area. This region will be constantly fixed to the player as the player moves through the scene. We do not need to test against every single object within the world. We only need to check that curved surface area and see if there's been an intersection with another bounding box. If there's an object that's 100 meters away, we shouldn't even have to have a need to test for it especially if it's not within the same line of sight and moving direction. We do need to test everything that is along that line though to find out if they did intersect if they are at least less than the max distance for the line of sight. There's way's to not have to test against everything. This is where having a z-depth buffer comes into player especially if they're already in sorted order. We only need to test for things less than a depth, ignore all else. Same thing with the width, it's not much different than culling and occlusion with the view frustum.

  • @SirLightfire
    @SirLightfire 24 дні тому +2

    One approach would be to offload the responsibility into some sort of "Collider manager" utility. Such that neither the object nor player needs to bother managing the game state beyond it's own responsibilities.
    This does introduce a (semi) new problem, namely having to explicitly define interactions between every pair of objects. However, i personally like having those definitions next to each other anyway

    • @cdarklock
      @cdarklock  24 дні тому +3

      I've been through both sides of the programming paradigm around this: put all your collisions in one central "collision" process, that knows what happens when every thing collides with every other thing, or put the collision management in every object so that object knows what to do when it collides with something else. In my experience, the big central process tends to be brittle and subject to weird esoteric bugs over time, which is a shame because I also like having everything in one place.

    • @skilz8098
      @skilz8098 23 дні тому +1

      I tend to prefer to have bounding spheres or boxes around objects that are interactable. Then for the player, NPCs, mobs that move or have some type of path finding algorithm to have a line or field of sight, or even a radial radar with some kind of attenuated max distance. Anything that is inanimate does not need to know or be aware of any other object unless if it's part of the design of the game by intent. From here we just simply need to incorporate edge detection (lines and curves), line of sight - field of view with max distance, intersections and we can incorporate all of these checks for collisions in either a BSP, Quad or Oct Tree that is closely integrated with the overall Scene Graph.
      If it's an enemy mob and there is no collision between the bounding boxes, spheres, yet the line of sight of that mob with its distance does intersect then that trigger the event for the mob to move towards the player to attack. If it's an NPC that has some kind of script for a quest or request, we can do it with the same approach. So, for these they can have their own individual but limited internal collision detections. As for inanimate objects regardless of if they are static or dynamic objects, they require none. They only need positional-orientational and size-bounding box-sphere data that can be queried from the player's or camera's perspective. The objects do not need to know about the player entity, but the player entity does need to know about the objects.
      You can have multiple collision detection systems within the same engine. It's just that a little more care needs to be taken when there are multiple systems running concurrently. There're many ways of doing this and there is no exact right solution or one-way fits all method. It all depends on the internal game flow mechanics, environment, intent, aesthetic, feel, etc. that you are trying to achieve.
      Yet as from an efficiency viewpoint. It's better for the player to scan ahead with a bounding volume through edge detection and intersections than having every object being locally aware. The other reason this is way more efficient is because of the fact that yes you might have a radial sphere around the player object, but typically the player has a combination of a looking or viewing direction, as well as moving or trajectory direction. These are straight lines that will intersect the edge of that box or sphere which is always known and constant. When the player is moving in a specific direction, there's only a subsection of that sphere that will trigger when objects intersect the boundary. So here we only really need to consider a cone to a semi sphere region, and we only need the outer surface area of it relative to the heading or moving direction of the player. This is a simple point to contour intersection test. The player object doesn't have to scan and test for everything within the scene. It only needs to scan and test for things that intersect its boundary. The player doesn't need to check for the car that is behind the building that is between them. It doesn't even need to check for the walls of the building unless if the player gets close.
      This is where BSPs, Quad Trees, Oct Trees, etc. come in handy that I already mentioned above. This can be built right into the scene graph itself, yet it can be beneficial for specific entities to have their own detection systems. This way, they can be customizable and specifically unique for a give type that requires them. For example, a wolf might have its own detection system compared to large bat. Their movements, their A.I. behaviors, etc. should have a unique feel instead of being a generic cookie cutter. This helps to make the world feel more dynamic, more alive. Again, these systems do not need to be checking for every other object. They only need to be aware of their local surroundings defined by some max distance, built in radar systems that will attenuate - dissipate over distance within a defined radius and trajectory. You don't want a wart hog coming at your player in the same manner as lion. Their visions, sense of awareness, etc. ought to feel unique to their types.

  • @Phantasen
    @Phantasen 21 день тому

    Interesting that I would stumble on this video when I was battling with the same problem yesterday. I have a simple game where blocks are falling down and you shoot them and then they collapse and fall down again. I was thinking should the rearranging happen by the level script that spawns the blocks, or should the blocks themselves be responsible for moving themselves.
    In these situations I try to think which is the most expandable approach in the future.
    I ended up going with the blocks moving themselves, because it it's just way easier for me to conceptualize, and I think it is easier to expand too. Depending on the types of blocks I decide to add, I just need to modify that type of block, instead of having all sorts of conditionals in the level script.
    In your case, I think I would have the player have an area2d called nearby_area, that has collision mask on layer 2, which would send a signal on_body_entered to the player itself. The player would then call a function near_player on the body that entered that (the body reference is supplied by the signal). For me I think this would allow for maximum expandability. If you add other objects that need to be attracted to the player, you just set their collision layer to layer 2 and add to them a function near_player. By modifying the near_player function in those other objects you could then give them custom functionality, like maybe health pickups are attracted slower than the experience pickups. You could even add the near_player function for objects that are supposed to be repelled by the player, or something else entirely. And there could be an upgrade that the player receives that just incereases the size of the nearby_area that the player has.
    But, like you said, it doesn't really matter in the end, there are benefits and drawbacks to every way of doing things.
    Other people here brought up optimization, but I don't think that matters too much here. Computers are powerful enough these days to handle things in simple 2d games which ever way you decide to do it.

  • @baranjan6969
    @baranjan6969 23 дні тому

    Relatable as hell.

  • @johnmarston2474
    @johnmarston2474 22 дні тому

    I'd just give all the XP orbs a collision box that is detected by the existing collision system and fires a method on them to signal the interaction if they are certain types of entities. Or a new loop dedicated specifically to this task that doesn't run every frame.

    • @cdarklock
      @cdarklock  22 дні тому

      That's the same problem, tho. Two objects collide. Which one handles and consumes the collision event?
      Furthermore, if you give every object a collision hull, you're going to generate a swarm of collision events from the objects colliding with each other. This is not necessarily a bad thing; with XP orbs, this could be used to combine them and reduce the number of orbs to be processed. But with something like a weapon or a health pickup, you're just crapping up the queue with events you need to ignore.
      I do like the way you're thinking: use the facilities you already have to reduce the amount of code you need to write. That's a good instinct.

  • @CryShana
    @CryShana 23 дні тому

    There is an objective reason, actually... The player should move the objects to themselves, because there are a lot less players than there are objects. Each object doing the attraction logic is not optimal. A player grabbing all objects in proximity and moving them in a loop is a lot more efficient, especially when you have thousands of objects (this is the concept behind Data-Oriented Design). Also we don't care about objects in far distance from the player, those should not be running any logic at all. It also centralizes the logic into one place, making it easier to debug (you will have all relevant objects in one place).
    However, it depends on your game as well. Assuming you are not doing a CO-OP game and only have a single player. And as long as you don't have too many objects, it may indeed be faster for an object to query a single player every time. However, if you will have a lot more objects, at some point querying the spatial structure (ex: quadtree) for objects in proximity only on the player, becomes better and SCALES MUCH BETTER. You just have to measure it. (Honestly, you don't need that many more objects for this to pay off, if done correctly. A single spatial query and looping a few objects is almost always going to be faster than looping through ALL OBJECTS and executing their simple logic for one player)
    Whether logically you think this attraction behavior makes more sense for player to do or object to do - it really depends on how you use it. What if a player gets a buff that improves the attraction force - it makes more sense to me for players to control the attraction. But if attraction is a property of the objects and each object has it's own attraction properties, then sure, have them be on the objects.
    If you are hesistant to put more logic into the player to keep code shorter - maybe you should organize the code better instead. There are many ways of doing that one. I often have a type of module system - the player just goes through modules in a list and executes them. I can easily enable/disable modules. That way, each module has it's own code. It's passed the player reference and works with it. Now you can easily separate code. This is just one option. If you're lazy you can always split the code into more files (partial classes in C#, or multiple implementation files in C/C++)
    Nice video tho. And nice posters.

  • @skilz8098
    @skilz8098 23 дні тому

    Let's assume the game is in a 3D virtual environment. If we have every object in the world that moves towards the player as the player becomes close, this means that they are always going to be checking to see if this is true. If there's 10,000 objects within the scene, that's a good amount of checks every single frame. If this was to be implemented towards the player's object perspective, then only the player has to be aware of the nearby surroundings. With this we can implement a bounding sphere around the player and have an algorithm that uses the edge (edge detection) in conjunction with an intersection test of an objects bounding sphere or box. When the objects within the viewable scene are within a BSP or even a Quad or Oct Tree, it's must more efficient and less computationally expensive for the player to pick up nearby objects. Now, if the objects within the world are say NPCs especially enemies or mobs, then yes, I could see them having a line of sight - distance detection with some type of path finding algorithm to charge towards the player. Yet for anything that is inanimate, I would say no, those objects shouldn't need to know anything about the player and by having these types of constraints it helps to keep the entire collision detection system a bit simpler reducing the number of bottlenecks it could end up otherwise generating. Also, with having the bounding sphere around the player this sphere moves with the player throughout the scene. We only need to know about the objects when they are within this volume to trigger the events of animations, motions to draw them to the player. We do not need nor want every object trying to constantly check for the player's whereabouts. Now once the object is within the player's bounding sphere, then from there do we have the objects move towards the player or the player towards the object? Again, this would make more sense for the objects to move towards the player. If the player is standing still and there are a dozen items all at different directions and distances from the player within that bounding sphere. It's more efficient for them to travel towards the centralized location. If you tried to implement it the other way, then you'd end up having the player moving in all sorts of directions and this could lead towards the traveling salesman dilemma and the motion could also present a jerkiness as it's being rendered throughout a series of frames. Again, this is a bit less efficient and less desirable. By having the player being the one that does the detection and triggering while having the objects that are in range move towards the player, this conceptually gives the impression or dynamic feel within the game - game play that the player has that kind of ability, control power within the game, the scene, the virtual environment. It has a certain appeal, desire, pleasure towards it, a sense of reward. These are the types of things I would think about and consider, and this is the approach I would take on tackling this type of problem.

  • @johnmarston2474
    @johnmarston2474 22 дні тому

    Best solution:
    Just implement it whichever way you can, and if it's a problem, make it better. Maybe even work on other things like health pickups and stuff afterwards. Then experiment with optimizations once you have everything available to actually test and if actually necessary.
    Another idea:
    Instead of giving each orb a collision box, do it in reverse. You have 5 orbs here, these 2 are in the same group, so give them the same box. Easier if you're spawning them all at the same time.

    • @cdarklock
      @cdarklock  22 дні тому

      Definitely best solution. Make it work, and fix it if it stops working. Done is better than perfect.

  • @owencoopersfx
    @owencoopersfx 18 днів тому

    IMO just use the physics system and filter by layer. If the exp orbs only care about the player, make them only detect the player layer. The player shouldn’t really be concerned with the behavior of the orbs, it should only be concerned with what happens when they’re collected. This makes debugging easier too because if something goes wrong with how the orbs are behaving then you know to look at the orb class and not the (likely) massive code of the player. Of course ultimately the decision really just falls down to what makes it easiest to understand when reading the code, but IMO separating them has more advantages than putting it all in the player.

    • @cdarklock
      @cdarklock  18 днів тому

      That's the conclusion I came to, as well. Isolate behaviour, isolate bugs. And there WILL be bugs. There are always bugs.

  • @UQuark0
    @UQuark0 23 дні тому

    My father once described a similar problem to me, he called it "The Smart Door Problem"
    tl;dr you have a Player class and a Door class.
    Should the Player have openDoor() and closeDoor() methods or should the Door have open() and close() methods?
    My father's answer is simple: doors do not open themselves in real life, so for all realistic purposes this method should belong to the Player class, while the Door class stores applicable-to-door values, e.g. rotation angle, locked state etc.

    • @ocks_dev_vlogs
      @ocks_dev_vlogs 16 днів тому

      I would argue the door should have the functionality for opening and closing itself, it’s a problem of scaling.
      It doesn’t really matter who has it when it’s just the player and the door, but if you think ahead, and want someone else to be able to open the door, then you run into the problem of having the code to do so only on the player. If the code to open and close the door is on the door, then you can have any manner of things interacting with the door without issue.

  • @flipperiflop
    @flipperiflop 25 днів тому +3

    Squeakiest chair that has ever squeaked :D Also, very interesting video, thanks for sharing. Often understanding the problem is to realise what you THINK is the problem, might in fact not be a problem at all, if you realise what the REAL problem is and solve that instead.
    A quick example that comes to mind is: I received a feature request to improve on how the shipping fees are calculated, so that they are more correct. I could have gone ahead an implemented logic to manage various edge cases (for example: what if the offer gets accepted before we know the real location of the item, that would mean that the shipping price cannot be known at the point of acceptance).
    After talking to the stakeholders, I learned that the real issue that they wanted to solve was simple: they just don't want to accidentally submit offers that have a shipping price of "0", or at least be notified if that is the case. So the whole task gets resolved by a simple confirm popup if the shipping price is calculated to "0", instead of having to start modifying different flows that the data goes through.
    This allows me to postpone fixing the core issue, which is caused by the flexibility requirements of the workflows, to a later point in time, when I KNOW more about the problem space, and understand the different requirements that there are for the whole processes. It doesn't help if I try to fix the previous assumptions that I've made with the system with solutions that are based on more information, but still fundamentally assumptions. I rather wait with that until it really needed, so that the decisions are made with most information possible.

    • @cdarklock
      @cdarklock  25 днів тому +3

      One of the things I found working with clients was that, particularly in large companies, people often think their actual problems are too small to bother with - so they try to wrap up their small problem in a big problem that is likely to catch someone's attention and get fixed.
      This gets even worse when you have people "on the ground" trying to get the attention of management, who will just shrug and recommend various workarounds that the mainline workers are already using... but that aren't reliable. A manager would probably recommend that people just "make sure they check" the shipping before approving the order, which is probably the first thing they did when this started happening.
      The right thing to do in these cases is to talk to the people who will actually be using the feature and see what they really need. We had a request once to add "tracking numbers" to shipping labels, which was kind of a catch-22 situation: you don't have the tracking number until you ship the package. This had been passed around the department for over a month, generating a lot of heated discussion, and eventually landed on my desk - so I went down to the warehouse to talk about the use case and potential solutions.
      What they meant was the INVOICE number, which is how they "track" the package internally. The actual ask took about thirty seconds to implement and went live the same day.

    • @flipperiflop
      @flipperiflop 25 днів тому +1

      @@cdarklock lol :D Sounds like they were really playing the telephone game with that ticket

    • @cdarklock
      @cdarklock  25 днів тому +3

      @@flipperiflop I cannot overstate how important it is, when working at any company, to get up from your desk and go talk to the people who email you. I spent thirty years solving problems nobody else could with this One Weird Trick.

  • @skilletpan5674
    @skilletpan5674 23 дні тому

    For me the solution is to make an event table. In that table you have all your objects and when/if they are scheduled to do something. I.e if your player presses the "move left" button then you add that event and how long it's supposed to take in what ever time unit you want to use (i'd suggest a large number like 10,000 per sec because then you can do some finegrained skills based time adjustment like a dodge skill shaves off some time).
    Next give your objects that can trigger a radius and have that event trigger by the scheduler. The scheduler will do it rather than some mumbojumbo "object orientated" obfuscation.
    One day when i get around to doing my mega better than ADOM rpg, i plan to do this for that.
    Why overcomplicate things?

    • @cdarklock
      @cdarklock  23 дні тому

      Sometimes when people have a problem they say "I know, I will build a manager class to handle this." Now they have two problems

    • @skilletpan5674
      @skilletpan5674 23 дні тому

      @@cdarklock I have an easy solution to this entire problem. Go back to procedural programming and just do object orientation when you want something to deal with it's self. I wonder why we don't have object orientated kernel schedulers? This is the problem you are really talking about and by changing the thinking it can be made much simpler. Yes a manager "class" (I'm no real programmer, I use freepascal and haven't coded anything resembling something for about 20 years) or in my case a scheduler solves this issue because it either does it for you or hands off to what ever object needs to deal with it. In terms of person vs exp orb. I'd say person if your person is reaching out a hand. I'd say orb if it was magically jumping and attaching to the player. I'd say scheduler if you want to make it easier to think about. Just have a time based scanner and a time+location based scanner. I.e the timed based scanner checks for "things that need to happen 'now'" and the time+location scanner looks for "things that need to happen 'now' and are close enough to be started".
      If you make your lists/arrays properly then it should be fairly nicely optimized. I think it's also a good way to implement story based things too. I.e events that will/should happen in the future but you just don't need to deal with any time soon.
      (this is more for other people reading this because I'm sure Caliban gets it).

  • @nadri3335
    @nadri3335 23 дні тому +1

    Have a nice day, I liked your video :D

  • @ArthurSchoppenweghauer
    @ArthurSchoppenweghauer 21 день тому

    I'd like to see what you're working on. Sounds like you're using an object oriented framework / engine. How much control does something like Unity give you over how the data is laid out in memory? It depends on how data is accessed, but I think that objects may lead to a less contiguous memory layout for certain data, which adversely impact the performance of your game due to memory re-allocations.

    • @cdarklock
      @cdarklock  19 днів тому

      I'm using Godot, and it does give you SOME control over how the data is laid out, but you have to actually exert that control. Like if I want to use object pooling for bullets in the game, I have to manually design and build that object pool instead of just telling the engine to pool the objects.
      The party line is that you don't have to do this because Godot is very very fast at allocating and freeing objects, but what that really means is "you don't have to do this AS OFTEN" because there is absolutely a threshold where object pooling would increase performance. The question is mostly whether you want to wait till you hit that threshold, or just go ahead and build it now.
      I have opted to wait until I hit that threshold, not because I don't think I will hit it, but because I want to have a clear picture of EXACTLY what the object pooling needs to fix before I start trying to fix it.

  • @newplayer7743
    @newplayer7743 23 дні тому

    I would argue choose game design first. If players the one that picked up the xp, then make sense to do so in code. But I will left a note. So when we do code optimizations, we know where to look at.
    But I'm personally will choose the most efficient one to whole code design. Even if that not make sense to the game design. I wish someone yell at me to stop doing premature optimization.
    Btw this video randomly pop out in my YT home, I'm come here because something in the background catch my attention.

    • @cdarklock
      @cdarklock  23 дні тому

      I always yell at myself not to do premature optimisation. It took many years to learn that, but it did eventually sink in; similarly, I have to whack myself about the head and shoulders with "JUST TRY IT" whenever I am wondering whether I can do something. Like right now I am wondering how the pickup code will perform with thousands of pickups scattered around the screen, and the correct answer is "just instantiate several thousand pickups and try it."

  • @takieddinbalti6956
    @takieddinbalti6956 23 дні тому

    It's an easy decision for me. I like to have the object do the logic related to the object to keep things clean. So i know when i need to make a change to how the object behaves, that i need to look into the object.
    I did nilly willy before and then i spent a lot of time to look for a logic and it's relations.

    • @cdarklock
      @cdarklock  23 дні тому

      Kind of the same thing I'm thinking, if you want to change how X object works, you open X object. The movement of objects toward the player is an object behaviour, not a player behaviour. I always like to think in terms of an object inherits from what it IS, adding members for what it HAS and methods for what it DOES. The player doesn't do the object motion, the object does that. But leaning on dogma like this can get you into trouble, so I still tend to agonise over the decisions.

  • @softgripper
    @softgripper 24 дні тому

    I've had this conundrum way more often than I'd like to admit :D, especially with Godot. "Does this signal that, or does that signal this... do they signal each other?"
    In this specific instance, I'd put the logic into the "objects".
    Why?
    Well, if there's ever going to be a different "collector" - eg, a loot goblin, or a second player etc, I'd personally have an easier time reconciling that at the "object" level, with a target destination than having competing collectors.
    Ultimately it doesn't matter. There is no "correct" way. Maybe that's why it's so bothersome.

    • @cdarklock
      @cdarklock  23 дні тому

      That's definitely why it's so bothersome. I lean in the direction of "the object does it" so I don't have to manage a collection. I think I may end up having to implement it both ways just to compare and contrast how they work; its not like either of them is especially difficult.

  • @spaghettiking653
    @spaghettiking653 20 днів тому

    Based posters in the background! What's the one on the left? And, I take it you're a KonoSuba fan?

    • @cdarklock
      @cdarklock  20 днів тому

      Fire Force, Maki Oze and Tamaki Kotatsu. And yes, very much a Konosuba fan. :)

  • @Hpykce
    @Hpykce 23 дні тому +2

    Megumin fan huh :dd

  • @InfiniteFreemannn
    @InfiniteFreemannn 23 дні тому

    Man, I am not a developer or something, just UA-cam recommended this to me for some reason, but I admire and respect ppl like you.
    I can't resist but just to ask this side question:
    What on Earth microphone are u using ?
    Or maybe you do post-editing, hardware filtering... ?
    By the way: Cheers ! 😅

    • @cdarklock
      @cdarklock  23 дні тому +1

      Cheap as shit Maono condenser off Amazon; I think it was $40 including the swing arm. Then that runs an XLR cable through a hardware mixer, an ancient Mackie 1202, where I cut the low end about 40% with an 80Hz shelving EQ; finally it hits OBS where I apply a fairly aggressive 4.0 compressor at -40dB and a moderate noise gate at -45/-35 with 25ms attack and 100ms hold/release.
      One of the tricks I use is to aim the condenser at 90 degrees to the sound source, which absolutely slaughters most of the mouth and breath noise. Of course, I haven't been especially successful at getting the chair squeaks out of the mix.

    • @InfiniteFreemannn
      @InfiniteFreemannn 23 дні тому

      @cdarklock Yeah, I listened with headphones and it was at least a bit strange noise xD
      Thanks for the info !
      I have even cheaper BOYA BY-BM2021 mic, which I intended to use with my digital camera, but it almost records only on right channel and it has a background noise/hissing... maybe the problem is not from the microphone or it is from both the camera and mic.
      Got it for about 25-30 euros (or about lets say 50 bulgarian levs) :)
      Note taken - never to buy the cheapiest when I want at least *some* quality.

    • @cdarklock
      @cdarklock  23 дні тому

      @@InfiniteFreemannn That's a shotgun mic with a fairly large pickup area, which means you're going to get more of the noise from the surrounding region. The Maono (AU-PM320S, I checked) is a studio mic, designed to work in a booth and pick up only the noise fairly close to the front of it, unless it's really loud.
      They're running about $65 on Amazon right now, but they are studio XLR microphones that don't plug straight into a camera or computer - you need a separate hardware interface, which will probably run another $50 or so. They do make some USB mics, but I don't know how well those perform.
      It's always a struggle trying to get all your kit to work together, especially when you're on a budget. Post-processing your audio might be able to kill the hiss with some EQ, and you can just duplicate the right channel to the left in your editing software. Most vocal tracks are mono anyway, so it won't make a noticeable difference.

    • @InfiniteFreemannn
      @InfiniteFreemannn 23 дні тому +1

      @cdarklock Yeah, I agree, I am aware that i can "copy" the right channel to the left one.
      Afterall it's not all about money, IMHO it's more about knowledge (not just information) and experience. :)
      Thanks again for the time you spent to reply me and have a nice day ! (It's 8PM here but not sure about you :) )

    • @cdarklock
      @cdarklock  23 дні тому +1

      @@InfiniteFreemannn 10:30 AM. Bulgaria's over in UTC+2 and I'm in UTC-8. Kind of amazing how we can be very nearly on opposite sides of the world and talk in almost real time.

  • @BrokenAtari
    @BrokenAtari 23 дні тому

    If you have a beefy gpu you can run your mic through it to clear it up if youre interested. And cool vid

    • @cdarklock
      @cdarklock  23 дні тому

      It's an XLR microphone, so it plugs into an external hardware mixer.

  • @codingtranquility
    @codingtranquility 6 днів тому

    Midian is a great fucking album

    • @cdarklock
      @cdarklock  6 днів тому +1

      Filth forever, man. 100%

  • @TheDoomerBlox
    @TheDoomerBlox 24 дні тому +1

    But what if you like solving problems, but writing the solutions down sucks.
    Worse yet - having to follow certain rules and norms of human-machine communication set to some arbitrary standard and interfacing with a bunch of undisclosed and ever-shifting customs? Yuck!
    3:37 - Do we move the object if it's close to the player, or do we have the player move the object closer?
    From an architectural perspective, the difference is having to always check on every silly little object whether a player is nearby, versus a player checking for what is nearby and Something happening.
    The former rapidly runs into scaling issues, the latter is always handy - as generally we want all sorts of Objects to interact with the Player - and it is a common point of optimization.
    e.g. the old Doom's blockmaps to first limit how much area we're going to be scanning for Player-Object or Object-Object interaction.
    have some more yapping

    • @cdarklock
      @cdarklock  24 дні тому +1

      I mean you're just describing programming. Every program is the solution to a problem, written down, according to the rules and norms of human-machine communication that were popular and convenient at the time.
      As far as object/player actors, the real difference is whether every silly little object looks for the player, or the player looks for every silly little object: you still have to check every object. Even if you cull the objects, you have to check every object to see if it needs to be culled, and that's only an optimisation if culling the objects is faster than checking the distance.
      Doom, for example, didn't have dynamic pickups. Everything you could pick up was placed before the level started, so you could identify where on the map it was - and restrict any checks for picking it up to when the player was in that section of the BSP tree for the map. Most of the work could be localised to build time, because nothing new was going to be dropped during gameplay.
      But in a system which DOES have dynamic pickups, where any item could be dropped anywhere at any time, whatever culling mechanism you use has to be managed at runtime during gameplay... and still has to check the distance to the player. So it needs to substantially reduce the number of checks made, or it's not even worth implementing.
      A fairly obvious one would be to calculate how fast the player COULD be within pickup range, and put the object to sleep for that period of time: you don't need to check, the player can't possibly be in range. This would work fairly well, as long as the player's speed didn't increase appreciably during that time, and even then it would rarely be noticeable.

    • @TheDoomerBlox
      @TheDoomerBlox 24 дні тому

      @@cdarklock Just-in-time initialization of objects, now we're cooking!

  • @alectoireneperez8444
    @alectoireneperez8444 23 дні тому

    The player should not move objects toward it, and objects should not move on their own volition. There should be an external entity, that knows about the player, and about objects, and moves objects towards the player if the player is nearby.
    This can be handled by the class representing the world, or by an entity held by the world

    • @cdarklock
      @cdarklock  23 дні тому +1

      How do you justify this? It's one thing to say "this is the right answer," but why? I mean obviously there IS an overall managing object where this logic can be placed, but why should it have the code instead of the player?
      Theoretically, the player is "picking up" the object, so there's a justification for the player to move the object - you, after all, move your coffee cup. Similarly, if the object is going to move toward the player, the object is affected by a force - the proximity of the player, similar to gravity - and it is the object that moves. What is the justification for doing neither, and having some external operator do it instead? Will it simplify the code?

    • @skilletpan5674
      @skilletpan5674 23 дні тому

      If you are worried about the why like that then it'll never be reaolved. Personally i think having an event scheduler that deals with time related things is the best way. It means you can resolve this stuff easily. Time related? Yes the when do things occur is more important than what is moving the magic exp orb to your guy issue.
      Also having a scheduler means you can easily resolve combat issues like who hits who first etc. Oftin in the 90s you'd be playing some real time action game (like street fighter 2) and the timing was just off.

    • @skilz8098
      @skilz8098 23 дні тому

      @@skilletpan5674 You can still have internal collisions in conjunction with time-based events. This is where BSPs, Quad and Octrees as well as priority queues, timers, etc. come together. You have your rendering engine, you have your animation engine, and you have your physics engine. They do need to be synchronized to get the desired frame rates that you want to where the transformation updates match that which you are expecting. How can we resolve different timings to be synchronized? Hmm perhaps FFTs. They're very fast and efficient and work seamlessly with matrix operations. Even quaternions can come into play although they are used more towards rotations. Yet instead of having every event handled in a single place, having multiple modules can provide you with a way to have independent and unique customizations for different types. Again, you can still incorporate an event handler that can be triggered either by a timer, or by some other criteria but it doesn't have to be a global thing. It can be localized. Also, when implemented correctly and finetuned, this allows the entire world or environment to feel more alive and dynamic than a boring and dull cookie cutter.
      Having the player object to scan a region via a distance and curved surface based on the viewing and moving directions only has to check for nearby objects within the scene graph. It doesn't need to check for everything. As for inanimate objects they only need a bounding box or sphere. They do not need to know anything about anything else. They only have positional and size data, potentially other attributes such as mass or momentum depending on if they are stationary or were moved by some other force, but they do not need to scan for anything when they are not moving. If they are moving then yes, they do need to do checks for collisions based on the direction of their trajectory (line of sight). As for NPCs or even Enemies, then yes should have their own independent collision detection system that is integrated in with their A.I. pathing, scripting engines (quests, requests, routines, etc.). And yes, they can have their own scheduler, timer mechanism. Now as within the scene graph as a whole, the farther an object is from the player, the lower it's priority within a priority queue it should be for its events to be triggered or handled. You only need the relatively closer objects or entities to the player that could potentially trigger the players collision to go off.
      Also, each entity doesn't have to be bound to a single bounding box or sphere. They can have multiple for different purposes. This allows for unique customization, it also helps to make the world feel more dynamic, more alive. Now, as for things that are happening in the background that aren't near the player but are still moving through the scene and are in the camera's view, then yes, these things should be pushed to the "world scheduler". For example, a helicopter flying in view in the background. Yes, you are going to have events. Yes, many things are based on time. Yet not everything has to be all the time. Time is only relative when something does move. Time is an emergent property of something in motion. When something undergoes a transformation, it being a translation, a rotation, a scaling, a change in color, emits particles, etc. that's when time appears. When something doesn't change and maintains the same state, it is static. Thus, the difference between potential and kinetic energy. However, each object that can be moved or interacted with does need a triggering mechanism as well as an attach event object to it.
      An example: A large rock or bolder might not have any event at all. It is stationary, it is static. It has no timer. Just positional, model (mesh - texture - color), basic properties (mass, temp) data, etc. Then a player places a stick of dynamite on it. The dynamite explodes. The force of this explosion has a radius and a force. That rock is within the radius. The trigger on the rock is set by the force carrier, and an event is attached to that rock. That rock then explodes or shaders which then triggers the animation of it separating into smaller pieces each moving in their own direction, or it disintegrates it to nothing. So here, the rock had no sense of time, no event, etc. Yet the explosion force itself carried the event to be attached to this rock and then internally the rock object then triggered that animation - shader, etc.
      Yet this is just one of many different ways of doing it. There is no one solution fits all. There're various different kinds of methods, and they all have their own pros and cons. We just have to weight them out and choose what we think is best for our needs. It also depends on the desired results, feel or aesthetic of the game play - game mechanics. An RPG game isn't going to play the same as an FPS or Dungeon Crawler, which isn't going to play the same as a platformer which isn't going to play the same as a skydiver or underwater submersion. Timing is a main concern for sure, but there's more to it than just timing. And many of those timing issues can simply be resolved through having efficient code with minimal bottlenecks. You don't want one function running 90% of the time hogging all of the systems resources. However, when you do sub divided yes you can minimize hogging functions, or bottlenecks by the work being spread around more, yet you do introduce other issues and concerns that needed to be accounted for and handled such as synchronous and asynchronous operations.
      There's typically the rendering engine, the physics engine, the collision detections, the animation engine, and the event engines. And these do have to be coordinated properly so that the rendering and updating of things looks right. So, we do have different timing intervals at the various engine levels, and this doesn't even account for sound, and yet we want everything to playout within our desired targeted frame rates.
      Here a batch processing mechanism can really help. Batching for sending objects to the GPU to be processed and rendered, batching for in game updates, etc. This can integrate quite easily into the scene graph. And with this we can do multiple batches in parallel on their own threads if all of their queued objects are independent from each other batch. So, there's many different systems and algorithms at play. A Game Engine is a complex beast. I've built a few of them from scratch in C/C++ some using DirectX 9.0c, 10 & 11, Legacy OpenGL, modern OpenGL 3.x-4.2 or 4.4, and even Vulkan. Wrote my own texture loaders, file parsers, even a scripting language to automate the loading of objects from a custom-built GUI system, as well as level data. I've tried many things, studied all of the various techniques and approaches. Sometimes, having hybrids of things works nicely.
      Somethings within the scene are static while others are dynamic, and those that are static can be changed to dynamic based on specific criteria and if some conditions are met, while other static items might be permanently fixed. It all depends on the current project, the original vision of the desired application as well as the progress of its development to where it might even help to design itself.
      In the end you have a frame that is being drawn. This is still image, a static image. Then another frame is being drawn, and so on. Each of these frames are static images like pages in a flip book. That's why films or movies are also called or classified as Motion Pictures. When you have a virtual environment regardless of if its 2D, 2.5, 3D or something else, there's always update methods that are time related for sure. Yet there's many different ways to handle this and many different approaches. Somethings don't have to be based on a timer as in seconds or milliseconds, somethings can be based on counters - iterators. Sure, in some sense they are similar or partially related, but not necessarily. We can have an iterator that increments by some factor or by some condition.
      This is why I kind of like an integrated hybrid system between what you suggested as an event scheduler - timing based system that also incorporates a triggering system, dynamic environment physics simulation, animation engine (sprite based or even model (skin & bones) based) object independent, particle engine, and so on. If the game is linear then sure I can see having a strict specific event scheduler, but if the game is open world sandbox, that's not always going to work especially if you want the world to feel alive. I've seen and played too many AAA cookie cutters, and they get boring very fast.

    • @alectoireneperez8444
      @alectoireneperez8444 22 дні тому

      @@cdarklock the player class can handle all conscious choices made by the player, but this is not a conscious choice, it’s a rule of how the world works.
      The player class does not need to know objects gravitate towards it; just that it can pick up nearby objects. And objects don’t know how to do anything aside from have a position and velocity and a size and shape and texture.
      Any forces that act on objects (whether they’re falling, or bumping into each other, or scattering due to wind or explosion, or gravitating towards the player) are the domain of the physics simulator, and objects should obey that unless or until they’re put in the player’s hand or inventory for use

  • @enrott8560
    @enrott8560 24 дні тому

    Would this mean that the object will always be checking for a player at all times would that be cpu heavy especially if theres a LOT of xp laying around. Atleast usually theres only 1 player checking for xp at all times depends on what you think.

    • @cdarklock
      @cdarklock  24 дні тому +3

      Well, as mentioned in another comment, it doesn't actually matter who is looking. Either every object has to check whether it is close to the player, or the player has to check whether it is close to every object. The obvious optimisation here is to have far-away objects "sleep" between checks; if the player has a pickup range of 200 pixels, can move 300 pixels per second, and is 2,000 pixels away... then they would have to move 1,800 pixels to be in range, which would take a bare minimum of six entire seconds, so you can just ignore that object for a while.

  • @serhii-dzhus
    @serhii-dzhus 24 дні тому

    All the time when I game questions like this - I try to understand which solution is better in the meaning of maintaining and/or simplicity of the code, but it’s not always easy to understand though)
    Do you use some game engine?

    • @cdarklock
      @cdarklock  24 дні тому +1

      I'm currently using Godot, but in the past I've used Unity and Unreal and various others.

    • @serhii-dzhus
      @serhii-dzhus 24 дні тому

      @cdarklock godot is cool, I made one game on it

  • @64packsofstraws
    @64packsofstraws 22 дні тому

    You're like me in 30 years

  • @aaronspeedy7780
    @aaronspeedy7780 23 дні тому

    Why not just have a function that does that? Why associate it with a class?

    • @cdarklock
      @cdarklock  23 дні тому

      For the same reason you might put the code in the player class or the pickup class: it's arbitrary. There's no concrete objective reason to put the code in any particular location, but it has to be SOMEWHERE. Something has to do the thing. It might be the player, it might be the pickup, or it might be a secret third thing - but it has to be something. Ultimately you just pick one.

  • @Ethyn_Jackson
    @Ethyn_Jackson 20 днів тому

    Are you from Kansas?

    • @cdarklock
      @cdarklock  20 днів тому

      Nope. Born in Ohio, raised (mostly) in Virginia, currently in Washington state.

  • @Nacho_Meter_Stick
    @Nacho_Meter_Stick 23 дні тому

    A common problem mathematically and philosophically is the 3-body problem. Three roughly equal entities are tugging on each other, and we don't know exactly where they are going to go.
    Now imagine you have a particle, and two players are tugging on it. Depending on which interaction you compute first (even if you alternate), position(t) will change. In this regard, the particle should weigh the two interactions and compute the movement vector itself.
    This only works because the players are not being accelerated by the particle. If they were, we would be right back at the 3-body problem.
    If this was something simple however, like we can make the assumptions that no particle will ever accelerate a player, that there is only ever one player, and particles will not accelerate each other, then for performance reasons, only one object (the player) should be trying to compute at any given moment.