Jump to content
  • Advertisement

Oberon_Command

Member
  • Content count

    4229
  • Joined

  • Last visited

  • Days Won

    1

Oberon_Command last won the day on June 21

Oberon_Command had the most liked content!

Community Reputation

6222 Excellent

1 Follower

About Oberon_Command

  • Rank
    Contributor

Personal Information

  • Role
    Programmer
  • Interests
    Design
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. The problem your first code block is trying to work around is the "iterator invalidation" that occurs when you erase an element. Typically pre-C++'11 code to erase a bunch of specific elements from a container would look like the following: for (it = container.begin(); it != container.end(); ) // note that we don't increment the iterator here! { if (condition(*it)) { it = container.erase(it); // erase returns the new iterator we're to use, so we don't have to mess around with decrementing iterators } else { // we didn't erase, so NOW we can increment the iterator ++it; } } The modern version would use the algorithms library and lambdas (ie. anonymous functions) to do the same thing with less code, via the "erase remove" idiom. // first we move all the elements we're going to erase to the end of the container // effectively, this partitions the container into elements we are going to keep and elements that we are not // note the use of auto to get around having to know the iterator type and even the object type! auto removedIt = std::remove_if (std::begin(container), std::end(container), [](auto&& elem) { return condition(elem); }); // removedIt now points to the first element we are going to remove, and every subsequent elements is also to be removed // therefore, we can erase them all at once container.erase(removedIt, std::end(container)); Or, more succinctly: container.erase( std::remove_if ( std::begin(container), std::end(container), [](auto&& elem) { return condition(elem); }), std::end(container)); Both of these should work fine with std::list.
  2. You appear to be conflating allocation (the process of setting aside memory for use) and construction (initializing the memory, causing it to be a valid object). Those are different things, though from the perspective of your C++ code, typically they happen (or appear to happen, as you've discovered with stack-allocated objects) at the same time. It is possible to allocate memory for an object on the heap without constructing it (at that time), as well, though the new operator (by default) does both for you. Similarly, "destruction" does not necessarily mean "deallocation" - it just means the destructor is called on the object - though the delete operator (by default) also does both and a stack-allocated object will do both when it goes out of scope. This allows for some types of custom allocator that might destroy an object without releasing its memory so that a new object can be constructed in the same memory block as the old one, for example. So, no, the books and tutorials are not lying to you.
  3. Not quite. Globals in C++ aren't stored on the heap or the stack, they're stored in the executable's "data segment".
  4. Oberon_Command

    As a game dev, what are you most afraid of?

    This one. I'm not interested in receiving death threats.
  5. Oberon_Command

    Specifications of a Gameplay Programmer?

    The most succinct job description I can come up with for a gameplay programmer is "making toys in a game engine for designers to play with." Engine programmers (typically) build the underlying technology that the gameplay programmers use.
  6. That's not very much work at all. I think I spend more than double that time just compiling my code (ie. not actually working) every morning.You'll find as you gain experience that 20 minutes is a trivial amount of time - 20 minutes is well in the noise in the lifetime of any substantial project. It's certainly not an excuse I would accept to not to do things properly. If you're not willing to accept that the book you're using won't actually be all that helpful to you, you might try not bothering trying to find the source and instead reconstructing it from the book. I suggest that you will probably learn more that way. And yes, get rid of the old compilers. You mentioned in another thread that you got some code working in VS 2017, just use that.
  7. Oberon_Command

    Simple trig problem driving me crazy

    Shouldn't sin and cos be reversed there? Ie. newPosition = (cos(rotationRadians) * offsetX, sin(rotationRadians) * offsetY) + oldPosition
  8. Oberon_Command

    Defining AAA

    The actual tweaking part can be done in minutes, yes. But that's not the part that takes all the time. The part that takes time is humans playtesting it and then deciding what the tweaks should be, if any, making the tweaks, then going back and playtesting it again to see if the tweaks made the game more fun.
  9. Oberon_Command

    Defining AAA

    That won't help you if the physics data isn't related to the object's physical geometry. That is quite often the case. The character physics in a first-person shooter rarely has any kind of (mathematical) relation to the character models. Usually the parameters are hand-tweaked by designers until they feel fun. To the best of my knowledge, tweaking for fun cannot be automated, because "fun" refers to the player's emotional reaction to the system as a whole. The purpose of a video game is to elicit that emotional reaction. How do you automate a process that necessarily involves human emotion to evaluate it? There's no physical reason why the TF2 Scout would run so much faster than the TF2 Sniper, for instance - Sniper is taller and has longer legs and generally looks more athletic, yet Scout can not only run and jump much higher than him, Scout can also *double-jump!*
  10. I see the problem. As I suspected, it's the way you're erasing the thing from a vector: std::vector::erase invalidates the iterator you pass into it. If you try to iterate from the iterator, you'll get undefined behavior. Very common mistake, I've seen even seasoned professionals screw that one up. Mostly because they're not overly familiar with the standard library - which in modern code is a mistake in and of itself. The quickest way to solve the problem is to assign the result of erase() to i, since std::vector::erase returns a new (valid) iterator on completion, but in modern C++, you would write this quite differently, and in such a way that this wouldn't be a problem... effects.erase(std::remove_if( std::begin(effects), std::end(effects), [](const EFFECT* effect) { return effect->isDead(); }), std::end(effects)); for (EFFECT* effect : effects) { effect->Update(deltaTime * m_gameSpeed); } In general, you should a) make liberal use of the standard algorithms b) use a compiler that supports at least C++'11 so that you can use them without loads and loads of boilerplate. In modern C++ you want to avoid working directly with iterators.
  11. Oberon_Command

    Unity dropping Monodevelop a let down for small indie?

    I haven't seen the "text-editor-only" mindset much in the professional world, but "lifestyle minimalism" in general is definitely in fashion these days, especially among the young programmers living in the big cities where everything is expensive. Many millennials are worried that they won't be able to retire at all given the costs of living and stagnant wages these days. The common advice to address those fears is "don't buy things you don't need and if you can do without something, do without it." I guess when you get into that mindset you start applying that to everything regardless of whether it's a good idea or not. That aside, I do actually know someone who uses vim professionally, but it's not for the sake of lifestyle minimalism. When I asked him why, his response was "when I was younger, I had to switch IDEs with every project. I eventually just learned vim so that I wouldn't have to learn a new IDE with each project and my workflow would be consistent, meaning I could be a lot more productive." He still uses VS for debugging, though. When I was in school, I used vim was because I was working on the lab machines, most of which ran Linux or Solaris, meaning there wasn't any Visual Studio available. In addition to that, not all the machines had the same distribution, so I couldn't count on any one particular tool being there - apart from gcc and vim. I occasionally switch back to vim for the sake of nostalgia and because I've found living without intellisense forces me to design APIs that are easier to remember and use.
  12. Okay. That callstack indicates that the assertion is being thrown in APPLICATION::Update - every other function above it is in standard library code. Why don't you post the code for that function here?
  13. That's not specific at all. Again, I'm not psychic. What I'm looking for is the actual place in your code where the assertion is being hit. To get that, you'll need to do what I said earlier and attach the debugger, catch the assertion, then use Visual Studio's callstack window to see the top-most function on it that is in your code. Post that function on the forum and let's have a look at it. If you're having trouble with this very basic task, I again suggest you go to the chat so we can help you more directly than trying to guess how your VS is set up. I'm also a little unimpressed that you expect us to go and search for the source code that your project is based on, then somehow psychically work out where the problem is and what you changed in that code to cause the problem, when what is actually needed here is for you to put some effort into using the tools available to you to get the relevant information at hand.
  14. No, not at all. I know nothing about how you've implemented any of this, other than apparently a vector is involved. Nobody here is psychic, you know. Without any code or at least an in-depth explanation of the code that is failing, there's very little we can do. That being said, my clairvoyance says you should double check that you aren't invalidating your iterators by erasing elements from your vector while iterating through it, that being a very common mistake.
  15. https://en.wikipedia.org/wiki/Call_stack When you call a function, your program jumps to another place in the code. When a function completes, it needs to "return" to the place in the program where it was called from. To get back to the place in the code that called the function, it needs to store that information somewhere. You can think of that as a "stack" of function return addresses. Each time a function calls another one, another entry is put on the call stack. When you're debugging a program, Visual Studio should have a tab somewhere that shows what functions are on that callstack. If I have a a program that calls a function called Foo, which calls a function called Frobnicate, which calls a function called YourMom, then if you put a breakpoint in YourMom, Visual Studio should show you something like this when the breakpoint is hit: YourMom Frobnicate Foo main Note that the most recently called function is on the top, while the functions that called it are beneath it. The idea of a call stack is really fundamental, so make sure you get this idea good and internalized. So fundamental, in fact, that if you didn't know what it was before, then I suggest this thread should have been put in the For Beginners section. If you're having trouble with the actual tools, then I suggest heading to the GDNet Discord chat or some Visual Studio-specific resource.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!