Jump to content

  • Log In with Google      Sign In   
  • Create Account

Pink Horror

Member Since 02 Jul 2013
Offline Last Active Today, 01:41 PM

#5293966 responsiveness of main game loop designs

Posted by Pink Horror on Yesterday, 02:51 PM

just cause you can only draw the screen once every 8 games turns doesn't mean you should let the computer move every turn and only let the user move every 8 game turns.

There should also get to be one human player for every core involved, or else the computer is ganging up on the player.




#5293137 Wrapper Function for lua_register?

Posted by Pink Horror on 23 May 2016 - 07:04 PM

Lua is written in C and thus cannot interact interact with C++ (there is no well-defined C++ ABI and as such 'calling a member function' is an unsolvable problem because different C++ compilers have very different idea what exactly that means and how to do that).

Lua is written to be capable of building in C or C++, and it is distributed as source code, so it doesn't need a well-defined ABI to interact with other C++ code. You can build it to match however you're building the rest of your code.




#5292932 Confused About Frames Per Second

Posted by Pink Horror on 22 May 2016 - 03:44 PM

I am confused however because it typically ends up being > 1000 fps. If it drops below 400, I start to notice a lag. If it were to run at 60 fps it would be cripplingly slow. But 60 fps is what most games run at, isn't it? That is my understanding anyway. Why are the numbers I'm seeing not matching up with my understanding? Is this method incorrect?

It's your own code. You should be able to describe what is happening better than "lag". You should be able to see in your code what is happening.

I didn't see an answer to this question: (Please excuse me if I missed it.)

 

1.  I assume your objects all are moving based on the deltaTime?!  If not, you will need to make that change because if not, things will move at different speeds on different computers.

To be clear, where in your code do you determine how far something should move in one frame? Does the time factor into it? You're almost certainly doing it wrong, if frame rate breaks your game in any way other than how it looks.




#5292550 Introducing Stanza: A New Optionally-Typed General Purpose Programming Langua...

Posted by Pink Horror on 19 May 2016 - 06:50 PM

That tab thing gives me an idea. If I ever make a language, you'll be forced to have whitespace around any binary operators. No more "a+b" in my language. The inherent productivity will be huge.


#5291986 Trying to draw area from image fails.

Posted by Pink Horror on 16 May 2016 - 08:58 PM


float topborder    = (1 / n)	  * (t - 1);
float bottomborder = 1 - ((1 / n) * (n - t));

-> Topborder results out of the selected square - 1   times  1/n  

-> Bottomborder is   1 minus  1/n times  the ammount of squares minus the chosen one

 

Let's think about this really simply.

We'll pretend you have a texture that is 8 units tall (I'm using "units" because I don't want to bring pixels into this). Each image you want to display is 1 unit big. There's no width - we only care about height.

If I want to draw image #1, the top is 0/8, and the bottom is 1/8. The next pair is 1/8 and 2/8. The next is 2/8 and 3/8. The next is 3/8 and 4/8. Do you see a pattern here?

(1/n) * (t - 1) ... looks ok
(t - 1) / n ... that looks a little better

1 - (1/n) * (n - t) ... oh dear, let's see what we can do to check this.
(n/n) - (1/n) * (n - t)
(n/n) - (n - t) / n
(n/n)  + (t - n) / n
(n + t - n) / n
t / n ... that checks out, too.

I guess it's just the integer math stuff mentioned above. You still might want to try to keep the math simple, if possible.

Edit: Note, it's common to save a reciprocal like (1/n) to a variable, and multiply by that instead of dividing by n. However, I don't write the math that way on paper (or type it like that into a forum).




#5291727 Templated Function results in Circular Inclusion

Posted by Pink Horror on 15 May 2016 - 02:03 PM

Why is IApp inheriting from Component? From what we can tell here, a Component is something that has a pointer to IApp. Is that just going to be null for the actual IApp, or will it point to itself? I have a feeling you don't really need to inherit from it.

Circular references aren't always bad, but they are still something you can try to avoid.

If necessary, you can split the definition of the templated function out of the header file defining the class, and put it in its own file. Or, you could put both of these classes in the same header and just do everything in the right order. The two classes depend on each other being included together anyway.

Still, this kind of problem is a sign that maybe your design needs rethinking.


#5291620 Loading outward from a point

Posted by Pink Horror on 14 May 2016 - 03:56 PM

Okay, Ill explain in more detail. I calculate where the player is in chunk position, so I know which chunk they are in. So, what I want to do is:

 

1. Load that chunk

2. Load the chunks surrounding that chunk

3. Repeat 2 with the new chunks (imagine an expanding circle)

 

Even more example:

 

4  4  3  4  4

4  3  2  3  4

3  2  1  2  3

4  3  2  3  4

4  4  3  4  4

 

(Numbers in order of loading)

The generic way to expand outwards through a graph is Dijkstra's algorithm for a shortest path tree.

You would load the player's chunk, then stick all of its neighbors into a queue that's sorted by distance to the player. Then keep taking new chunks out of the queue, loading them, and putting the neighbors into the queue (while keeping track of which ones were already loaded, so you don't load them again). You can stop when you've loaded enough chunks or when the queue is empty.




#5291357 when to use concurrency in video games

Posted by Pink Horror on 12 May 2016 - 07:37 PM

 

The problem with multithreading is knowing how to do it. Whenever you have a thread manipulating a variable or data structure, it makes them unavailable to other threads unless you declare it with "volatile".

 

 

Multithreading is a powerful tool, but it's easy to lock up your code if you do it wrong.

If you use volatile for multi-threading, you're doing it wrong.




#5290917 My game ends up being boring

Posted by Pink Horror on 09 May 2016 - 10:09 PM

Just judging by photos for a few seconds (like a real phone game shopper!)...

ZigZag is named "ZigZag". Your game is named "Car Survive". ZigZag sounds better.

ZigZag's photos suggest some creativity in level design. They, well, zig zag all over the place. It also looks like there is some sort of collectible. Your photos have a straight segment, and a slightly bent segment.

The car doesn't really fit in. Is it animated? If that's your "sweet graphics", I'm sorry. I don't see anything sweet about it. ZigZag uses a little lighting ahead of where the ball is moving. It has a UI. The thicker path helps fill the screen a little more, and gives some depth to let you know the path is high off the ground.

In the end, if it makes you feel better, I wouldn't play either of them.




#5289641 Which alignment to use?

Posted by Pink Horror on 01 May 2016 - 05:28 PM

On problem I see though is that default-move-ctors will not properly move PoD values like integers, which means that sometimes classes will be left in an invalid state. Not so much a problem for containers, in fact I'm not sure how much of a problem that actually is. I decided to keep some explicit move-ctors specifically due to this, but I might need to evaluate it again.

What do you think is the "proper" way to move an integer?




#5289183 Which alignment to use?

Posted by Pink Horror on 28 April 2016 - 08:40 PM

 

Also, be very wary of the code your example indicates you might have. A vector is a _very bad_ choice for the backing store of a generalized memory pool as it can and will reallocate and move objects in memory, which can lead to all kinds of undefined behavior if your Component types are not strictly PODs (as in is_pod_v<Component> == true). The reason is that when the vector resizes, it thinks its just moving char's, which are trivial to move. A general class however might have a complex move constructor. Even a seemingly-simple class can end up having back-references (hidden ones inserted by the compiler!) that will fail to be updated and lead to all kinds of crashes or other nastiness. Although in this particular example, since your ComponentPool is a class templated parameterized over Component, it makes far more sense to just have a vector<Component> and let vector deal with alignment and all that jazz.

 

Even if they are PODs, the reallocation also invalidates all the pointers to the Components you've created.




#5287705 Should you load assets/resources at runtime or compiletime?

Posted by Pink Horror on 19 April 2016 - 06:54 PM

"Compile-time" loading, that is, embedding the resource into the executable, has the advantage of the resource always being available. There's no (reasonable) way for the asset to "not be there," so it's a good thing to use for very important, low-level assets, such as your default shaders, fallback "object not found" models and materials, et cetera. However, every resource you embed this way bloats the size of your executable, and they're hard to change or update, so you should use them sparingly and only for things that are very important.

 

"Runtime loading" is reading the assets from a file on the disk or elsewhere. These are way easier to update and patch and you can usually control the layout of the file better (or at least with less effort), which is useful for optimizing loading and patching. The downside is that the data can go missing relatively easily, so you have to have fallbacks or error handling in place.

 

Most of your data should probably be loaded at runtime. The advantages in control (and thus in perf) are significant. It's not true that "compile time loaded" data is faster at all. That's basically never the case in practice, especially if you're going to put all your data into the executable like that. It still gets read from the disk and if there's enough of it will get paged in and out just like anything else. Embed only the most critical of resources.

If you wanted to go nuts with building assets into executables instead of reading files, you could put them in DLLs. Then you can load and unload the assets and the code that goes along with them at run time. Each level could have its own DLL. However, I must say, this is probably a bad idea.

I can swear I've worked on some project where they had a DLL filled with nothing but assets, but I don't remember what it was.




#5287548 Optimizing Generation

Posted by Pink Horror on 18 April 2016 - 05:32 PM

Thanks. So, it's a class. I wonder if it could be a struct, or just a simple enum.

Your generation program is probably still spending time allocating all of these objects, which each contain little to no data. Do any of the child classes have instance data they actually need? I don't see anything passed into their constructors.

If I was focused on generation speed, I would switch away from this object-oriented design for individual blocks. You could still create a data-oriented design that looks up a block processor based on its type and has all those same virtual functions in it. I suppose, theoretically, that might be slower to use, except you'll be scanning through a much smaller amount of memory when processing blocks. You always have to measure these things, of course. If blocks need some instance data, you could pack an enum for block type and an id and/or seed into a struct, and use the seed to figure out whatever other data the block needs on the fly.

As a half-measure, if the individual objects for any particular block type are all the same, you only need one instance of that class. Instead of assigning new blocks, you could reuse the same block instance over and over. For example, why does the system need more than one copy of BlockEmpty, ever? Of course, if you switch to a struct, this no longer applies.




#5287401 Memory Allocation

Posted by Pink Horror on 17 April 2016 - 10:42 PM

Why are you allocating sizeof(struct Node *) bytes?

Also, if you want to make sure your queue class works, try compiling a queue of something like std::string instead of int, and fix all of the compilation errors you'll get from that.




#5286941 Optimizing Generation

Posted by Pink Horror on 14 April 2016 - 05:27 PM

I'm curious, what is the definition of your Block type?






PARTNERS