RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Sat Mar 10, 2007 11:24 pm    Post subject: RPG design [quote]

So I'm looking to design an RPG. I'm basically trying to poll for opinions here.

I'm currently programming in c++, and have limited DirectX experience. Because of this, I could either program it in 2D (using SDL), or try to learn directx again if necessary.

Or I could learn another language. I've never used anything besides c++, so would basic do the job?


My intentions are to make a single player game. A mmo seems hard enough, so I'll stick with the basics.

My main questions are in the design of an RPG. How should I set up a messaging system, how should I have my classes laid out?

I realize there are many ways to do this, but I need a push in the right direction.
Back to top  
Terry
Spectral Form


Joined: 16 Jun 2002
Posts: 798
Location: Dublin, Ireland

PostPosted: Sun Mar 11, 2007 12:16 am    Post subject: [quote]

If working on this contest game has taught me anything, it's that the programming bit is by far the least important part. You should use whatever lets you get into the game quickest, including game makers - writing a good engine can take years and it's a waste of time. However, I'd be a bit of a hypocrite if I told you to hardcode the whole game, even though that's what I wish I'd done...

I don't know if this is any help to you, but here's how my RPG engine is laid out, at a very high level. Keep in mind that I'm a self taught programmer, so this isn't particularly pretty :)

Code:
initialisation();
main loop{
  render{
    select state{
      Walkabout:
        draw walkabout map
        draw npcs
      Battle:
        draw battle map
        draw npcs
    }
    draw effects (rain, etc)
    draw cutscene images
    draw textboxes
    draw cursors/osd
  }

  input{ (again, state specific)
    get input
    clean input (no walking into walls, etc)
  }

  logic{
    select state{
      Walkabout:
        move npcs
        process npc positions
        process jumping
        process animations
        if scriptname!="NULL"{
          process script
        } 
      Battlemode:
        bring_in_your_dead (little hack to end battles/remove dead enemies)
        process atb
        if(battlescript!=-1) process_battle_actions
    }
    ProcessTextboxes
    process_floating (a textbox thing)
    process_camera
    process_rain
    process_eventanimation
    process_npclighting
  }
}
unload everything()


Just to give you an idea of the game's structure in detail, here are a few more interesting classes I'm using in the engine:

These two classes I'm using for the battle:

Code:

class actions{
public:
  int type, size;
  int cost[20];
  string name;
  string link[100];
};

class characterclass{
public:
  int strength, defence, intelligence, speed;
  int hp, maxhp;
  int sp, maxsp;
  int limit;
  int holder;
  double time;
 
  int strength_plus, defence_plus, intelligence_plus, speed_plus;
  int maxhp_plus, maxsp_plus;

  int strength_base, defence_base, intelligence_base, speed_base;
  int maxhp_base, maxsp_base;
 
  int level;
 
  int deathtype;
 
  string name;
  string action;
};


These are my textbox classes (which I'm going to rewrite after this contest, because it's a total mess):

Code:

class tb{
public:
  tb(){x=0; y=0; start=0; end=0; frontcolour=WHITE;
       width=0; height=0; backcolour=WHITE; columns=1;
       display=TRUE;};
  double x, y;
  double width, height;
  int truex, truey, truewidth, trueheight;
  int start, end, size;
  int start2, end2, size2;
  int frontcolour, backcolour;
  bool display;
  int transin, transout, status;
  double xchange, ychange;
  int backing;
  int columns, division;
};

class floating_text_class{
public:
  fl(){value=""; x=0; y=0; time=0; color=WHITE;};
  int x, y;
  int time, color;
  string value;
};

class textboxclass{
public:
  textboxclass(){
    size=200; num=0; realnum = 0; pos=0;
    num_floating=0;
    for(int i=0;i<1000;i++){
      expired[i]=false;
    }
  };
  void create(bool p, int x, int y, int siz, int fc, int bc, int in, int out,
              int b, int customwidth=0);
  void addcolumn(int siz, int d);
  void destroy(int t);
  void move(int t, int x, int y);
  void addline(string t){
    textbuffer[pos]=t;
    pos=(pos+1)%TEXTBUFFERSIZE;
  };
  void addmenulines(string t1, string t2){
    textbuffer[pos]=t1;
    simpletextbuffer[pos]=t2;
    pos=(pos+1)%TEXTBUFFERSIZE;
  };
  void createmenu(string mennam, int sz, int pr, int ofst=0);
  string finddest(){
    for(int i=0; i<numoptions; i++){
      if(options[i]==menudest) return optionsdest[i];
    }
    return "else";
  }
 
  void add_floating(int x, int y, string value, int color=WHITE){
    floating[num_floating].x = x;
    floating[num_floating].y = y;
    floating[num_floating].value = value;
    floating[num_floating].color = color;
    floating[num_floating].time = 0;
    num_floating++;
  };
 
  void copy_floating(int i, int j){
    floating[i].x = floating[j].x;
    floating[i].y = floating[j].y;
    floating[i].value = floating[j].value;
    floating[i].color = floating[j].color;
    floating[i].time = floating[j].time;
  }
 
  tb textbox[100];
  string options[100];
  string optionsdest[100];
  string textbuffer[TEXTBUFFERSIZE];
  string simpletextbuffer[TEXTBUFFERSIZE];
  int num, realnum, size, pos, numoptions, numstaticoptions;
  int longestline, longestoption;
  int pointer, pointerx, pointery, menupos, menuheight, menunum;
  int menusize, menustart, menuend;
  int menustyle;
  bool comment;
  bool expired[1000];
  string menuname, menudest, newmenuname, topicname;
 
  int num_floating;
  fl floating[100];
};



One thing I'm very glad I did was to seperate all the graphics calls into their own little class. My original idea was that it would mean I could change the library I was using by just rewriting this one routine, but unfortunately it's more complex than that :( Allegro is tied up in everything - the timers, the input routines, the music - I'd almost need a complete rewrite.

Just to warn you, this bit is a little messy:

Code:

class graphicsclass{
public:
  graphicsclass();
  void drawtile(int x, int y, int num){
    blit(tiles[num], buffer, 0, 0, x, y, 40, 40);
  }
  void drawtranstile(int x, int y, int num){
    draw_sprite(buffer, tiles[num], x, y);
  }
  #ifdef GAME_EDIT
  void drawrawlight(int x, int y, int num){
    blit(lights[num], buffer, 0, 0, x, y, 40, 40);
  }
  void drawtileblocked(int x, int y, int num){
    blit(tiles[num], buffer, 0, 0, x, y, 40, 40);
    rect(buffer, x, y, x+39, y+39, makecol(128,128,128));
  }
  void drawtileoutside(int x, int y, int num){
    rectfill(buffer, x, y, x+39, y+39, makecol(11,64,95));
  }
  void drawtranstilelight(int x, int y, int num){
    draw_trans_sprite(buffer, tiles[num], x, y);
  }
  void drawwhitebox(int x, int y){
    fblend_rect_trans(buffer, x, y, 40, 40, makecol(128,0,0), 128);
    rect(buffer, x, y, x+39, y+39, makecol(255,255,255));
    rect(buffer, x+1, y+1, x+38, y+38, makecol(255,255,255));
  }
  #endif
  void lockscreen(){ acquire_bitmap(buffer); }
  void unlockscreen(){ release_bitmap(buffer); }   
  void drawlight(int x, int y, int num){
    if(num>0) draw_trans_sprite(buffer, lights[num], x, y);
  }
  void drawsmall(int x, int y, int num){
    draw_sprite(buffer, smalleffects[num], x, y);
  }
  void drawnpc(int x, int y, int num, bool lit=false,
               int r=0, int g=0, int b=0, int a=0){
    if(lit==false){
      draw_sprite(buffer, npcs[num], x, y);
    }else{
      set_trans_blender(r,g,b,255);
      draw_lit_sprite(buffer, npcs[num], x, y, a);
      solid_mode();
    }
  }
  void drawenemy(int x, int y, int num, bool lit=false,
                 int r=0, int g=0, int b=0, int a=0){
    if(lit==false){
      draw_sprite(buffer, enemies[num], x, y);
    }else{
      set_trans_blender(r,g,b,255);
      draw_lit_sprite(buffer, enemies[num], x, y, a);
      solid_mode();
    }
  }
  void render(){blit(buffer, screen, 0, 0, 0, 0, 800, 600);}
  void cls(){clear_bitmap(buffer);}
  void print(int x, int y, string t, int color){
    if(color!=CLEAR){
      const char* txt;
      txt = t.c_str();
      alfont_textout(buffer, gamefont, txt, x+1, y+1, makecol(0,0,0));
      alfont_textout(buffer, gamefont, txt, x, y, fontcolor(color));
    }
  }
  void printbold(int x, int y, string t, int color){
    if(color!=CLEAR){
      const char* txt;
      txt = t.c_str();
      alfont_textout(buffer, boldfont, txt, x+1, y+1, makecol(0,0,0));
      alfont_textout(buffer, boldfont, txt, x, y, fontcolor(color));
    }
  }
  void box(int x1, int y1, int x2, int y2, int t);
  void dimage(int num, imageclass& image){
    draw_sprite(buffer, cutscene[num], image.im[num].x, image.im[num].y);
  }
  void dfloat(int num, textboxclass& text);
  void dtextbox(int num, textboxclass& text);
  void fade(int amount){
    fblend_fade_to_color(buffer, buffer, 0, 0, makecol(0,0,0), 255-amount);
  }
  void rain(){
    for(int y=0;y<15;y++){
      for(int x=0;x<20;x++){
        draw_sprite(buffer, raintiles[rainframe], x*40, y*40);
      }
    }
    fblend_fade_to_color(buffer, buffer, 0, 0, makecol(0,0,64), 196);
  }
  void drawcursor(int x, int y, int n){
    draw_sprite(buffer, cursors[n], x, y);
  }
  void drawtargetcursor(int x, int y);
  void drawbattlebackground(int num){
    blit(battle_background[num], buffer, 0, 0, 0, 0, 800, 600);
  }
  void showstats(characterclass *heros);
private:
  BITMAP *tiles[3000];
  BITMAP *lights[300];
  BITMAP *npcs[432];
  BITMAP *raintiles[8];
  BITMAP *cursors[4];
  BITMAP *cutscene[20];
  BITMAP *smalleffects[100];
  BITMAP *corners[64];
  BITMAP *target_cursor;
  BITMAP *buffer;
  BITMAP *majorarcana[22];
  BITMAP *enemies[9];
  BITMAP *battle_background[10];
  bool transon;
};



I also have a map class, a field object class (which deals with NPCs, among other things), a scripting class, a music class, an items class, and an input class that processes Allegro's input routines into something more manageable - namely:

Code:

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define MENU 4
#define CONFIRM 5
#define CANCEL 6
#define SQUARE 7

bool khit[8];
bool kpress[8];
int kdelay[8];
int upkey = KEY_UP, downkey = KEY_DOWN;
int leftkey = KEY_LEFT, rightkey = KEY_RIGHT;
int menukey = KEY_S, confirmkey = KEY_X, cancelkey = KEY_Z;
int squarekey = KEY_A;
bool hitup = false, hitdown = false, hitleft = false, hitright=false;
bool hitmenu=false, hitconfirm=false, hitcancel=false, hitsquare=false;
bool pressup=false, pressdown=false, pressleft=false, pressright=false;
bool pressmenu=false, pressconfirm=false, presscancel=false,presssquare=false;

void processinput(){
  if(!key[upkey]){khit[UP]=false;kpress[UP]=false;kdelay[UP]=0;}
  else if(key[upkey]){
    if(kpress[UP]==false) kdelay[UP]=-6;
    kpress[UP]=true;
  }
  if(!key[downkey]){khit[DOWN]=false;kpress[DOWN]=false;kdelay[DOWN]=0;}
  else if(key[downkey]){
    if(kpress[DOWN]==false) kdelay[DOWN]=-6;
    kpress[DOWN]=true;
  }
  if(!key[leftkey]){khit[LEFT]=false;kpress[LEFT]=false;kdelay[LEFT]=0;}
  else if(key[leftkey]){
    if(kpress[LEFT]==false) kdelay[LEFT]=-6;
    kpress[LEFT]=true;
  }
  if(!key[rightkey]){khit[RIGHT]=false;kpress[RIGHT]=false;kdelay[RIGHT]=0;}
  else if(key[rightkey]){
    if(kpress[RIGHT]==false) kdelay[RIGHT]=-6;
    kpress[RIGHT]=true;
  }
  if(!key[confirmkey]){khit[CONFIRM]=false;kpress[CONFIRM]=false;
                       kdelay[CONFIRM]=0;}
  else if(key[confirmkey]){
    if(kpress[CONFIRM]==false) khit[CONFIRM]=true;
    else khit[CONFIRM]=false;
    kpress[CONFIRM]=true;
  }
if(!key[cancelkey]){khit[CANCEL]=false;kpress[CANCEL]=false;kdelay[CANCEL]=0;}
  else if(key[cancelkey]){
    if(kpress[CANCEL]==false) khit[CANCEL]=true;
    else khit[CANCEL]=false;
    kpress[CANCEL]=true;
  }
  if(!key[menukey]){khit[MENU]=false;kpress[MENU]=false;kdelay[MENU]=0;}
  else if(key[menukey]){
    if(kpress[MENU]==false) khit[MENU]=true;
    else khit[MENU]=false;
    kpress[MENU]=true;
  }
if(!key[squarekey]){khit[SQUARE]=false;kpress[SQUARE]=false;kdelay[SQUARE]=0;}
  else if(key[squarekey]){
    if(kpress[SQUARE]==false) khit[SQUARE]=true;
    else khit[SQUARE]=false;
    kpress[SQUARE]=true;
  }

  for(int i=0;i<4;i++){
    if(kpress[i]==true){
      if(khit[i]==false){
        kdelay[i]--;
        if(kdelay[i]<=0) khit[i]=true;
      }else if(khit[i]==true){
        if(kdelay[i]<-2) kdelay[i]=10;
        else kdelay[i]=2;
        khit[i]=false;
      }
    }
  }
}

void clearinput(){for(int i=0;i<8;i++) kdelay[i]=0;}


Hmm... I can't quite remember why I redefined all the allegro keypress consts, but I'm sure it made sense at the time...

[yikes- that's way more than I'd meant to post... well, hope it's useful information for you :) Everyone else feel free to laugh at my crappy code!]
_________________
http://www.distractionware.com
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Sun Mar 11, 2007 12:30 am    Post subject: high-level [quote]

Thank you very much for your post.

You know I've been thinking lately. I'll never get a game up at the rate I'm going. I seem to want to program everything myself so I understand what's going on, but realize that it will take me 10 times longer than using pre-existing code.

I mean, the object of a video game is to be played, right? So why not use other code to actually create it?


Now I'm debating on which engine to use and what type of game do make. I'm looking into messaging systems and asking these questions because I'm using c++ and love to program, but now I'm at the point where I want to do something.

Do you recommend any higher-level languages or engines that I look into? I want to get a game up already... know what I mean?


(p.s. if I were to make this online, do most engines support online play or will that be something I have to implement?)
Back to top  
Terry
Spectral Form


Joined: 16 Jun 2002
Posts: 798
Location: Dublin, Ireland

PostPosted: Sun Mar 11, 2007 12:37 am    Post subject: [quote]

Quote:
You know I've been thinking lately. I'll never get a game up at the rate I'm going. I seem to want to program everything myself so I understand what's going on, but realize that it will take me 10 times longer than using pre-existing code.

I mean, the object of a video game is to be played, right? So why not use other code to actually create it?


I couldn't agree more. I just wish I'd had the same realisation myself back in college - maybe I'd have actually finished something at this stage, heh.

I'm not aware of any online RPG engines, so I don't think I can be much help there. The Mana World is open source, but I don't think it's built for general use.

If you were interested in the single player side of things, I might have a few suggestions for you :)

There's a great thread on Tigsource about the pros and cons of different programming libraries and utilities : if you're not sure about that side of things yet, it might give you a few ideas.

Awesome Tigsource Programming Languages and Compilers thread
_________________
http://www.distractionware.com
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Sun Mar 11, 2007 12:40 am    Post subject: [quote]

single player suggestions would be great. Do you have an aim/msn messenger account?

AIM: massive war


If not, we can talk over this. Thanks man.
Back to top  
Terry
Spectral Form


Joined: 16 Jun 2002
Posts: 798
Location: Dublin, Ireland

PostPosted: Sun Mar 11, 2007 12:42 am    Post subject: [quote]

I have MSN, but I don't really use it. I'm in the IRC channel right now though!

irc.esper.net
#indie-rpg
_________________
http://www.distractionware.com
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Sun Mar 11, 2007 12:43 am    Post subject: [quote]

I've never used IRC. I"ll google it now
Back to top  
Terry
Spectral Form


Joined: 16 Jun 2002
Posts: 798
Location: Dublin, Ireland

PostPosted: Sun Mar 11, 2007 12:46 am    Post subject: [quote]

If you're using firefox, you can get a quick and dirty irc client built into the browser called chatzilla that's fairly unintrusive. That's what I use anyway.

Heh, what's with all the recommendations I'm dishing out today? Anything to keep from working, I guess :)
_________________
http://www.distractionware.com
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Sun Mar 11, 2007 12:55 am    Post subject: [quote]

I got the firefox plugin, but it says that indie-rpg doesn't exist
Back to top  
Terry
Spectral Form


Joined: 16 Jun 2002
Posts: 798
Location: Dublin, Ireland

PostPosted: Sun Mar 11, 2007 12:57 am    Post subject: [quote]

Weird - are you attached to the esper.net network?

Feck it, I'll just use MSN. My address is blinkthedarkness at hotmail, feel free to add me.
_________________
http://www.distractionware.com
Back to top  
Captain Vimes
Grumble Teddy


Joined: 12 May 2006
Posts: 225
Location: The City Streets

PostPosted: Wed Mar 14, 2007 1:07 pm    Post subject: [quote]

Whoa, Echo. That helped me out a lot.

...

Kinda sad, isn't it?
_________________
"Sometimes it is better to light a flamethrower than to curse the darkness."
- Terry Pratchett
Back to top  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum