Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1412053 Posts in 69447 Topics- by 58483 Members - Latest Member: Exye

June 22, 2024, 07:22:39 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Coding styles
Pages: [1] 2 3 ... 7
Print
Author Topic: Coding styles  (Read 18978 times)
Sos
Level 8
***


I make bad games


View Profile WWW
« on: February 26, 2010, 04:02:05 AM »

I bet all of you have your own style of coding regardless of your favourite language. I guess we may share our preferences regarding this, since I believe each of you have some guidelines they use. also, where do they come from?

I use C mostly, and I try to follow these:
Code:
#include "stdio.h" // really, i don't know why i do that instead of <>

#define ALLCAPITALS 0xf // defines in capitals always, that saves some head scratching,             
                        //also those may become vars later on, but they stay capitals

int var1,var2,var3;
int var4,var5,var6,frame; // i know i should keep these under one 'int' but it feels clear to read this way for me

void draw_me_a_basket(int x, int y) // every declarations get lowercase only
                                    // because not having to press shift saves some time :)
// also underscores go only to functions, not vars
{
  int a,b,c,d,i,xx,yy; // single letters only for local use. c/i for iterations, a,b,d for temp vars
                       // xx,yy are recalculated values for x and y
  float fx,fy,f;       // f as temp float value, fx/fy = x/y in float
  // I like using one var for many things, unless i have too save the value for later use
 xx=x-8+(rand()%16); 
 yy=y-8+(rand()%16);
 draw_sprite((frame^=1?bmp1:bmp2),screen,xx,yy);
  // i just love to abuse the (what?this:else) expression in a spagetti code way
}
I keep all the code in one file too, because i hate setting up project to do RAD (apparently i set up projects only to include app icon)
These make me write the crappiest code ever which is hard for me to follow.
 
There are probably some more I do not remember, but i guess this gives the idea clearly.
I look forward to see how other people code.

PS. I do this all in FPC (free pascal compiler) derived colour scheme, which is mostly the same as borland one (yellow chars on blue bg, white keywords etc.) but immediate values (numbers, strings) are cyan. preprocessor stuff green.
Logged

shrimp
Level 5
*****


View Profile WWW
« Reply #1 on: February 26, 2010, 06:12:25 AM »

I guess my guidelines (C++ and C#) come from team projects that I've working on at various companies, and for the most part they have converged on the same thing, except for a few minor details like variable prefixes, indent style, etc.

Also from
http://www.amazon.co.uk/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0201924889
and
http://www.parashift.com/c++-faq-lite/

I've always used an IDE which helps, for example autocomplete allows you to have longer descriptive variable names without much impact on typing speed and IDEs generally make it much easy to create and navigate between multiple source files, and don't have to create makefiles.

...NamesAreUsuallyCapitalised like that.
...I pretty much never reuse local variables for multiple things as it just gets confusing and invites bugs. Also might suggest the function is too long. Variables are declared where first used and tightly scoped.
..."static const" variables and inline functions instead of #defines where possible to avoid errors.
...I try to have functions and classes that do one clear, atomic-ish job.
...tons of formatting habits, like 4-space tabs, {} on new line, yadda yadda.
...etc, etc. Of course some of this goes out the window if really rushing to finish something.

I still shudder when I remember 2 months spent last year at work maintaining, refactoring and then finally just deleting a 5000 line function with ~80 goto statments, and variables that were all declared at the top and arbitrarily did ("id3") or didn't ("id4") retain values for future whilst the code skipped around the blocks of the function.
Logged

Skofo
Level 10
*****



View Profile
« Reply #2 on: February 26, 2010, 06:27:13 AM »

I put all of my code on one line. I hate scrolling down.
Logged

If you wish to make a video game from scratch, you must first invent the universe.
dspencer
Level 3
***


View Profile WWW
« Reply #3 on: February 26, 2010, 06:31:04 AM »

Quote
void draw_me_a_basket(int x, int y) // every declarations get lowercase only
                                    // because not having to press shift saves some time Smiley

Except that you need to press shift to get the underscore  Durr...?
But other than that one thats basically the same as my style. Classes and Structs start with uppercase.
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #4 on: February 26, 2010, 06:45:11 AM »

..."static const" variables and inline functions instead of #defines where possible

"static const" is generally a bad idea if you're using it within functions, as part of a class or translation unit it's a different story.

Here's what happens:
Code:
void funk()
{
    static const unsigned kof = 98;
    unsigned best = kof;
}

Here the compiler will propagate 98 to the variable 'best,' but it still has to reserve space for the const, even though that space is never referenced.

The compiler is allowed to treat integral consts as macros, and never actually allocate storage for them.  It only has to allocate storage if the const is used in a way that requires it to have storage.  One way to force this is by taking its address, another is by declaring it static.  You're wasting sizeof(unsigned) bytes of memory for no real reason.  Removing static effectively gets you a local macro, unless you take its address or something.  Take at look at the assembly sometime and you'll see what I mean.

This is C++, the rules for const are slightly different in C, and I haven't verified them.
Logged



What would John Carmack do?
shrimp
Level 5
*****


View Profile WWW
« Reply #5 on: February 26, 2010, 06:51:06 AM »

Ah OK. I was thinking more for file/class scope stuff, i.e. replacing
#define MAX_HEADROOM 12
with
(static?) const int MAX_HEADROOM = 12
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #6 on: February 26, 2010, 06:56:07 AM »

Ah OK. I was thinking more for file/class scope stuff, i.e. replacing
#define MAX_HEADROOM 12
with
(static?) const int MAX_HEADROOM = 12

That's fine at class scope, but that use of static at file scope has actually been deprecated in C++.  You're supposed to use the anonymous namespace.

Code:
namespace
{
    const int max_headroom = 12;
}

All caps names are generally reserved for #define macros too.  I've had to debug problems resulting from macro clashes and they aren't fun, it's like debugging invisible code.
Logged



What would John Carmack do?
Christian Knudsen
Level 10
*****



View Profile WWW
« Reply #7 on: February 26, 2010, 07:03:35 AM »

Need more Pascal in here!

Since I've always programmed on my own, I've got some really nasty habits that people always balk at when I ask for code advice. Like always capitalizing my variables:

Code:
   // Draw character text:
   FOR I := 1 TO MaxCharacters DO BEGIN
      IF Character[I].TalkLine[2] <> '' THEN BEGIN
         FOR X := 1 TO 2 DO BEGIN
            IF (Character[I].TalkLine[X] <> '')
            AND ((X = 1) OR ((X = 2) AND ((Character[I].TalkLine[1] = '') OR (Character[I].TalkLineCounter[1] = Character[I].TalkLineCharacters[1]))))
            THEN BEGIN
               DestinationX := (((Character[I].X - Character[I].Y) * 38) + 370) + ScreenOffsetX;
               IF X = 2
               THEN DestinationY := (((Character[I].X + Character[I].Y) * 19) + ScreenOffsetY) - 100
               ELSE DestinationY := (((Character[I].X + Character[I].Y) * 19) + ScreenOffsetY) - 120;

               IF Character[I].TalkLineTextWidth[X] > 76
               THEN Dec(DestinationX, Trunc((Character[I].TalkLineTextWidth[X] - 76) / 2))
               ELSE Inc(DestinationX, Trunc((76 - Character[I].TalkLineTextWidth[X]) / 2));

               IF Character[I].AnimationType = Run THEN BEGIN
and so on...

I think it just looks better like that. Shrug
Logged

Laserbrain Studios
Currently working on Hidden Asset (TIGSource DevLog)
Dataflashsabot
Level 2
**


View Profile
« Reply #8 on: February 26, 2010, 07:29:14 AM »

variablesCapitalizedLikeThis
FunctionsCapitalizedLikeThis()
{
    // new line for curly brackets
}

// I tend to
// use multiple single-line comments
// for multi-line comments
// instead of /* */
// for some reason

All of the above applies to C++ and C#.
I use const instead of #define.
Logged
Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #9 on: February 26, 2010, 10:15:12 AM »

Code:
int var1,var2,var3;
int var4,var5,var6,frame; // i know i should keep these under one 'int' but it feels clear to read this way for me

I would avoid doing this in C/C++ because the following code doesn't do what it looks like it should do:
Code:
int* p1, p2;
Logged

increpare
Guest
« Reply #10 on: February 26, 2010, 11:45:16 AM »

I would avoid doing this in C/C++ because the following code doesn't do what it looks like it should do:
Code:
int* p1, p2;
Oh f**k I never knew that.  AAAAAH.

*runs away screaming*
Logged
dustin
Level 6
*


View Profile
« Reply #11 on: February 26, 2010, 12:50:19 PM »

Quote
I would avoid doing this in C/C++ because the following code doesn't do what it looks like it should do:
Code:

int* p1, p2;

yeah I always put the * after the int because I feel it's part of the type however I know lots of people who do this...

int *p1, *p2;

which will work and do what you think it would do.
Logged
Kadoba
Level 3
***



View Profile
« Reply #12 on: February 26, 2010, 01:12:06 PM »

Code:
// All variables are capitalized and have a lowercase prefix depending on the scope. 
// The type isn't indicated.

// Global variables are prefixed with "the"
Manager theManager;

// Template types are descriptive and prefixed an uppercase "T"
template<class TResource>

// All classes and types are nouns and capitalized without spaces
class SomeClass{

   // Public comes first. This is the interface of your class to the world so
   // people usually want to look at these first.
   public:

      // Constructors and such go here.

      // All functions are verbs and capitalized without spaces.
      // Passed variables are prefixed with "arg"
      void DoThis(int argVariable);
   
   private:
      // Member variables are prefixed with "my"
      TResource myResource;

      // Boolean member variables are prefixed with "im" or "ive"
      bool imRunning;
      bool iveJumped;

      // Containers must be plural
      std::list<TResource> myResources;

      // Pointers or handles are suffixed with "Ptr"
      SmartPtr<Image> myImagePtr;

     // Pointers to pointers are suffixed a second time with "Ptr" and so on.
      SmartPtr< SmartPtr<Image> > myImagePtrPtr;
};


void SomeClass::DoThis(int argVariables){
 
  // temporary variables allocated inside functions are
  // prefixed with "tmp"
  int tmpVariable = argVariable;

  // non-member boolean variables must start with "Is" or "Has"
  bool argIsHappy = true;
  bool argHasSlapped = false;
 
}
Logged
Riley Adams
Level 5
*****


I don't actually use Ubuntu much...


View Profile
« Reply #13 on: February 26, 2010, 02:18:33 PM »

I use C++

Header example
Code:
#ifndef MYCLASS_H
#define MYCLASS_H

#include "whatever.h"

// namespaces and classes have the first letter of each word capitalized
namespace Example
{
class MyClass
{
public:

// I use comments formatted for use with doxygen:

/** Documentation goes here... */
MyClass();

/** More documentation goes here... */
MyClass(const int& number);

/** Documentation goes here...
And another line..............*/
~MyClass();

// I name functions with the first letter lower
// case and the first letter of each other
// word capitalized.

/** Sets the number
@param number The new number */
void setNumber(const int& number);

/** Gets the number
@returns The number */
int getNumber();

protected:

// I prefix protected/private member vars with 'm'
int mNumber;

};
}

#endif
Source Example
Code:
#include "MyClass.h"

namespace Example
{
MyClass::MyClass()
:mNumber(0)
{

}

MyClass::MyClass(const int& number)
:mNumber(number)
{

}

MyClass::~MyClass()
{

}

void MyClass::setNumber(const int& number)
{
mNumber = number;
}

int MyClass::getNumber()
{
// To show how I name temporary variables:
int temporaryNumber = mNumber;
return temporaryNumber;
}
}
Logged

David Pittman
Level 2
**


MAEK GAEM


View Profile WWW
« Reply #14 on: February 26, 2010, 02:24:47 PM »

Code:
#include "stdio.h" // really, i don't know why i do that instead of <>

I think it's compiler-dependent, but the quote and pointy bracket forms can actually mean different things. In VC++, quoted includes means to look locally for the file first, then look in other include directories if the file wasn't found; and brackets means to look in include directories immediately instead.

So I tend to do:
Code:
#include "me.h" // This is a header I wrote, so I put it in quotes

// (Whitespace to separate my headers from standard C/C++ libraries)

#include <stdio.h> // This is a standard library header, so I put it in brackets

I've heard it said that standard library headers should be included first, but I can't imagine a compelling reason to do that.
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #15 on: February 26, 2010, 06:16:34 PM »

Rectangle.h

Code:
#ifndef __AWESOME_RECTANGLE_H_
    #define __AWESOME_RECTANGLE_H_

All names containing two consecutive underscores, or beginning with an underscore followed by a capital letter are in the compiler's reserved namespace.  Doing that is an extremely bad idea.
Logged



What would John Carmack do?
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #16 on: February 26, 2010, 06:17:47 PM »

I've heard it said that standard library headers should be included first, but I can't imagine a compelling reason to do that.

It's to keep macros defined in your own headers from changing the meaning of the standard headers.
Logged



What would John Carmack do?
Core Xii
Level 10
*****


the resident dissident


View Profile WWW
« Reply #17 on: February 26, 2010, 11:24:27 PM »

Logged
terloon
Level 0
**


View Profile WWW
« Reply #18 on: February 26, 2010, 11:33:06 PM »

Oh goodness, I have a great disdain for spaces after if, for, while, etc. A coworker does this to me on purpose to annoy me to no end Cheesy. When did that syntax take root?
Logged
st33d
Guest
« Reply #19 on: February 27, 2010, 03:54:18 AM »

This is how I roll:

Code:
package com.robotacid.engine {
import com.robotacid.gfx.BlitRect;
import com.robotacid.phys.Block;
import com.robotacid.phys.Collider;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Rectangle;

/**
* A decapitated head that bounces along spewing blood when
* kicked by the player and inflicts damage upon
* monsters
*
* :D
*
* @author Aaron Steed, robotacid.com
*/
public class Head extends Collider{

public var vx:Number;
public var vy:Number;

public var damage:Number;
public var blood_count:int;

public static const GRAVITY:Number = 0.8;
public static const DAMPING_Y:Number = 0.99;
public static const DAMPING_X:Number = 0.9;

public static const UP:int = 1;
public static const RIGHT:int = 2;
public static const DOWN:int = 4;
public static const LEFT:int = 8;

public static const BLOOD_DELAY:int = 20;

public function Head(victim:MovieClip, damage:Number, g:Game) {
// first we get capture the target's head
// each decapitatable victim has a marker clip on it called "neck" that we chop at
var neck_y:int = victim.neck.y + 1;
var bounds:Rectangle = victim.getBounds(victim);
var data:BitmapData = new BitmapData(Math.ceil(bounds.width), Math.ceil(-bounds.top + neck_y), true, 0x00000000);
data.draw(victim, new Matrix(1, 0, 0, 1, -bounds.left, -bounds.top));
var holder:Sprite = new Sprite();
var bitmap:Bitmap = new Bitmap(data);
bitmap.x = bounds.left;
holder.addChild(bitmap);
g.fx_holder.addChild(holder);
holder.x = victim.x;
holder.y = victim.y + neck_y;
// now we've got a head, but the width of the actual graphic may be lying
var colour_bounds:Rectangle = data.getColorBoundsRect(0xFFFFFFFF, 0x00000000, false);
bitmap.y = -colour_bounds.bottom;
super(holder, colour_bounds.width, colour_bounds.height, g);
call_main = true;
weight = 0;
blood_count = BLOOD_DELAY;
block.id |= Block.HEAD;
this.damage = damage;
}

override public function main():void{
if(left_collider is Character) punt(left_collider as Character);
else if(right_collider is Character) punt(right_collider as Character);
if(Math.abs(vx) > Collider.TOLERANCE || Math.abs(vy) > Collider.TOLERANCE){
if(blood_count > 0){
blood_count--;
var blood:BlitRect, print:BlitRect;
blood = Math.random() > 0.5 ? g.blood_small_bs : g.blood_big_bs;
print = blood == g.blood_small_bs ? g.blood_small_fade_bs : g.blood_big_fade_bs;
g.addDebris(x, y, blood, -1 + vx + Math.random(), -Math.random(), print, true);
}
}
soccerCheck();
// when crushed - just pop the head and kill it
if(((collisions & RIGHT) && (collisions & LEFT)) || ((collisions & UP) && (collisions & DOWN))){
kill();
}
up_collider = right_collider = down_collider = left_collider = null;
collisions = 0;
updateMC();
}

/* Apply damage to monsters that collide with the Head object */
public function soccerCheck():void{
if(up_collider && up_collider is Monster) (up_collider as Character).applyDamage(damage, this)
if(right_collider && right_collider is Monster) (right_collider as Character).applyDamage(damage, this)
if(left_collider && left_collider is Monster) (left_collider as Character).applyDamage(damage, this)
if(down_collider && down_collider is Monster) (down_collider as Character).applyDamage(damage, this)
}

/* Movement is handled separately to keep all colliders synchronized */
override public function move():void {
temp_y = y;
temp_x = x;
vx = DAMPING_X * (x - px);
moveX(vx, this);
if (parent_block){
checkFloor();
}
if(!parent_block){
moveY(DAMPING_Y * (y - py) + GRAVITY, this);
}
px = temp_x;
py = temp_y;

map_x = (rect.x + rect.width * 0.5) * INV_SCALE;
map_y = (rect.y + rect.height * 0.5) * INV_SCALE;
}

public function punt(character:Character):void{
parent_block = null;
blood_count = BLOOD_DELAY;
if(parent) parent.removeChild(this);
py += Math.abs(character.vx * 0.5);
px -= character.vx * 0.5;
}

public function kill():void{
active = false;
g.createBloodRect(rect, 0, 10);
}


/* Update collision Rect / Block */
override public function updateRect():void{
rect.x = x - width * 0.5;
rect.y = y - height * 0.5;
rect.width = width;
rect.height = height;
}

/* Handles refreshing animation and the position the canvas */
public function updateMC():void{
mc.x = (x + 0.1) >> 0;
mc.y = ((y + height * 0.5) + 0.1) >> 0;
if(mc.alpha < 1){
mc.alpha += 0.1;
}
}

override public function nameToString():String {
return "soccer";
}
}

}
Logged
Pages: [1] 2 3 ... 7
Print
Jump to:  

Theme orange-lt created by panic