Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Kyall

Member Since 25 Mar 2005
Offline Last Active Dec 08 2012 01:12 AM

#5008104 Is C++ too complex?

Posted by Kyall on 07 December 2012 - 07:05 AM

Header file & separation isn't a problem. I like it, the lack of it is one of many reasons for hating on so many inferior languages. It's not OCD about why can't I organize things the way I want as much as I would like to have headers available when I don't have a sylladex to tell we what every function and it's parameters are. Header/code separation makes programming easier.

Many of the advanced features of the c++ language have pretty limited use. And there is the issue that these features can take a bit of time and experience with the language to understand. The problems that exist are when these features become core components that are absolutely necessary to achieve a design, and then that design happens to be a core feature of a game or game engine or a piece of code architecture. This is where it gets to the point that every programmer on the project needs to have an advanced understanding of c++ to be able to do anything. So a solution is to avoid these features and find other simpler solutions. I don't want to hate on less advanced programmers here, but the fact of the matter is that I know a lot more about the c++ language now then I did 5 years ago, and I programmed exclusively in c++ 5 years ago and never failed to build what ever it was I wanted to build. The problem is using these features is an easy and simple alternative to building tools that extend the compilation process to generate metadata about the project to achieve the same purpose - or any other complicated task that can be achieved with the advanced features.

And this is the part where it all gets messy. The features are perfectly stable and reliable, it's not necessarily a house of cards, but the code degenerates into something not even reminiscent of what I say c++ code looks like. And use of the system, or at least users using the system comfortably without doubts as to it's quality, becomes dependent upon the relevant skill level in c++ of the programmer. It's a bit like the language itself suffers from something a lot of software suffers from, bloat. And it needs a refactor or refinement to bring it back into sanity.

The cx11 I reckon is very good, if you're using the smart pointers you can bring your class design back to what it hypothetically 'should be'. No need to worry about implementing the copy constructor or assignment operator as the new features take care of this for you. A continuation down this path of introducing features to bring things back to sanity would be welcomed by me. This is just one thing though, it seems like there should be more. And no I VILL NOT USE BOOST. Don't even. Just don't.

EDIT: -9 points for saying that advanced c++ didn't resemble simple c++, and expressing a general feeling that I don't like the inconsistency. I'm adding this:
127.0.0.1 gamedev.net
to my hosts file.

Bye everybody.


#5006194 Is C++ too complex?

Posted by Kyall on 01 December 2012 - 09:03 PM

I'm thinking you need a programming application test instead.... A really simple one. That contains a loop requirement...


#5006005 Is C++ too complex?

Posted by Kyall on 01 December 2012 - 05:06 AM

It's not really hostility if you don't get more replies. We have this unfortunate thing of not posting replies when we're not completely confident we know this answer. So yeah... the best way to get help from programmers is asking directly....


#5005610 Is C++ too complex?

Posted by Kyall on 30 November 2012 - 01:42 AM

I always want to improve my C++ knowledge and this time around this means finding out what parts of C++ aren't any good, so I thought I'd field a question to the experts: what parts of the c++ language are too complex to the point they interfere with writing good code and should be avoided as much as possible. Should I always use the stdio and not iostream for example, dynamically allocated memory in classes vs putting it in structs. What's the debate on what parts of c++ improve code, and the other parts that are over complicated and are damaging to code standards.


#5005218 Browser Cross-platform Cloud Based Game

Posted by Kyall on 29 November 2012 - 01:59 AM

I've been thinking about setting up a VPS for myself purely for the purpose of building some server-client tech that I could use in the future. My decision for this would be to get a linux debian server and program the server for that operating system. Since debian is pretty common amongst dedicated servers and VPS you can get, so if you get a VPS or dedicated server from a hosting company for the purpose of hosting a game you have pretty good changes of it being a debian. I'm rambling a bit cause I have to leave like 5 seconds ago, so I'll try and explain the rest and maybe you can piece the logic back together afterwards.

The user who administrates the server would set the settings for the game on their server, and then the players would pull configuration changes and updates from their server to their client install. This allows for different versions of the game to be run connecting to different servers so that you can gradually release new code to the public for updates and patches etc. Need to run, bye. Probably more to this but yeah. For a real time or any other type of network game where they need to set up their own configuration of the game play for their uses, I would build a Debian based server side application.


#5003663 Targetting Cues

Posted by Kyall on 23 November 2012 - 10:34 PM

It seems like you've pretty much solved the math for this and you're more or less curious about the design. What I've used in the past is 2 cross hairs along with auto aim. The first cross hair represents where the player is aiming, the second represents where an enemy closest to that crosshair is, and when the player moves the cross hair close enough the first one jumps onto the second to show a lock on, and all rounds fired go towards where the player's cross hair is. This started out as a solution for the z point of where the player was aiming in our 3rd person shooter and eventually became an aim assist that the player could use. It took some of the challenge of shooting out of the game, but it meant that the challenge of the game was getting into cover, and then selectively taking out the targets by the danger priority each target presented. Quite impressive that you've solved the mathematics of this given you have player velocity and direction and enemy velocity and direction to account for. For accuracy we scaled the cross hairs to represent the accuracy of the selected weapon and for some weapons that accuracy decreased as they fired so thee player would end up firing short bursts to keep the shots focused in the reticule. We also used different textures for the cross hairs of different weapons. Another thing to keep in mind with a third person shooter is, that you need to solve that z-axis based on what target you think the player is aiming at for the shots from the player's avatar to hit the target instead of go around it. Which is important when the player needs to fire deflection shots (aiming ahead of the enemy) to score a hit. It's not an issue in first person shooters however. We had a bit in the game where the player fired a turret in first person against fast moving flying enemies, it didn't have a lock on, but it was a bit of a pain to get the deflection shots working intuitively since we needed to use the projected Z position of the target the player was aiming at to solve the z in the equation of what direction the bullet should go.


#5003152 why is it recommended to make game with placeholders and do art last?

Posted by Kyall on 22 November 2012 - 01:31 AM

Greyboxing is a rapid iteration and cost saving exercise. The artists do produce the grey boxes, they are usually modelled, they're just not textured or very detailed. If you imagine a game level that's something like an office; with greyboxing instead of having desk, chairs, paintings on the walls etc, you'll just have walls, floor, and cubes in place of all the furniture. There's not much modelling to do but the artists can still model things faster than other people can (experience with modelling tools) so they would do the modelling, and what this gives you is a good mock up of what a level could be.

Producing actual assets, with textures, and high detail, is expensive in both time and money, this is why there are usually twice as many artists than programmers on a team. And the worst part is that given that expense, once you have the assets, you are stuck with them. Because there's never a good enough justification for throwing a level that has been fully detailed out, even when the setting ceases to work in the story and the layout ceases to be compatible with the mechanics.

So it's pretty useful for small and large teams; because you can build your assets and levels fast, essentially build large swathes of the game so you can iterate, without having to commit to anything, and without wasted hours down the road trying to make old assets fit a new setting or set of mechanics.


#5001049 Utilizing vectors to move entities in 3D space

Posted by Kyall on 14 November 2012 - 06:27 PM

Usually when we use vectors in math/physics/game development we use them as a 3-scalar value ( for 3D ) where each represents a magnitude along each axis.

[source lang="cpp"]class Vector { float x, y, z; Vector(float _x,float _y, float _z);}[/source]

If we create a vector that has value Vector( 1, 0, 0 ) we are saying that this vector is 1 along the x axis and 0 along the y and z. You've probably noticed that this vector describes a position in 3-point space just as well as it does a direction and a magnitude. Which means if you have your position of an object stored as a Vector( x, y, z ) and you have the velocity stored as a Vector( x, y, z ) then you add the two vectors together with the equation

result = Vector( x1 + x2, y1 + y2, z1 + z2 )

You have now calculated the result of moving that position by the other vector's magnitude and direction.

But why a 3-scalar to describe direction and magnitude, rather than a series of angles and a magnitude value ?

Mostly for mathematical reasons. A 3 scalar of direction and magnitude is more powerful and easier to use than an angle + magnitude representation of the same value. A magnitude and direction from angles/magnitude can be calculated as:

result.x = cos( direction.x ) * magnitude - sin( direction.y ) * magnitude
result.y = sin( direction.x ) * magnitude + cos( direction.y ) * magnitude


I've tried writing more to this post. But the simple fact of the matter is that an introduction to vectors and linear geometry would end up being 10 pages long. Basically, don't use angles/magnitude to represent vectors. That is not what a vector is.

A vector has as many values as there are axis in the system, and each of those values corresponds to the magnitude of the vector along that axis. A vector is x, y, z where x represents magnitude of the vector along x-axis, y represents magnitude of the vector along y-axis and so on. 2D/3D/4D doesn't matter. Magnitude along an axis however is an internal magnitude. The concept of magnitude itself is a representation that is not of the internal components, but of the sum of their parts.

So where do direction and magnitude come from ? These are a description of the two basic properties that you can derive from that internal representation; direction and magnitude are not the components of a vector, they are properties of it.

The magnitude is obtained with
magnitude = sqrt ( x * x + y * y + z * z )

And the direction is obtained with
direction = Vector( x / magnitude, y / magnitude, z / magnitude )

Notice that the direction is also a vector. It's just a normalized vector. A directional vector has the property that it's magnitude is equal to one.

I'm not sure on what books are good for learning linear geometry. Which is what this is. I'm going to throw that out to the outfielder.


#4993612 Unreal Engine... How did they do it?

Posted by Kyall on 24 October 2012 - 06:46 PM

My quick and easy way to achieve something similar is for development purposes, split the game into two applications and have those two applications communicate over a local network connection.

The game application does most of the game stuff, but asset loading & use is separated out to the second application.
The second application does the asset loading, rendering, audio and other things that use large amounts of memory.

Game loads up, runs as it would, calls it's APIs to load in textures/audio/etc. Some of those loads are routed to the second application to load that data.
The game renders, sending a render command buffer to the second application which does the rendering.

This deals with a vast amount of the game data that has to be loaded from disk and keeps it in memory.

The next step is to hold the game data that is needed for game logic in the second application's memory. And then the next step after that is to give the second application a representation of the game's state so that when the game is reloaded it returns to the point in game play it was at when it was terminated.


#4993041 Favorite little known or underused C++ features

Posted by Kyall on 23 October 2012 - 03:33 AM

variable arguments
...
^ is awesome


#4989021 Why does my anti-virus program think my programs are suspicious?

Posted by Kyall on 11 October 2012 - 02:25 AM

I use AVG and it has the habit of reporting any application with

std::cout << (int value) << std::endl;

as being a backdoor trojan. You can deal with it simply enough by disabling the anti-virus while you're developing, or finding a way to stop it from active scanning your projects folder. But when it comes time to release you'll probably have to test your executable against virus scanners for false positives. When it comes to releasing an executable in a world with crap virus scanners does anyone have any pre-release tips ? Because I'd like to hear them.


#4988529 Code Sample Review Request

Posted by Kyall on 09 October 2012 - 05:15 PM

for ( list::iterator it = Actor::getActors().begin(); it != Actor::getActors().end(); it++ )
  {
   (*it)->update( timePassed );
  }

++it

The postfix increment, it++, creates a copy of the object prior to the operation for comparison of the old value, and it isn't necessary here, the prefix increment doesn't do this. so:

for ( list::iterator it = Actor::getActors().begin(); it != Actor::getActors().end(); ++it )
  {
   (*it)->update( timePassed );
  }

Don't compare against a function call in a loop, where you have

it != Actor::getActors().end();

Change it so you create a local iterator value called end, so you end up with:
for ( list::iterator it = Actor::getActors().begin(), end = Actor::getActors().end(); it != end; ++it )
  {
   (*it)->update( timePassed );
  }

And lastly (*it)-> looks like a bug. Without the class to look at to see that the *it operator is a dereference for the iterator and the class for actor to look at to see that -> is a valid reference for that class I'm just having alarms shoot off here. If that is valid syntax you need to put a comment in there to explain why you're dereferencing twice.

for ( list::iterator it = Actor::getActors().begin(), end = Actor::getActors().end(); it != end; ++it )
  {
   // The Actor class overloads -> because it is stored as a shared pointer (example)
   (*it)->update( timePassed );
  }

// Delete all Nodes, Actors and Cameras
  while( Node::getNodes().size() > 0 )
   delete (*Node::getNodes().begin());
  
  while( Actor::getActors().size() > 0 )
   delete (*Actor::getActors().begin());

  for( int i = cameras.size()-1; i >= 0; i-- )
   delete cameras[i];

Are you sure you want to delete the result of .begin() ? Once again I don't know how you're code works but this looks like an infinite loop to me.


for( int i = cameras.size()-1; i >= 0; i-- )
   delete cameras[i];


while( cameras.size() > 0 ) {
   cam = cameras.pop_back();
   delete cam;
}

you might want to leave your camera delete in to demonstrate that you know how to do a counting downwards for loop though

Otherwise the general quality of the code is better than what I had for my code samples when I started.


#4988280 Communicating with Programmers

Posted by Kyall on 09 October 2012 - 04:16 AM

As a programmer I fear that people might not understand me more than I might not understand them. But my brain tends to compartmentalize everything so I might seem like I don't have a clue what you're talking about sometimes.

"Whats the progress on it?"
"What what ? What it ? What is this it? "
"The thing we were talking about 5 minutes ago"
"Oh right, I reckon I've figured out how to do it, will tell you if I succeed"

Generally if a programmer ever says something you don't understand; make them explain it, jargon isn't jargon, it's a concept that has a name.


#4988254 starting game engine

Posted by Kyall on 09 October 2012 - 02:21 AM

Write games; not engines.

If you are going to write an engine, write it on a per-module basis, not as a whole big chunk. Do a rendering component, an asset management component, the architecture for the game etc etc separately and merge them. This way you have more reusable code as each component/utility is specific to itself. 'Black boxed'

This also makes it easier to throw stuff out or change it. Being able to throw bits away & keep the good stuff is part of a re-iterative process of building a good engine over a series of game projects.


#4985341 Designing Entity systems without global pointers to subsystems

Posted by Kyall on 30 September 2012 - 06:59 AM

// Updater template class
template <typename T>
class EntityUpdater {
public:

// Need to inherit to override this
virtual void Draw();

// Make this a singleton
static EntityUpdater<T> hInstance;
private:
std::vector<Entity> entities;

};

// Inherit it and override the update
class UpdateCat : public EntityUpdater<Cat> {

};


template <typename T>
void Register( void * entity ) {
   // If the singleton for the update of this entity type exists, then add this object	
   if( EntityUpdate<T>::hInstance ) {
	 // Add entity to the entities in EntityUpdate<T>
  }
}


You can then register each entity with Register<MyType> or you can use the template in a function pointer thing.

typedef void (*RegisterFunc)( void* ); 

struct TypeDefinition {
   RegisterFunc reg;
};


then later, and this is if you're using a reflection thing with your entity factory in the constructor for the type's reflection defition

cat.reg = Register<Cat>;

I might me missing an & there or something.




PARTNERS