Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Feb 2006
Offline Last Active Today, 08:34 AM

#5256208 Generating multiple versions of the same enemy.

Posted by gdunbar on Today, 08:36 AM

Are you familiar with using a debugger? If you set a breakpoint in eneMove_Tick and step through (looking at variable values as you go), it should rapidly become clear what is going wrong. If you are good with a debugger, this should be a lot easier than trying to figure out what is going wrong by inspection. If you are not familiar with a debugger, this is a perfect time to start! This is a skill that you will need and use often.


I'm not great at understanding code through inspection. If I was to try to understand your code better, I would probably walk through it in a debugger myself.


Good luck!


#5254609 RPG item/spell/combat system

Posted by gdunbar on 29 September 2015 - 09:49 AM

I'm the author of a real-time pausable RPG. To answer your basic question, "Do I have to do all that stuff?" Yes, you do. In fact, I think you simplified; for an attack, my code runs three timers. One for a character preparing to attack, but not yet attacking, who should display a fighting animation. Second, when the character actually is attacking, to display the attacking animation. And third, when the character is recovering from his attack, displaying a recover animation (i.e. moving his sword back from the extended position to the ready position). Real-time is complicated!


Now, how to handle it in code? For your action class, I have a similar set of classes. However, I subclass depending on the particular action. So "attack with a weapon" in one subclass, "cast a spell" is another, etc. Is something like that possible in your architecture? If so, you should be able to avoid having one mega-action class. I actually have one giant class that handles running all the actions through a switch statement. I'm not proud of this architecture, but there are not that many types of actions, so I live with it, and it works fine. You can probably do better than that, though, if you are writing code from scratch, by moving some or all of the action-running code into the sub-classes.


Hope that helps a little,


#5253439 Is it possible to optimize this? (keeping a small array in registers)

Posted by gdunbar on 22 September 2015 - 07:34 AM

Caveats: I'm not really good at this kind of optimization. It should properly be performed at the assembly level, and I'm just not that good at it, especially on modern CPUs where performance results are often surprising. (Fewer instructions doesn't mean faster). My level of skill is about "Don't do anything unnecessary, and make sure everything fits into the cache".


But here at some things that I would try, if confronted with this problem.


1) sum is a tempting target. Could you calculate sum when you calculate dist, instead of in this loop? If you use the same dist array for more than one run, that could save a little time.

2) In the second loop, you add sum to every element of matchups. Could your algorithm just assume that matchups is normalized to start at sum? Or maybe apply sum when you access the matchups array later, instead of adding it every time?

3) You are having trouble getting your compiler to vectorize loops for you. I'm not good at this either. But you could try a couple of things. One would be to try a different compiler. I'm completely out of date here. But certainly you could try Visual C++. Intel's C compiler used to be known for optimization. Even if your target platform isn't supported you could "borrow" the assembler output.

4) Or, split your loops into multiple loops until the compiler vectorizes at least one of the loops. matchups[i] = sum + dist[i] certainly should vectorize on its own, I would think.


Anyways, just some thoughts. As I said, I'm not great at this, so I would just blunder around trying stuff, and maybe something will give a performance boost. Actually, I guess I would try to find someone good at assembly optimization, but you're probably already looking.




#5243413 default install folder for windows game

Posted by gdunbar on 29 July 2015 - 12:05 PM

I'm using NSIS, not InnoSetup, but I install to:


Which works out to "C:\Users\gdunbar\AppData\Local\TotAW" on Windows 7. I believe when I researched that this was "the right place" to put an application such that it could be installed and run by a non-admin user, but I don't have that research handy. Seems to work well enough.


Good luck!



#5222315 Messing with the depth buffer for skybox effect

Posted by gdunbar on 09 April 2015 - 04:09 PM

EDIT: Hey you're right, if I draw the planets and skybox first and then clear the z buffer, I should get exactly the output I want. I guess the only complaint would be that often the skybox takes up very little of the screen, and is therefore usually drawn last.


You're worried about the performance of drawing the full skybox, when usually it would be mostly blocked by objects in front? I'm hardly an expert on graphics performance but I wouldn't think it would be a big deal.


If you're really worried, you could experiment by drawing the skybox a bunch of times per frame and see how many you can do before it affects frame rate. If the answer is in the single digits, maybe worry about it... if in the hundreds, safe to ignore. That would be easy enough to do, and should quickly assuage your fears without doing serious profiling or anything.



#5222300 Messing with the depth buffer for skybox effect

Posted by gdunbar on 09 April 2015 - 03:24 PM

What if you just clear the z-buffer after drawing your planets, but before drawing everything else? You could even futz with the projection matrix at the same time, and, as you say, "make it real" by drawing the planets at their proper distance.



#5195891 Writing code more general

Posted by gdunbar on 02 December 2014 - 09:46 AM

The void pointer thing is troublesome. I may be missing some of the fine points, but to me, the point of having an interface like IMeshLoaderPlugin, and a method like IMeshLoaderPlugin::loadFile, is that, given an IMeshLoaderPlugin, you can call loadFile() without knowing what kind of plugin you have. In this case, that is lost; if you have an assimp plugin, you have to give it an AssimpDesc or it will fail. Worse, it will fail at run-time, not at compile-time.


So, my question to you: Is there some good reason to have a generic IMeshLoaderPlugin::loadFile method, and the related IMeshLoader::load function? Why not just have separate AssimpLoader::loadAssimpFile and HeightmapLoader::loadHeightmapFile functions? You may well be getting some other benefit from the generic IMeshLoaderPlugin::loadFile method that I'm just not seeing. However, if I were you, I'd be looking at my class abstraction carefully. If you really have plugins that are not interchangeable, then you probably don't need any of this enum stuff in the first place.


Anyways, I hope that's a little helpful. I've probably asked more questions than supplied answers. Good luck!


#5168350 How dangerous is returning a initialized pointer in C++?

Posted by gdunbar on 22 July 2014 - 06:07 AM

All the discussion about smart pointers is great. However, it is possible to make the original code safe (or safer) without using smart pointers. You need to use a static function for Create, instead of a standard function. A static function is part of the class, but doesn't access any of the class members, and thus is safe to use even if you don't have an instantiated object. So, change:

EngineAPI *Create();


static EngineAPI *Create();

And change:

gEngine = gEngine->Create();


gEngine = EngineAPI::Create();

Again, all the smart pointer and ownership discussion is great, but static Create functions are a pattern you'll often see, and are perfectly valid.



#5139766 Removing Large number of objects from vector immediately.

Posted by gdunbar on 17 March 2014 - 12:39 PM

How have you profiled this code? I suspect that the "delete list1;" call might be pretty quick compared to the allocations and push_back() calls (which will dynamically resize your vector). First step is to verify that the slow part is actually what you think it is.


Second step is to be sure you are using a non-debug build, as allocations and deletes can be significantly slower with debug builds.


If you are using Visual Studio, be sure to turn off the STL debugging stuff, too, as that can be frightfully slow.


OK, if all of that doesn't help (and I think it will), the big optimization I can think of is to move away from std::vector and use the C-style array allocation mechanism directly. Then you can allocate and free a while bunch of objects at once. This is not nearly as maintainable, though, so be sure to exhaust other possibilities first.


Hmm... an object pool could work too. Also to be avoided if possible.


Good luck!


#5000997 Virtual still the bad way ?

Posted by gdunbar on 14 November 2012 - 02:03 PM

Virtual functions are the bedrock of modern, object-oriented C++, and are unlikely to be a significant performance bottleneck on today's relatively fast processors. I recommend you proceed with using them. If at some point in the future, as a result of performance profiling, you do identify a virtual function or two that are slowing your code down (perhaps used very often in a tight loop), then address the problem locally at that time.

Good luck!

#4957634 Seeking in Direct Show

Posted by gdunbar on 10 July 2012 - 09:54 AM

No, that's not what you want at all. You aren't writing your own filter, just using existing filters.

The documentation isn't great, but this topic "Seeking the Filter Graph" should help:


It's the IMediaSeeking interface that you want.

Good luck!