• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By dp304
      As far as I understand, the traditional approach to the architecture of a game with different states or "screens" (such as a menu screen, a screen where you fly your ship in space, another screen where you walk around on the surface of a planet etc.) is to make some sort of FSM with virtual update/render methods in the state classes, which in turn are called in the game loop; something similar to this:
      struct State { virtual void update()=0; virtual void render()=0; virtual ~State() {} }; struct MenuState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; struct FreeSpaceState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; struct PlanetSurfaceState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; MenuState menu; FreeSpaceState freespace; PlanetSurfaceState planet; State * states[] = {&menu, &freespace, &planet}; int currentState = 0; void loop() { while (!exiting) { /* Handle input, time etc. here */ states[currentState]->update(); states[currentState]->render(); } } int main() { loop(); } My problem here is that if the state changes only rarely, like every couple of minutes, then the very same update/render method will be called several times for that time period, about 100 times per second in case of a 100FPS game. This seems a bit to make dynamic dispatch, which has some performance penalty, pointless. Of course, one may argue that a couple hundred virtual function calls per second is nothing for even a not so modern computer, and especially nothing compared to the complexity of the render/update function in a real life scenario. But I am not quite sure. Anyway, I might have become a bit too paranoid about virtual functions, so I wanted to somehow "move out" the virtual function calls from the game loop, so that the only time a virtual function is called is when the game enters a new state. This is what I had in mind:
      template<class TState> void loop(TState * state) { while (!exiting && !stateChanged) { /* Handle input, time etc. here */ state->update(); state->render(); } } struct State { /* No update or render function declared here! */ virtual void run()=0; virtual ~State() {} }; struct MenuState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<MenuState>(this); } }; struct FreeSpaceState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<FreeSpaceState>(this); } }; struct PlanetSurfaceState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<PlanetSurfaceState>(this); } }; MenuState menu; FreeSpaceState freespace; PlanetSurfaceState planet; State * states[] = {&menu, &freespace, &planet}; void run() { while (!exiting) { stateChanged = false; states[currentState]->run(); /* Runs until next state change */ } } int main() { run(); } The game loop is basically the same as the one before, except that it now exits in case of a state change as well, and the containing loop() function has become a function template.
      Instead of loop() being called directly by main(), it is now called by the run() method of the concrete state subclasses, each instantiating the function template with the appropriate type. The loop runs until the state changes, in which case the run() method shall be called again for the new state. This is the task of the global run() function, called by main().
      There are two negative consequences. First, it has become slightly more complicated and harder to maintain than the one above; but only SLIGHTLY, as far as I can tell based on this simple example. Second, code for the game loop will be duplicated for each concrete state; but it should not be a big problem as a game loop in a real game should not be much more complicated than in this example.
      My question: Is this a good idea at all? Does anybody else do anything like this, either in a scenario like this, or for completely different purposes? Any feedback is appreciated!
    • By svetpet
      Hello, I want to optimize the used memory in my game so that it supports low end devices - for instance iPhone 4s.
      I know that some of the main things I should look into are memory leaks, big textures and some game specific things, which occupy a lot of memory.
      To detect all that I am using MTuner on Windows and Instruments (Allocations) on XCode.
      What are you generally looking for when optimizing memory? What instruments are you using? My target platform is iOS.
    • By d3daywan
      【DirectX9 Get shader bytecode】
      I hook DrawIndexedPrimitive
          HookCode(PPointer(g_DeviceBaseAddr + $148)^,@NewDrawIndexedPrimitive, @OldDrawIndexedPrimitive);    
          function NewDrawIndexedPrimitive(const Device:IDirect3DDevice9;_Type: TD3DPrimitiveType; BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord): HResult; stdcall;
              ppShader: IDirect3DVertexShader9;
              Device.GetVertexShader(ppShader);//<------1.Get ShaderObject(ppShader)
              ppShader.GetFunction(_Code,_CodeLen);//<----2.Get bytecode from ShaderObject(ppShader)
              Result:=OldDrawIndexedPrimitive(Self,_Type,BaseVertexIndex,MinVertexIndex, NumVertices, startIndex, primCount);
      【How to DirectX11 Get VSShader bytecode?】
      I hook DrawIndexed
          pDrawIndexed:=PPointer(PUINT_PTR(UINT_PTR(g_ImmContext)+0)^ + 12 * SizeOf(Pointer))^;
          procedure NewDrawIndexed(g_Real_ImmContext:ID3D11DeviceContext;IndexCount:     UINT;StartIndexLocation: UINT;BaseVertexLocation: Integer); stdcall;
              game_pVertexShader: ID3D11VertexShader;
                  ppClassInstances: ID3D11ClassInstance;
                  NumClassInstances: UINT
              g_Real_ImmContext.VSGetShader(game_pVertexShader,ppClassInstances,NumClassInstances);    //<------1.Get ShaderObject(game_pVertexShader)
              .....//<----【2.Here's how to get bytecode from ShaderObject(game_pVertexShader)?】
              OldDrawIndexed(ImmContext, IndexCount, StartIndexLocation, BaseVertexLocation);

      Another way:
      HOOK CreateVertexShader()
      HOOK need to be created before the game CreateVertexShader, HOOK will not get bytecode if the game is running later,I need to get bytecode at any time like DirectX9
    • By shooter9688
      Once I needed a program for packing an atlas with 3d models. I could not find one, so I made it.
      Now it has only basic functionality. Should I improve it further? Does it need someone else?
      Link to download(for Windows): https://drive.google.com/open?id=1CLizcUAOsYnbdfyKCYDcGxmso79GPBuv
    • By standinonstilts
      Hi, I am new to Game Development and am currently making my first game in Unity using c#. I am a second year uni student studying computer science (internet security specialization). I am new to unity and have had trouble understanding how the game engine actually functions and how I should use the engine to my advantage when programming. Currently I am making a RPG and want to implement an efficient and scalable item database. My plan is to store all items in the game in an xml database using the built in unity xml serializer. I have an abstract class item -> weapon, armour, potion, ring etc. Each of these classes have respective values (damage, cost etc.). For a relatively generic and straightforward item system: How would you organize your code? What interfaces/classes/other would you implement; why? In your experience what kinds of issues have you run into and how did you work around them? Is there any other advice with regards to rpg design in general?
  • Advertisement
  • Advertisement
Sign in to follow this  

Coding Guidelines

Recommended Posts

After a feeled million hours of coding in the past 16 years there have been many ways to write code in many different languages. Some seemed correct to the time they were used, some seemed to be too strict or too chaotic and I also evolved my coding style with each new line written. Now considering the results of over 5 years in professionall game development, tools and engine code as hobbyist and on small and large commercial projects up to AAA titles, there are still many ways one could write code in different languages but also in the same language on different projects in one and the same but also different companies. I mostly agree with; see some trends in C#, C++ coding guidelines that are fully worth to go for but the major difference is on the naming conventions.

Because I have currently to write my own coding guidelines (not for a special project but primary as a personal convention to refer to when coding) and seek for a way I'm happy with, I did some research on different guidelines and came up with following references:

When Epic Games write about Unreal


Naming Conventions

  • The first letter of each word in a name (e.g. type or variable) is capitalized, and there is usually no underscore between words. For example, Health and UPrimitiveComponent, but not lastMouseCoordinates or delta_coordinates.

  • Type names are prefixed with an additional upper-case letter to distinguish them from variable names. For example, FSkin is a type name, and Skin is an instance of a FSkin.

    • Template classes are prefixed by T.

    • Classes that inherit from UObject are prefixed by U.

    • Classes that inherit from AActor are prefixed by A.

    • Classes that inherit from SWidget are prefixed by S.

    • Classes that are abstract interfaces are prefixed by I.

    • Enums are prefixed by E.

    • Boolean variables must be prefixed by b (e.g. "bPendingDestruction", or "bHasFadedIn").

    • Most other classes are prefixed by F, though some subsystems use other letters.

    • Typedefs should be prefixed by whatever is appropriate for that type: F if it's a typedef of a struct, U if it's a typedef of a UObject etc.

      • A typedef of a particular template instantiation is no longer a template and should be prefixed accordingly, e.g.:

        typedef TArray<FMyType> FArrayOfMyTypes;

This seems a bit confusing when seeking for some type like Animation or Skin (that are both different prefixed with A and F) but prevents various naming conflicts to types and variables when writing a function that accepts FSkin Skin as parameter for example.

Googles c++ guidelines point into a completely different direction when they write


Type Names

Type names start with a capital letter and have a capital letter for each new word, with no underscores: MyExcitingClass, MyExcitingEnum.

The names of all types — classes, structs, type aliases, enums, and type template parameters — have the same naming convention. Type names should start with a capital letter and have a capital letter for each new word. No underscores. For example:

// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...

// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;

// using aliases
using PropertiesMap = hash_map<UrlTableProperties *, string>;

// enums
enum UrlTableErrors { ...

Variable Names

The names of variables (including function parameters) and data members are all lowercase, with underscores between words. Data members of classes (but not structs) additionally have trailing underscores. For instance: a_local_variable, a_struct_data_member, a_class_data_member_.

Common Variable names

For example:

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.

Class Data Members

Data members of classes, both static and non-static, are named like ordinary nonmember variables, but with a trailing underscore.

class TableInfo {
  string table_name_;  // OK - underscore at end.
  string tablename_;   // OK.
  static Pool<TableInfo>* pool_;  // OK.

Struct Data Members

Data members of structs, both static and non-static, are named like ordinary nonmember variables. They do not have the trailing underscores that data members in classes have.

struct UrlTableProperties {
  string name;
  int num_entries;
  static Pool<UrlTableProperties>* pool;

See Structs vs. Classes for a discussion of when to use a struct versus a class.

Constant Names

Variables declared constexpr or const, and whose value is fixed for the duration of the program, are named with a leading "k" followed by mixed case. For example:

const int kDaysInAWeek = 7;

All such variables with static storage duration (i.e. statics and globals, see Storage Duration for details) should be named this way. This convention is optional for variables of other storage classes, e.g. automatic variables, otherwise the usual variable naming rules apply.


Function Names

Regular functions have mixed case; accessors and mutators may be named like variables.

Ordinarily, functions should start with a capital letter and have a capital letter for each new word (a.k.a. "Camel Case" or "Pascal case"). Such names should not have underscores. Prefer to capitalize acronyms as single words (i.e. StartRpc(), not StartRPC()).


(The same naming rule applies to class- and namespace-scope constants that are exposed as part of an API and that are intended to look like functions, because the fact that they're objects rather than functions is an unimportant implementation detail.)

Accessors and mutators (get and set functions) may be named like variables. These often correspond to actual member variables, but this is not required. For example, int count() and void set_count(int count).

Namespace Names

Namespace names are all lower-case. Top-level namespace names are based on the project name . Avoid collisions between nested namespaces and well-known top-level namespaces.

The name of a top-level namespace should usually be the name of the project or team whose code is contained in that namespace. The code in that namespace should usually be in a directory whose basename matches the namespace name (or subdirectories thereof).

Keep in mind that the rule against abbreviated names applies to namespaces just as much as variable names. Code inside the namespace seldom needs to mention the namespace name, so there's usually no particular need for abbreviation anyway.

Avoid nested namespaces that match well-known top-level namespaces. Collisions between namespace names can lead to surprising build breaks because of name lookup rules. In particular, do not create any nested std namespaces. Prefer unique project identifiers (websearch::index, websearch::index_util) over collision-prone names like websearch::util.

For internal namespaces, be wary of other code being added to the same internal namespace causing a collision (internal helpers within a team tend to be related and may lead to collisions). In such a situation, using the filename to make a unique internal name is helpful (websearch::index::frobber_internal for use in frobber.h)

Enumerator Names

Enumerators (for both scoped and unscoped enums) should be named either like constants or like macros: either kEnumName or ENUM_NAME.

Preferably, the individual enumerators should be named like constants. However, it is also acceptable to name them like macros. The enumeration name, UrlTableErrors (and AlternateUrlTableErrors), is a type, and therefore mixed case.

enum UrlTableErrors {
  kOK = 0,
enum AlternateUrlTableErrors {
  OK = 0,

Until January 2009, the style was to name enum values like macros. This caused problems with name collisions between enum values and macros. Hence, the change to prefer constant-style naming was put in place. New code should prefer constant-style naming if possible. However, there is no reason to change old code to use constant-style names, unless the old names are actually causing a compile-time problem.

Macro Names

You're not really going to define a macro, are you? If you do, they're like this: MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

Please see the description of macros; in general macros should not be used. However, if they are absolutely needed, then they should be named with all capitals and underscores.

#define ROUND(x) ...
#define PI_ROUNDED 3.0

Exceptions to Naming Rules

If you are naming something that is analogous to an existing C or C++ entity then you can follow the existing naming convention scheme.

function name, follows form of open()
struct or class, follows form of pos
STL-like entity; follows STL naming conventions
a constant, as in INT_MAX

So they heavily make use of typos, underscores and also lower case prefixes to identify different kinds of member, static, nonstatic and function names and in the same breath except there rules for various special cases.

Some other examples from different projexts I was invovled to also use and do not use prefixing types or use underscores

class Class
    const <type> cConstant;
    const <type> Constant;
    const <type> __Constant;
    <type> _myClassMember;
    <type> _MyClassMember;
    <type> myClassmember;
    <type> mMyClassMember;
    <type> function(<type> parameter);
    <type> Function(<type> parameter);
    <type> Function(<type> aParameter);
class NAClass //avoid using namespaces, instead prefix anything with a 2 letter namespace like identifier

Dont need to mention that Visual Studio will raise a Warning/Exception that a type is named as same as a function parameter when using a class

class Container
    private int size; //current size
    public Resize(int size) //will cause compiler telling that type matches a member type
        //do resize here

So in the end anyone does he or she thinks that it is worth to be done and so me do too. I would like to hear your opinions to why and what codings style do you prefer or are involved to in whatever way. What do you think makes a good standard especially for the most common point, Naming Convetions?

Will be corious to read your opinions

Share this post

Link to post
Share on other sites

In the end it all comes down to your preferences, since the compiler wont care at all.  But generally, I think the important things are that whatever you choose is consistent throughout the code and creates as little confusion or obfuscation as possible.  Other things like typing speed can also come into play, but again that can be a matter of preference especially with auto-complete and other built-in features that may or may not exist in your code editor of choice.

Personally I use camelcase, avoiding underscores whenever possible, using them only in special cases.  I start my classes and function with upper case letters, local variables with lower case, and member variables start with "m" followed by capital letter for variable name.  Macros are all caps separated by underscores.  For curly braces I use Allman style because it aligns the curly braces and makes them easier to match up when looking at code, as well as separates the block of code inside the braces from the code before it... which again makes it easier to read for me.  I have trouble telling what code does if it's all bunched up into a solid brick of text.

Share this post

Link to post
Share on other sites
16 minutes ago, 0r0d said:

since the compiler wont care at all

There are a few things one should avoid, though -- one of which is listed as one of the last examples in the original post.

Identifiers should not start with leading underscores, nor should they contain double underscores. These can run into issues with reserved names.


Other than that I agree that's it's just a preference thing. If you're working with someone else, come to an agreement. The fact that there exists so many and different guidelines is good evidence for there not being any One True Style™.

Share this post

Link to post
Share on other sites

I mostly agree with the C# Style 0r0d mentioned except that in my opinion the leading m/a/c prefix for class/argument/constant types could lead to faster recognition what a name is used for but I personally feel that it leads to more thinking about "was this a member, argument or temporary I used here" rather than writing for the initial intention.

For example I know i need the size stored in my class right now so I would in some kind of subconscious auto typing write "size" and go ahead in the knowing of this beeing the correct addressor I intendet. Using a prefix "m" for my class member "mSize" could (or potentially would most of the time in my case) lead to a less subconscious typing but a conscious active reminder about "do not forgett that it isnt size rather than mSize" that might lead to a break in code flow.

When I had C# first and learned C++ later, there were no such things like prefixing your member/argument/constant whatever variables in my years of school at all.

Share this post

Link to post
Share on other sites

Prefixing type is generally a terrible idea.

Scope decoration, OTOH, can be kinda useful. Using m or _ for member variables, for example, allows differentiation between parameters and members, and also intellisense will quickly list all your members for that class. Sure, you could explicitly type "this->", but that's overkill.

I'm also open to prefixing pointers with p, purely because it makes your life a tiny bit easy when you're coding (variable. vs pVariable->).

But basically, pick a standard with your team, agree on it (quickly) and stick to it.


Readability is key.

Share this post

Link to post
Share on other sites
3 hours ago, 0r0d said:

How so?

CBecause GProgramming VIs Aa NWork POf NLiterature.  PIt VMakes PIt AVery VDifficult PFor NHumans VATo VRead CAnd AThe NCompiler PDoesn't VCare.

CAlso, IWhat's PWith CAll AThe GCapitalization PIn ASo AMany NGuidelines?

Edited by Bregma

Share this post

Link to post
Share on other sites
5 hours ago, 0r0d said:

How so?

Basically what @Bregma said.

All it does is add noise. It also discourages refactoring (int iThing = GetAThing() now returns a float, now we have rename every variable).

The whole lpszThisIsAString was a mistake in the first place. Initially, "Hungarian" notation was meant to encode metadata in the variable name. For example, wndX vs scnX to denote a window coordinate versus a screen coordinate. The idea was that if you see

wndX = scnX // oops should be wndX = ScreenToWindow(scnX)

it would look immediately wrong. 

But even that is no longer that useful (you could make different ScreenCoord and WindowCoord types, for example).



Share this post

Link to post
Share on other sites
4 hours ago, Bregma said:

CBecause GProgramming VIs Aa NWork POf NLiterature.  PIt VMakes PIt AVery VDifficult PFor NHumans VATo VRead CAnd AThe NCompiler PDoesn't VCare.

CAlso, IWhat's PWith CAll AThe GCapitalization PIn ASo AMany NGuidelines?

Oh, you were talking about prefixes for the type of a variable... that wasnt clear to me when I originally read your post.

Yeah I agree it's not a thing I would do.

I thought you were talking about prefixes for things like classes or functions, as in instead of namespaces.


rendTexture vs rend::Texture


rendGetTexture() vs rend::GetTexture()

Edited by 0r0d

Share this post

Link to post
Share on other sites

But is using mMember, aArgument and so on not the same as prefixing stuff; where

mWndPos = aWndPos + cWndPos;
//do some stuff to mWndPos;

*pWndPos = mWndPos;

is as same confusing as whatever Bregman wrote?

I know that it would make life easier when using some kind of member type to variable separation but writing this-> seems to be pretty standard here

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  

  • Advertisement