First look at my Text RPG

Greetings all,
I haven't really posted my progress for a while. I got a bit bummed out / busy with other things. >< I know, getting bummed out at the beginning is not such a good sign, though I was spending a few hours every day with yard work on top of a full time job. Just wanted to take a break after all the hard labor.

Suffice to say, I am back at it 100%. I am working on a new little project to help me learn more about programming fundamentals. Believe me when I say, I have learned a lot. The little tiny, almost none functional game attached, took me around 5-10 hours to program. I programmed, then reprogrammed, then found a better way to do something else, reprogrammed, then worked through a harry array of bugs... yeah, it was fun.

Anyway, this little text RPG only is good for about 2-5 minutes of gaming, depending upon how fast you read. You can start a new game, provide your name, select your class, and that's about it. Yeah, not that much there.

I just wanted to know if I am going in the right direction. I am not sure if how I am programming, is the "correct" way to go about things. I am not even sure if there is a "correct" way. I just don't want to develop any bad habits. ><

My main questions with the provided source is how I reference files. I have several .C files and a .H file. I used to have several header files, though I removed them and replaced them with .C files. I am not sure if I am including them correctly (or if I have to include them at all), or what file can see what, etc. Is there a good tutorial on handling multiple files? I am merely using several .C files to keep things organized, like: town.c, intro.c, etc. Each portion of the game, I have new .C files.

Anyway, feel free to browse through the source and state your opinion. What am I doing that is good and what is bad, in your opinion. This is just the start of a learning project. My main idea is to have a text RPG where you can control more than one hero at the same time (group). I am aiming at programming a full fledge text based RPG that is similar to Final Fantasy 1. It won't carry the same story line, though there will be a few similarities. Thought the project would be interesting.

Anyway, I'll shut up now.... I ramble too much. Have a good one guys and thank you for your help and time!

Achithyn Wrote:My main questions with the provided source is how I reference files. I have several .C files and a .H file. I used to have several header files, though I removed them and replaced them with .C files. I am not sure if I am including them correctly (or if I have to include them at all), or what file can see what, etc. Is there a good tutorial on handling multiple files? I am merely using several .C files to keep things organized, like: town.c, intro.c, etc. Each portion of the game, I have new .C files.

When you need to access code in a .c which resides in another .c, then you need to include the .h of that other file at the top of your .c.

You generally separate a project's source files into logical groups. In your current code, it seems you are grouping things by place (town.c, forrest.c, ridge.c). That is a fine logical separation for a small project.

However, as your project grows in size you will probably find it difficult to store everything in its own source file. In fact, it would prove easier to extract the actual data about these places out into resource files (ie, XML files) and write generic code which can handle all rooms. For example, your game could be:

room.c : code which handles everything internal to a room

room_graph.c : code which handles how rooms interact. If a door exists from room A to room B, this code handles that knowledge. A simple directed graph works best for this.

game.c : Handle starting the player in the first room, displaying player options, handling player input, allows room movement based upon the room graph.

Quote:When you need to access code in a .c which resides in another .c, then you need to include the .h of that other file at the top of your .c.

So, if you have two .c files: blue.c and green.c, and they both include one header file, blueen.h, they should be able to see the content of each other? Does their prototype functions have to be declared within the header to be accessible?

Make sense? blue.c and green.c contain the "meat" of the functions. blue.h and green.h describe the functions contained in the .c. We supply blue.h and green.h to main.c so he knows how to call the functions in blue.c and green.c.

Hey KittyMac,
Thanks for your in depth example. What you've pointed out makes sense. I tried the example on a test project I've started up to play with each code tidbit I learn, so that I can remember it. Your little project worked.

What I don't understand, though, is why I have to include the "helpdocs.c" file within my main.c file, in order for the PlayerQuestion function is able to see the content within that .c file. If you remove the #include "helpdocs.c" within main.c, and type ?Fighter, the compiler returns an error stating that the function does not exist. If I can make sense of this little problem, I think I will have this bit down for good.

Also, just to be sure, all .C files can share the same .H file, correct? You don't have to have blue.c with blue.h and green.c with green.h, you can have blue.c and green.c with purple.h - right?

first of all, never #include a .c file -- if you need to, you're doing something wrong.

second, .h files are used to declare things that need to be visible from multiple .c files. If you only ever #include a .h file once, that's probably a poor stylistic choice.

function declarations:

Code:

extern int myGreatFunction(int someParameter);

global variable declarations (go easy on the globals!):

Code:

extern int myGlobalVariable;

Third, each function and global variable must be defined in one, and only one, .c file.

function definitions:

Code:

int myGreatFunction(int someParameter)
{
/* some code */
}

global variable definitions:

Code:

int myGlobalVariable = 3;

fourth, stylistically, you should pair your headers and your source files -- eg. foo.h should contain declarations for the functions and globals in foo.c that other .c files are allowed to use.

By that rule, you will sometimes have a .c file that has no header (particularly main.c ) but seldom have a header without a .c file (generally only if the header provides only macros and inline functions -- topics for another time).

If you eventually want to have the player control a group of heroes you need to re-think how you handle a hero. Currently it looks like you just define a bunch of ints and character strings (heroExperience, heroHealth, etc.). The common way of doing this is to create a struct that contains each attribute of a hero.

Greetings all,
Thank you for all the help. I believe I understand how to work with multiple files now. The only problem is, even after all the detailed examples and my own code, which I got to work on a test project, my helpdocs.c (now renamed help.c) still does not work.

I've rewritten a bit of my code, re-organized it and cleaned it up a lot. I tried to make a makefile, though the tutorial kind of confused me. >< I read through it twice. @KittyMac: perhaps if you could make me a makefile, I'll see how it is suppose to be done. I tried to make the graph, though got confused. Once I see my files organized in a make file, I should be able to see how it works, if you don't mind (I'll give it another go tomorrow, non-the-less).

My test code I wrote up in a separate project was able to see the other .c files without header files at all. Is this just because I was running it on my computer? I added the header files and wrote up all the functions with extern, though there was no change, it still worked - which is a good thing I suppose, though can be confusing to newbies.

Quote:If you eventually want to have the player control a group of heroes you need to re-think how you handle a hero. Currently it looks like you just define a bunch of ints and character strings (heroExperience, heroHealth, etc.). The common way of doing this is to create a struct that contains each attribute of a hero.

You have a valid point there. I was thinking of using the struct data type with weapons and monsters... oddly enough, I never really thought about it when it came to the heroes. >< Once I get my files seeing and interactive with each other, I will be rewriting a lot of the game. I want to remove most of the dialogue I have up and just get the core aspect of the game done, then go back and make it pretty. I also want to start the game off differently, so you can choose and edit four heroes, rather than one. I'll be sure to use structs for heroes, monsters, weapons, armor, spells, and NPC's.

Obviously I am doing something wrong. lol. I'll make sure to not include .c files anymore. It's just when I did it, everything started working. Now when I try it with the .h file, it is not. >< Does anything stick out in my code that says: "this is wrong!" ? I've been through it a few times and cannot see why my help.c file is being neglected.

Well, thank you all for your help. I'm learning quite a lot. It's just, I can't find anything in my book concerning file management among .c and .h files. I have The Complete Reference C Fourth Edition, C Primer Plus (in the mail), The C Programming Language, and Learning C on the Mac. If you have any of these books and know of a good section I should look over, please let me know.

Achithyn Wrote:@KittyMac: perhaps if you could make me a makefile, I'll see how it is suppose to be done. I tried to make the graph, though got confused. Once I see my files organized in a make file, I should be able to see how it works, if you don't mind (I'll give it another go tomorrow, non-the-less).

I'm no makefile guru, so others may jump in and critic this. However, I tried to keep it simple (no variables and whatnot) so you can understand what a makefile does.

Basially, a makefile is simply a collection of shell commands. You can break things out into sections, which allows you to compile separate portions of your code together.

BTW, you had three functions undefined... I added stubs to get it to compile.

Code:

all: help intro main town
gcc help.o intro.o main.o town.o -o game

help:
gcc -c help.c -o help.o

intro:
gcc -c intro.c -o intro.o

main:
gcc -c main.c -o main.o

town:
gcc -c town.c -o town.o

On the command line while in that directory, simply type "make". Make opens the makefile, looks for the "all" section, and then compile all dependent sections (the listing after all: ). This in turn executes the gcc commands in order, stopping if gcc reports an error. Once the dependents are done, it runs the last gcc which stitches all of the .o's together into an executable "game".

It is also good to include a clean: section which removes all .o's in the directory. I left that out for you to add.

Sorry for the link to a bad tutorial... I'll admit I simply Googled one and scanned it briefly.

[edit]
Be careful, each line after a section label needs to be indented with a tab. I don't know if the code block trashed that or not.

Your Makefile may work, but isn't the normal way to write such a thing. One might write:

Code:

all: program

program: a.o b.o
gcc a.o b.o -o program

a.o: a.c a.h
gcc -c a.c -o a.o

b.o: b.c b.h a.h
gcc -c b.c -o b.o

clean:
rm -f program a.o b.o

Obviously, writing out all the dependencies and rules like this is time-consuming and error-prone, so there are shortcuts for that. I used to have an example lying around, I'd have to dig that out.

These days, many projects are moving away from Make because it's so easy to make a subtly incorrect Makefile. There are several replacements, eg. Cons and SCons. SCons is my personal favorite. This is an SConstruct for the program above:

Quote:On the command line while in that directory, simply type "make". Make opens the makefile, looks for the "all" section, and then compile all dependent sections (the listing after all: ). This in turn executes the gcc commands in order, stopping if gcc reports an error. Once the dependents are done, it runs the last gcc which stitches all of the .o's together into an executable "game".

That is really neat. I was wondering how I could compile all my source into one clickable/runable program. Thanks for creating the makefile for me, I think I understand how it is suppose to work now.

Quote:These days, many projects are moving away from Make because it's so easy to make a subtly incorrect Makefile. There are several replacements, eg. Cons and SCons. SCons is my personal favorite.

I bookmarked the sconstruct website. I'll go back later to download it, though, which one do I get that works on the mac? I think it will be helpful to know how to go about the different ways of compiling your code. Makefiles seem easy now after seeing it work. I look forward to trying SCon now.

Quote:Obviously I am doing something wrong. lol. I'll make sure to not include .c files anymore. It's just when I did it, everything started working. Now when I try it with the .h file, it is not. >< Does anything stick out in my code that says: "this is wrong!" ? I've been through it a few times and cannot see why my help.c file is being neglected.

I think I resolved my problem. You see, there wasn't one. Grrrr! I think the problem was with Xcode. I unchecked the help files, ran the program, then checked the boxes for my help.c and help.h - ran the program again, and... automagically, it works. *sigh* Was this just a glitch?

Thank you for your help and time! I'll get to work on this soon to be awesome text rpg.