• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Oammar

Strange Visual Studio Release Mode Behavior

11 posts in this topic

I am encountering a strange issue when attempting to build my project for release mode. It works fine in debug mode, but my Vector3D object seems to be returning garbage when I am setting one vector equal to the other.

 

I've been wondering if it has something to do with not having a operator=, except the default one given by the compiler, but I'm not sure. It is strange. I was also initially wondering if the compiler was executing my code out of order due to release mode compiler optimizations, but then I noticed that my Vector3D was just garbage values for some reason.

 

This is what I am doing:
 

Vector3D playerPos = mainPlayer->getObjectPosition(); // Doesn't do anything in release mode (playerPos remains as garbage)
playerPos = this->WorldToScreen(&playerPos);

All that getObjectPosition() does is:
 

Vector3D& GameObject::getObjectPosition()
{
  return this->position;
}

Thank you for any insight you can give me on solving this issue.

0

Share this post


Link to post
Share on other sites

Is it possible that mainPlayer->position hasn't actually been initialized at that point in the program? When I see an accessor appearing to spit out garbage in release but not debug, that's usually the first thing I check. 

 

Also, how are you checking for these garbage values? If you're only seeing them in the debugger and the program is otherwise behaving as expected (or even if it isn't), that's not too unexpected. Very optimized code can make a debugger very confused.

1

Share this post


Link to post
Share on other sites

I just checked, I added a std::cout statement above to check, and it is initialized to the expected result. It seems to be having issues placing the result into the Vector3D for some reason.

 

The problem seems to be duplicated within debug mode when I create a custom assignment operator:
 

Vector3D& Vector3D::operator=(const Vector3D& rhs)
{
  this->set(rhs.x, rhs.y, rhs.z);
  return *this;
}

If I get rid of that assignment operator it works fine in debug mode.

 

Here is some more code on what I am doing:

  float x = mainPlayer->getObjectPosition().x, y = mainPlayer->getObjectPosition().y, z = mainPlayer->getObjectPosition().z;
  std::cout << x << " | " << y << " | " << z << std::endl;
  Vector3D playerPos(x, y, z);// = mainPlayer->getObjectPosition();
  std::cout << playerPos.x << " | " << playerPos.y << " | " << playerPos.z << std::endl;
  Vector3D nPlayerPos = this->WorldToScreen(&playerPos);
  std::cout << nPlayerPos.x << " | " << nPlayerPos.y << " | " << nPlayerPos.z << std::endl; // INVALID RESULT

I was inspecting the matrices within WorldToScreen and they appeared out of order in the release mode, however, that may have just been the compiler debug mode in release confusion.

Edited by Oammar
0

Share this post


Link to post
Share on other sites

That looks fine to me given the context you've provided. What happens inside of set()? What are you expecting to see and what sort of "garbage values" are you seeing, exactly?

1

Share this post


Link to post
Share on other sites

set() sets the x y and z component of the Vector.

void Vector3D::set(float x, float y, float z)
{
  this->x = x;
  this->y = y;
  this->z = z;
}

The value I'm expecting to see after the WorldToScreen is: | 512 | 384 | 0, which is what I get in debug mode without the custom assignment operator, but in release mode I'm getting:
| 4.57501e+013 | 2.47714e-039 | 4.26061e+013

I can't help but wonder now if the release mode is shifting my matrices around for some reason, I'm not sure tho, I don't think they would be nor how. I'll print those out to see if they are for some reason.

Edited by Oammar
0

Share this post


Link to post
Share on other sites

There definitely seems to be something wrong with my library when my project is accessing it. I call the WorldToScreen function in my library and get those invalid results, but if I pull out that code from within my library and execute it manually in my other project it produces the correct results.
 

0

Share this post


Link to post
Share on other sites

Thanks for the insightful posts. It turns out the problem was definitely in the WorldToScreen function, I was returning a local variable as a reference, which I should have known not to do, but that was the problem.

 

I changed the function to:

Vector3D GameZone::WorldToScreen(const Vector3D& worldPos);

Instead of:

Vector3D& GameZone::WorldToScreen(const Vector3D& worldPos);
1

Share this post


Link to post
Share on other sites

Thanks for the insightful posts. It turns out the problem was definitely in the WorldToScreen function, I was returning a local variable as a reference, which I should have known not to do, but that was the problem.


Get in the habit of compiling with the highest warning level and with all warnings treated as errors. Microsoft's compiler is quite capable of diagnosing this mistake for you and catching it long before it turns into a forum thread. smile.png
2

Share this post


Link to post
Share on other sites


Get in the habit of compiling with the highest warning level and with all warnings treated as errors

 

i actually use second highest warning level, so i don't get 5 billion "yo dude! i'm in-lining this!" warnings. inline is the only warning i get at level 5, so i just kicked it back down to level 4. really i ought to suppress the inline warning and kick it back up to level 5.

 

i don't treat warnings as errors. that way you can have unused variables in a routine you're writing and still see if it compiles. but in general, the code is written so it generates no warnings (except inline warnings).

 

and finally, i develop in release mode only. if it works in release mode, it'll work in the final version, which is all that really matters. i've experienced and heard of too many cases like this where incorrect code works in debug but not release mode. so long ago i said to heck with debug mode all together.

 

for debugging, i use trace variables i can assign values to and then display.  for optimization, i use hi-rez timers and the trace variables to time sections of code and display the results.

 

no debug mode, no debugger, no profiler.  its not the usual way of doing things, but it avoids debug vs release mode bugs. its been years since i had a bug complex enough that it even tempted me to use a debugger. and i can hook up a timer to a section of code faster than the profiler can even load! but of all the things i do, clean simple straightforward code is the #1 weapon vs bugs. 

1

Share this post


Link to post
Share on other sites

Get in the habit of compiling with the highest warning level and with all warnings treated as errors

 
i actually use second highest warning level, so i don't get 5 billion "yo dude! i'm in-lining this!" warnings. inline is the only warning i get at level 5, so i just kicked it back down to level 4. really i ought to suppress the inline warning and kick it back up to level 5.
 
i don't treat warnings as errors. that way you can have unused variables in a routine you're writing and still see if it compiles. but in general, the code is written so it generates no warnings (except inline warnings).
 
and finally, i develop in release mode only. if it works in release mode, it'll work in the final version, which is all that really matters. i've experienced and heard of too many cases like this where incorrect code works in debug but not release mode. so long ago i said to heck with debug mode all together.
 
for debugging, i use trace variables i can assign values to and then display.  for optimization, i use hi-rez timers and the trace variables to time sections of code and display the results.
 
no debug mode, no debugger, no profiler.  its not the usual way of doing things, but it avoids debug vs release mode bugs. its been years since i had a bug complex enough that it even tempted me to use a debugger. and i can hook up a timer to a section of code faster than the profiler can even load! but of all the things i do, clean simple straightforward code is the #1 weapon vs bugs.


Turn on warnings as errors + highest level warnings. Like Sean pointed out, you'll catch a ton of bugs this way before you even spend the time loading up your game to see if it broke. Plus warnings as errors will prevent you from forgetting about warnings in a file that compiled - since the compiler won't re-build a file that only built with non-erroring warnings.

The only inline-related I'm aware of is some compilers will tell you they aren't inlining something you declared inline. But you probably shouldn't be declaring anything inline anyway, since it doesn't do what most people think it does (it allows ODR violations, but doesn't actually inline your code).

I don't know how you even work on anything larger then hello world without a debugger... It's so much easier to knock out almost all of your bugs in debug mode and then only concentrate on stuff that shows up in release in release.

And please, use a profiler. Sticking timers in your code not only doesn't measure what you think it does, but changes the code, thereby changing how fast it runs, how the compiler optimizes it, and either exposing or hiding threading issues and the like. Timers also can't tell you why things are slow, like repeated Load-Hit-Stores or cache misses due to algorithm design or object layout - both things a good profiler can easily show you. Edited by SmkViper
2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0