Hot answers tagged

34

I know you do not conceptualize this as collisions, however what you are doing is colliding a circle centered at the creature, with all food. You really do not want to check food that you know is distant, only what is nearby. That is the general advice for collision optimization. I would like to encourage to search for techniques to optimize collisions, and ...


23

Storing the blocks as the positions and the values is actually very inefficient. Even without any overhead caused by the struct or object you use, you need to store 4 distinct values per block. It would only make sense to use it over the "storing blocks in fixed arrays" method (the one you described earlier) is when only a quarter of the blocks are solid, ...


16

You should adopt a space partitioning algorithm like BVH to reduce complexity. To be specific to your case, you need to make a tree that consists of axis-aligned bounding boxes that contain food pieces. To create a hierarchy, put food pieces close to each other in AABBs, then put those AABBs in bigger AABBs, again, by distance between them. Do this until ...


14

Sometimes you might want to store your savegame data somewhere else than on the users hard drive. You might offer a cloud save service, for example. In that case you would use SaveDataToMemory to create a savegame in a memory buffer and then send that memory buffer to a server via network. Another possible use-case could be to always keep the last savegame ...


7

Octrees exist to solve exactly the problem you describe, allowing dense storage of sparse data without large search times. The fact that your voxels are the same size just means that your octree has a fixed depth. eg. for a 16x16x16 chunk, you need at most 5 levels of tree: chunk root (16x16x16) first tier octant (8x8x8) second tier octant (4x4x4) third ...


7

TLDR - start simple and build up. Getting to AAA quality networking in an action game is complicated but may not even be necessary for your game. So basically: When client connects to the server, server creates new entity. Now, for example, when client presses 'A', packet is sent to a server containing this information. Server will proccess it, moves the ...


5

Preface: I've designed several game engines in C and C++ by hand and have plenty of experience with game engine architectural patterns and theory It appears you're designing a game from scratch. Let me first say, no, you should not use global variables for this purpose. They are stored in what's called the BSS or Data segment and while you may not notice ...


5

You're using a std::vector<Bullet>. This has the advantage of keeping data contiguous in memory, so iterating over it is fast (it has something to do with cache efficiency vs cache misses). The way you're using it is slow. auto it = Bulletlist.begin(); while (it != Bulletlist.end()) { if ((it->del)) { it = Bulletlist.erase(it); } else ...


5

This depends on how good the compiler is at optimizing the code. I'm inclined to say it is good if not very good. However, if you want to be sure, you got to do the experiment. Measure both versions with a profiler and see what comes up on top. Your job is not to optimize code, it is to make a system (a game in this case). If you go ahead and do that, and ...


4

You probably figured this out already, but just in case you haven't - the GLAD library has both a header file and a source file. So you'll need to add that source file (glad.c) to your project as well as referencing the header file (glad.h) from the rest of your code as you've already done. That should fix your linker errors, as the glad_ symbols you're ...


4

you are copying in your ranged-for loop. You should use for (auto& path : Path) This will pass by reference and allow you to make changes to the variable correctly.


4

I think you're pretty close. Here is one option, which I'd try to implement first. You need 2 components Input Camera I assume you'd create an entity and add them like this: ECS::Entity * UserCameraManager = EntityWorld->create(); UserCameraManager->assign<Input>(); UserCameraManager->assign<Camera>(getMainUserCamera()); Each frame, ...


4

Your lerps and slerps are backwards: lerp(current, previous, alpha) should be lerp(previous, current, alpha) ie. increasing alpha (more time accumulated since the last update) should move us toward the future, not toward the past. This could account for at least some of the choppiness you perceive. There could be additional judder coming from the player ...


3

In GLSL (like HLSL), a vec4 (float4 in HLSL) has three different ways to access its four values. You can use (rgba), or (xyzw), or (stpq). They're all identical to each other; Asking for vector.r gets you the same value as vector.x or vector.s, so use whichever you prefer. (General best practices suggest using 'rgba' if it's a color, or 'xyzw' if it's a ...


3

Godot can be used fully without any type of GDScript interaction. C# has official engine support, and can be used instead of GDScript in all places because the way C# scripts are loaded is similar. In fact, all of the "built-in" functions available in GDScript are made available in C#, typically as static methods under Godot.GD. I personally have had a very ...


3

The issue is that you calculate the FPS according to a single measurement, which means that any slight variation will cause a significant shift in results. Since the actual loop time varies due to system considerations, you'll get stabler results by averaging more calculations. fpsCount = 0; m_lastFPSDisplayTimestamp = glfwGetTime(); while(shouldRender()) { ...


3

If you have the normal of the collision triangle, then you can do a dot product with a normal pointing up (0, 1, 0), the result will be related to the angle of the surface (0 when is completety vertical, 1 when it's completely flat, and in between) That should be really all, you check that against a threshold to determine if you want the ellipsoid to slide ...


3

Shared pointers make sense when you have unclear ownership and unclear lifespan; otherwise they're just a dead weight you're dragging around. For most games you want to have a defined build-up and tear-down points where you load all your data and dump all your data. For example, at level load and level complete. In this case you can just use a nice, clean, ...


3

In C++ you can just destroy the CapsuleCompoennt, however the ACharacter class is intended to use the CapsuleComponent many of its underlying functions are relying on a CapsuleComponent. With that said you probably better to use APawn - and add all the bells and whistles manually. - Yes it will lose all the ACharacter's bells and whistles. Leaving the ...


3

You'll need some persistent state and a frame counter passed in: float lightning(lightningState* state, uint64 frame){ if(!state->enabled) return 0.0f; if(frame - state->lastStart < state->flashDuration) // during flash return 1.0f; //can also have a decreasing function here based on the difference if(frame - state-...


3

First of all, you dont have breaks in your switch statement, that means that if your random number is for example 1, after substrating the speed value from the position, the program will keep running inside the switch statement executing the case 2 and 3, so the case 3 will be always executed, making the object move to the bottom and the case 1 will be more ...


2

The classic standard answer for single-threaded games is to render first, then update game logic, and only then call your SwapBuffers. while (running) { draw(); update_game_logic(); GL_SwapBuffers(); } If you render first and then update game logic, the GPU can continue processing the submitted rendering commands while the game logic is updated on ...


2

There are some games which actually use at least two threads - one for rendering and one for gameplay. While the rendering thread renders the current gamestate, the gameplay thread calculates the next. But this software architecture is a lot more complex than it seems at first glance. If implemented poorly it can actually hurt performance. One problem is ...


2

Everything has to be in the loop, otherwise they can't be rendered. The question is, should they be there by themselves or hidden behind function/classes? This is an organisation question, as in, all results work, but what's "better" depends on you. One way to solve this, is to have an abstract class that implements some functions like update and draw. This ...


2

After looking further into the differences between the Bullet libraries and my own project turns out the runtime libraries were different. Multi-threaded Debug (/MTd) is the default after building Bullet. Changed it to Multi-threaded Debug DLL (/MDd) and it works fine!


Only top voted, non community-wiki answers of a minimum length are eligible