Log in to check your private messages

Rive's Programming Thread of Doom
Page 1, 2, 3 ... 11, 12, 13  Next
 
Post new topic   Reply to topic    Rebels Forum Index » General Discussion View previous topic :: View next topic  
Rive's Programming Thread of Doom
 PostPosted: Fri Oct 30, 2009 3:21 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

As mentioned in another thread, I'm thinking of restarting work on The Battlesystem (AKA: Project Maelstrom).

For those of you that don't remember it, here's what it looked like in its last incarnation:
Spoiler:



Also as mentioned in another thread, the project is going to be a bit more ambitious in scope this time around (that last time around I had the system built from scratch to "nearly complete" in under a week since it had a very small scope).

That said, it's likely that sooner or later - I could use some help.

So, I'll be teaching some basic programming skills in this thread to give you the ability to do that if you're so inclined/ambitious/awesome.

The only recommendation is that you download Eclipse, since it's what I work in and will be pretty much required if you want to help. You can wait a few days on that.
You'll want "Eclipse IDE for Java Developers (91 MB)".

So here we go. The plan is for me to post a basic little tidbit of information that'll help you help me (and yourself if you find this sort of thing interesting and decide to pursue it on your own) every day. We'll see how that goes. As long as 2 or more people are following along, I'll probably keep it up.

Day 1
Spoiler:

Data is obviously pretty key to computer systems. 1's and 0's. Thankfully, Java is a "high level" programming language - so we don't need to worry about 1's and 0's.

What we do need to worry about is "primitives" and "objects".

Today, we'll just cover primitives.

A primitive is a data type that stores a value. Java's primitives include: byte, short, int, long, float, double, boolean, and char.

We'll mostly be interested in the ones in bold.

An int is short for "integer" - meaning it can hold whole numbers (2, 5, -3, 7, 0, etc).

A double is similar to an int, but it allows decimals (2.556, -3.56, 1334, etc).

A boolean can only hold two values. True - or false.



Day 2:
Spoiler:

Review from day 1:
Java uses primitives and objects to hold data.
The primitives we're mainly concerned with are ints, doubles, and booleans.

So how do we actually create a primitive to hold data?

It's a relatively simple process. We simply need to tell Java what primitive we want and give it a name.

For example:
int counter;

I've just declared an int named 'counter'.

Then I can initialize it by giving it a value.
counter = 3;


It's worth noting that you CAN declare and initialize on the same line:
int counter = 3;

That's perfectly valid. In either case the end result is storing the integer value 3 to our 'counter'.

You may have noticed the semicolon at the end of those lines. A semicolon is how you tell Java you're done writing a particular line of code.

Now let's talk a bit about manipulating data once we have it.

int value1 = 5;
int value2 = 7;
int value3;


You can see we have 3 ints here. The first two have been initialized by associating data with them, the last has not.

value3 = value1 + value2;

That's obviously valid. value3 = 5 + 7. Thus, we've just assigned 12 to value3.

Not everything is so obvious though:
value3 = value3 + 2;

Well that's crazy! 12 = 12 +2?  12 = 14? That's madness! This is some 1984 2 + 2 = 5 lies! LIES!

... But this is valid in Java.

Why?

We're not actually saying "12 equals 14"
What we're saying is: "value3 is assigned the value of value3 plus 2."

'=' in Java should be read as "is assigned" not "equals".

There are two other operator symbols we should be aware of at this point:
'++' meaning "increase by 1"
'+=' meaning "increase by the following value"

Example:
int value1 = 5;

value1++;


value1 was assigned the value 5 and was then increased to 6 on the next line.

value1 += 1;

That's valid and does the same thing, but it's longer. So we generally use the '++' symbol when we want to increment something by 1. That sort of thing comes up very often.

So now value1 has increased to 7.

value1 += -7;

That reads a bit oddly in english, "value1 is increased by negative 7" --- but it is valid.

value1 is now 0.

It's worth noting we could have done the same thing with a '-=' operator instead and made it much more easily read:

value1 -= 7;
"value1 is decreased by 7"

value1 is now -7.



Day 3:
Spoiler:

We're going to talk about objects tomorrow. But today we're just going to deal with a special object: String.
A string is an object, but it's used soooo often for soooo many things that Java has special rules for using them. In fact, it makes them look a lot like primitives.

So today we're going to write a program that's pretty much the first program every programmer being taught programming after 1970 has done.

First, let's remember how we declare a variable:
String myString;

I've declared a String object.

Now, as I said, for most objects this part would look different, but for Strings - initializing it will look pretty much the same as it did for primitives.
myString = "Hello World!";

So now I've assigned "Hello World!" to myString.
You might wonder why it's called a string. A string object is actually a bunch of char (short for "character") primitives that have been 'strung' together. It's much easier to work with a String than a bunch of individual letters. Imagine if we had to say:
char char1 = 'H'
char char2 = 'e'
char char3 = 'l'


And, in fact, that IS similar to what we had to do back in the old days of programming! Be thankful that's no longer the case! :D

Alright, so now we have the phrase "Hello World!" stored in Java code. But how do I display that to the world? How do I access that data?

1. Open up your Eclipse program. Just press "Ok" when it asks you to select a workspace.
2. You're probably on some sort of welcome screen. Find and click the button (should look like a bent arrow) that says "Workbench". It's probably in the upper-right hand corner.
3. With any luck, you're on a screen that looks like:


4. Select the "File" menu, then hover over "New", then select "New Java Project"
5. Type in a name for the project folder, maybe "Rebels Stuff". Then click "finished" at the bottom. You can ignore the rest of the settings.


6. The project folder should have appeared on the left side of the screen (as in the screenshot above) now. Right click it and say "New" then "Class" (we'll talk more about classes later). It should be the fourth one down.
7. Name the class "HelloWorld" - you can ignore the rest of the settings and just click "Finished". Make sure you didn't put a space between the words in the name or it won't work.

Now things should look like this:


Alright, fantastic!

Now, you know that a semicolon ends a line of code.
Now you need to know that curly braces ( '{' and '}' )enclose sections of code.
We'll talk more exactly about when you to use those later.

So, between the two existing curly braces, copy and paste this line in:

public static void main(String[] args){

That line is quoted on Urban Dictionary.com as "The most annoying line a beginner Java programmer has to type in each one of their programs." and they're right :)

Now, you'll notice that line ends with a curly brace. That means you need to close it.

Fortunately, you can just press "enter" now and Eclipse should add the closing curly brace for you - since Eclipse is cool like that.

Make sure things look like this now:


Now declare and initialize a String saying "Hello World!". You can look back up above if you need help doing that, or you can just scroll down and look at the next screenshot:








You'll notice that 'myString' (or whatever you chose to call it) is underlined in yellow. That's an Eclipse warning. It's Eclipse telling us (in this case), "You just declared and initialized a variable... but you aren't using it anywhere? That's a waste of space. What's up?"

So let's use it.

Here's another piece of code you can just copy and paste - you don't need to understand it perfectly yet:
System.out.println();

That's how we tell Java to print something to our console. You'll see the console in a moment.

Now, put that line of code in your program - BELOW where you initialized your string.

Between the parenthesis in that line of code, put the name of your string.

You'll notice the yellow warning line went away. Because now we're using that variable.

Try to finish that step on your own, but if you have trouble then you can click here for a solution: [Solution]

Now, finally, go up to the "Run" menu (far to the right of "File") and press "Run" - the first option in the dropdown.
Or you can just hold ctrl and press F11 on your keyboard.

It's possible that this screen will come up, maybe it won't:

If so, just select "Java Application" and press "Ok".

If everything's gone right. This should show up at the bottom of your Eclipse window!


Hello Java!



Day 4:
Spoiler:

Today we're going to do two things. We're going to introduce the concept of an object - and we're going to run through another program (or, if you're more ambitious, you can write it yourself).

Pretty much everything in Java is a class, an object, or a method - or one of those primitives we've already talked about.
You've already used one class, actually, since you probably noticed your first program started with public class HelloWorld. But we're still going to hold off on talking about those, for a moment.

And, as I told you, you already used an object - the String.

But, as I ALSO told you, Strings are special in Java - since they're used so often. BUT you can also use Strings like regular objects - skipping the shortcuts Java lets you use for them. So let's do that.

Here's how we declared and initiated a string using Java's shortcuts:
String myString = "Hello World!";
Which was pretty much how we did primitives.

If, however, we use our String like most objects... it changes a bit.
String myString = new String("Hello World!");

The declaration stayed the same, but the initiation (right of the '=') changed.

That basically reads, in English, as: "I declare a String object named 'myString' and then I initiate it as a new String object with "Hello World!" as its arguments we're passing it.

We'll talk more about passing arguments and objects tomorrow. For now, we're going to pull back and do another program and look at another concept.

-----------------

Recall that we could modify ints we'd declared and initiated using operators like '+=' or '++'

Now we're going to introduce a new concept: The While loop.

A while loop looks like this:
while(){

}


Fairly simple looking. Inside the parenthesis we can place a condition. The while loop will keep repeating - over and over - as long as that condition is true. For instance, we could say:
while(true){

}


Well, you don't want to say THAT because that's ALWAYS going to be true. Your program will start repeating forever in an "infinite loop" and lock up - which is bad :)

But we could also do something like:
int counter = 16;
while(counter >= 4){
   System.out.println(counter);
   counter = counter / 2;
}
System.out.println(counter);

So we started with 16 stored to our 'counter'
Then we got into the loop. The condition is: while 'counter' is greater than or equal to ('>=') 4 - keep going.

16 is greater than or equal to 4, so we go into the loop.
We print out 'counter' (16).
counter is assigned the value of counter (16) divided by 2. So now it's 8.

Now, we go back up to the top of the while loop to see if we need to keep going.

'counter' (8) is still greater than or equal to 4. So we keep going.
We print out 'counter' (8).
We assign it the value of itself divided by 2. So now it's 4.

Again, we go to the top of the while loop. Is 4 greater than or equal to 4? Yes, it's equal.

We print out 'counter' (4).
We assign it the value of itself divided by 2. So now it's 2.

We go back to the top of the while loop. Is 2 greater than or equal to 4? No. So now we're done and we exit the while loop.

Finally, we print out 'counter' one last time, since that's the next line of code outside the loop. (2).

Okay. Hopefully we understand while loops now. Let's apply them to a different situation.

------------------------

"Sir, the possibility of successfully navigating an asteroid field is 3,720 to 1"
"Never tell me the odds!"

I want you to write a program in a class called "NeverTellMeTheOdds" in which your program prints out all the numbers up to 50 - starting with 0 - that are even. No odds should be printed out.
Try to figure out how to do this on your own. But, if you have trouble - click below for a solution. I say 'a' solution because there are many different ways you could solve this problem.

[A Solution to this Problem]



Day 5:
Spoiler:

Today should be very easy if you understood yesterday's stuff.

We talked about while loops - and how they're based on conditions.

It's VERY often the case that we want to check a condition - but we don't want to loop.

For this we use:
if(){

}


Again, with a condition being placed in the parenthesis.

If we take a look at my solution to yesterday's problem:


We could add something like:
if(counter == 24){
System.out.println("Halfway there!");
}


We could add that just after our main print line, so our results would come out as, now:

...
20
22
24
Halfway there!
26
28
...


There was a new symbol there '=='
As we discussed, '=' roughly equates to "is assigned" in Java.
'==' does, in fact, mean "equals".



Day 6:

Spoiler:

Let me start by saying this: Anything you can do with a for loop can also be done with the while loops we already learned.

But, for loops are still highly useful and can make things a lot "cleaner".

Let's look at our "NeverTellMeTheOdds" program again (or, at least, my version):



It turns out that we want to do things like that a lot. That is, use a loop to go through a sequence of values or objects.

So, we have the for loop. Which is constructed like so:

for(initialization; termination; incrementation){

}


Initialization let's us create a counter-type variable. Termination lets us define the condition to end the loop. Incrementation says what to each time we loop.



By using a for loop instead of a while loop with an externally defined counter - we saved 2 lines of code and reduced chances for error.



Day 7:
Spoiler:

Recall that a few days ago we talked about how the String class in Java is special and normally you declare/instantiate it pretty much like you would a primitive. BUT we could also declare/instantiate it like a regular Object. Which looked like this:

String myString = new String("Hello World!");

So let's talk a bit more about objects.

An object is defined, in Java, by a Class. We've previously used classes to run our programs, but we can also use them to define objects.

Let's say, for instance, we want to create a class that defines Force Powers in a video game. We might have something along the lines of:



So look there at that:
public ForcePower(String powerName, int powerCost, String powerDesc){

That's called a constructor. It's how was say we want an object to be instantiated.

So now we'd be able to say - in another class that contains our program (that's in the same project/directory as our ForcePower class):

ForcePower forceChoke = new ForcePower("Force Choke", 15, "Through the power of the darker aspects of the Force, one can constrict the airway of their target.");

Huzzah! We've instantiated a new ForcePower object based on our construction rules in our ForcePower class!

That's all well and good. But what can we do with it?

To do something with our class, we need to define a method. We've already seen at least one method before.
System.out.println("Hello World!");

Somewhere in Java - in the code for the class System - you'd find the code for the method println. And then it would have code defining how to output data to the console.

Here's a theoretical method we could add to our ForcePower class:



As you can see, it looks fairly similar to our constructor.

The biggest difference is that constructors have no return type, while methods do.

public String use(...){

String is our return type for this method. We'll talk a bit more about return types on another day, but, let's suffice to say for now: after a method does its work, it's often useful for it to report something back to the class that called that method.

Our method uses a theoretical class "Player" (there is a red line under it because it doesn't presently exist in our codebase - but let's pretend it does).

A Player, in our system, has a number of "Force Points" to use Force Powers. In fact, let's say that the constructor for Player looks like this:

...
public Player(int startingForce){
...


Player has a method to report back (return) how many Force Points they have right now: getForcePoints()
A player also has a method to change their Force Points to another number: setForcePoints(int newPoints)

Rather than explaining exactly what this method does step-by-step, let's look at a concrete examples.

Let us imagine we have another class that we're defining a runnable program.

Player testPlayer = new Player(100);
ForcePower forceChoke = new ForcePower("Force Choke", 15, "Through the power of the darker aspects of the Force, one can constrict the airway of their target.");

System.out.println(testPlayer.use(forceChoke));
System.out.println(testPlayer.getForcePoints());


In this case, a Player is constructed with 100 force points to start with. Then we define our "Force Choke" ForcePower - it costs 15 points.

Therefore, when we call the use method of that power - by our player. It runs through just fine. When it got to this check in our ForcePower's use method:

if(caster.getForcePoints() < cost)

Java said: if(100 < 15).... no, 100 isn't less than 15, let's skip the code in this if section.

so then it moved on to:
caster.setForcePoints(caster.getForcePoints() - cost);
return "You use " + name;


So we'd print out the return statement: "You use Force Choke"

The next line of code in our program:
System.out.println(testPlayer.getForcePoints());

Would print out 85, since our testPlayer used 15 points in that use method of Force Choke (cast.setForcePoints(100 - 15);).

Let's look at a modification of that same example:
Player testPlayer = new Player(10);
ForcePower forceChoke = new ForcePower("Force Choke", 15, "Through the power of the darker aspects of the Force, one can constrict the airway of their target.");

System.out.println(testPlayer.use(forceChoke));
System.out.println(testPlayer.getForcePoints());


In this case, when we got to the testPlayer.use(forceChoke):
if(caster.getForcePoints() < cost)

Java said: if(10 < 15).... Yes, that's true. Let's do the code in this if block.

return "You don't have the Force power to cast " + name;

When a method returns - it stops executing any more code in that method. So we don't need to worry about anything below that in ForcePower's use method, in this case.

So our println statement would come out: "You don't have the Force power to cast Force Choke"

And the next line of code:
System.out.println(testPlayer.getForcePoints());

That would print out as "10" - since we never modified the testPlayer's Force points. We only determined they didn't have enough and returned.





_________________

May The Force Be With Us, Always


Last edited by Rive Caedo on Thu Nov 05, 2009 12:32 am; edited 9 times in total


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 4:06 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

Yeah I'll be interested in helping you out. I'll download the program in the next few days.
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 4:38 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

*nods*

Presuming this system gets laid out the way I envision, there'll basically end up being 4 tiers of help.

I. No help at all (/bioshock The Parasite Wink )
II. Able to make new basic force powers, enemies, and maps via easily modified text files.
III. Able to make some basic new features by knowing the basics of programming (example: adding a new force power that doesn't work like any previously created force powers)
IV. Rive (able to create the backbones that support things like force powers and maps in general)
V. Above Rive (Get away! Make your own program! Razz )

So my goal with these "lessons" is to - eventually - get people up to level III. That way I can spend more time on building backbones while others are able to flesh them out with content.

I am, of course, getting ahead of myself. So I'll try to pull back from grand plans for the moment and focus on little plans Smile
_________________

May The Force Be With Us, Always


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 4:46 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

Ha no worries, happy to help in anyway possible. Smile
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 4:59 am Reply with quote  
Message
  Dakoth
Senior Jedi Council Member
Senior Jedi Council Member

Joined: 31 Jan 2006
Posts: 11219


Location: Arkua

Well its downloading.  The primitives remind me a lot of the WCIII editor.
_________________
Audi famam illius                                    Aftershock.


View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger

 PostPosted: Fri Oct 30, 2009 7:21 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

Dakoth wrote:
Well its downloading.  The primitives remind me a lot of the WCIII editor.

You'll absolutely find any experience you have with the advanced features of the WCIII editor to be very helpful learning programming - because a lot of the WCIII editor is basically programming with training wheels.

I mean, take the very first trigger condition. It's just a flat boolean comparison. Something is equal to Something Else.
I liked unit-type comparisons.
(Unit-type of (Triggering Unit)) equal to (Footman)

We're not quite ready to get into actual Java syntax yet, but it shouldn't be hard to see that this is the same idea:
if(triggerUnit.getType().equals(footmanType))

Essentially, while the Warcraft III editor gave you lots of specific comparisons to use, when you get down to the actual code you can compare whatever you want.
The trick is that you also need to know exactly what your options are, hehe.
_________________

May The Force Be With Us, Always


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 7:32 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

Uhh, why would you want to compare things? Your post made very little sense to me. Razz
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 7:38 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

Well Dakoth was the one asking about the Warcraft III unit editor, not you - so hopefully it made sense to him Smile

By about day 3 or 4 you'll probably understand what types of things we can compare. But, to give you a quick example of why you'd want to do that.

Let's say the characters in our system have "types" attached to them - IE: Human, Droid, Rancor, etc.

Once we've established types, then we're able to do things like, for example, make it so that when you press your "Jedi Mind Trick" button on a unit, it'll check to make sure that unit is biological.
And then, if the comparison says "no, that thing you're targeting is not biological" we can make the ability not work and spit back to the user:
"Jedi Mind Trick failed, does not work on droids."
_________________

May The Force Be With Us, Always


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 7:40 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

Well yeah but I was trying to understand what you said.

Ah k that kind of makes sense now, so you'd want to use the like function to give greater detail on what a character is.

For instance could you use it to make different classes of Jedi?
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 7:45 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

Xander Vos wrote:
For instance could you use it to make different classes of Jedi?

Could I use comparisons to do that? No, not really.

What I CAN do (oh my, now we're really getting ahead of ourselves) is have, say:

My generic "Jedi" type. Which has force points and can learn Force powers.
Then I can have a more specific Jedi type, say "Jedi Guardian" that extends that generic Jedi type.
From the program's point of view, if I create a Jedi Guardian - it'll count as a Jedi Guardian (so I can run comparisons/checks and let them learn specific lightsaber attacks that other Jedi can't learn) AND a Jedi (so it'll have force points and such).

Don't worry at all if you don't understand the concept of "extends" or types or anything at all with this. As I said, we're way way ahead of ourselves.

Just make sure you understand an int can hold whole numbers, a double can hold decimal numbers, and a boolean can be true or false Smile
_________________

May The Force Be With Us, Always


Last edited by Rive Caedo on Fri Oct 30, 2009 7:47 am; edited 1 time in total


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 7:47 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

How do they 'hold' whole numbers?
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 7:48 am Reply with quote  
Message
  Rive Caedo
Jedi Grand Master
Jedi Grand Master

Joined: 02 Dec 2005
Posts: 8294


Location: Kallibann

That's exactly the question you should be asking Very Happy

And you'll receive the answer as Day 2's lesson tomorrow, hehe.
_________________

May The Force Be With Us, Always


View user's profile Send private message Visit poster's website

 PostPosted: Fri Oct 30, 2009 9:05 am Reply with quote  
Message
  Dakoth
Senior Jedi Council Member
Senior Jedi Council Member

Joined: 31 Jan 2006
Posts: 11219


Location: Arkua

I can't wait to drown myself in an endless  sea of conditions! yay!  Saving variables is fun!
_________________
Audi famam illius                                    Aftershock.


View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger

 PostPosted: Fri Oct 30, 2009 9:59 am Reply with quote  
Message
  Xander Vos
Sith Emperor
Sith Emperor

Joined: 08 Jan 2006
Posts: 19753


Location: The Sith Temple

I eagerly anticipate. Smile
_________________


Time to start again.


View user's profile Send private message Visit poster's website AIM Address MSN Messenger

 PostPosted: Fri Oct 30, 2009 7:26 pm Reply with quote  
Message
  Sirak Sazen
Knight - 5th Degree
Knight - 5th Degree

Joined: 25 Sep 2008
Posts: 5591


Location: The Asylum

Uhhhh, what?  Shocked



_________________

"I find it hard. It's hard to find, oh well, whatever, nevermind."


View user's profile Send private message Send e-mail Visit poster's website

Post new topic   Reply to topic    Rebels Forum Index » General Discussion

Page 1 of 13
All times are GMT
Page 1, 2, 3 ... 11, 12, 13  Next

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

Card File  Gallery  Forum Archive
Powered by phpBB © 2001, 2002 phpBB Group
Jedi Knights 2 by Scott Stubblefield

Create your own free forum | Buy a domain to use with your forum

The Star Wars Combine Banner Exchange