Advertisement

Settlers/RTS AI

Started by September 30, 2007 05:35 PM
2 comments, last by ggp83 17 years, 2 months ago
Don't know if this question belongs here or the Game Programming forum, but I take my chances here. I've got an idea of a game similar to Settlers, however I've never made an RTS before and there are some questions I need answered, or suggestions on... What I mostly can't figure out is how to handle when you give your little people commands. Like tellings one guy to cut a tree and then he performs it, or tell another guy to attack something which he then does. I've come up with two solutions to this, either just hardcode the whole "cut tree" process into a single or a couple of functions, so that once the command is given, the guy finds a tree, cuts it down, clears it from any branches and then carries the tree to a sawmill or whatever, and then all over again. Or I could go with a way where each step is a small task. So you basically have a "work" which in this case is called "cut tree", and this "work" has smaller tasks which needs to be performed in a certain order. So for this cut tree example, the first task would be to walk to the closest/random tree. The second task would be to cut it down. The third task would be to clear cut it. The fourth task would be to deliver it to a sawmill. Then the fifth task would either be go home and rest or go back to the first task. In code, the first example would basically just look like this:

class Character {
  void performWork(WorkType ) {
    // lots and lots of code, actually this is probably a bad way
    // of doing this..
    if( workType == CUT_TREE ) {
      cutTree();
    }
  }

  void cutTree() {
  }
}


Where as the second example would look something like this:

class Work {
  void addTask(Task newTask) {}
  void performWork() {
    // work it's way through each task
  }
}

class Task {
  void abstract perform(Character chr);
}

class WalkToTask extends Task {
  void perform(Character chr) {
    // move character to some destination
  }
}

class CutTreeTask extends Task {
  void perform(Character chr) {
  }
}
//.. and so on..


The problem with the second example, is that these task classes would depend alot on the character class. For example, when you start the cut tree task, that task would have to start the characters "cut tree" animation and start the neccessary sounds etc, and there's alot more dependacies which I can't come up with right now. However it seems like a much nicer way, since the Character class wouldn't get so damn huge, like it would if I hardcoded everything it could do into one single class.. Of course I could skip the whole task system, and just keep the work class, and make a work class for every possible command. Anyways what do you think of my thoughts? Am I attacking this "problem" from the wrong direction? How would you solve this, codewise? I'm happy if I get anything to get me in the right direction, so links and stuff like that are welcome too. No books tho, I won't buy that hehe, to cheap :P
Do you have an idea how the code will be used? If so, then that's the most important design factor. If not, then I suggest you start with that part of the code...

For example, if you always call performWork(CUT_TREE) then you might as well just call cutTree() directly! Make that a virtual function and you'll be ok.


I've seen both approaches used, but I personally prefer the second example you show. It is more code, but it's more modular. You can dump tasks into a lookup table, and it becomes easily data-driven.

I hope that helps a bit.

Join us in Vienna for the nucl.ai Conference 2015, on July 20-22... Don't miss it!

Advertisement
Hi,

great to see that there are ppl out there who want to do a Settler similar game. Having been working on Settlers 4, this makes me particulary happy :)

As for your question:

Since your game won't only have a lumberjack, the second approach would be the most effective. Not only you can cut down the tasks into much smaller parts but you also can stick new tasks in between 2 others (i.e. a blacksmith who has to light a fire, goes to the ambush and then heats the fire... you can stick any intermediate task in between the lighting and the heating of the fire).

Also, be aware that the "jobs" are animation dependent. This means that to look good, you have to make sure that the animation fits. Therefore, a subtask such as removing any branches from a trunc are mostly hardwired. This means that there are fix positions at the trunc where the lumberjack goes to to play his "cut off the branches" animation. You have similar positions for anything that can be used by the character (i.e. a position at the ambush so that the blacksmith is standing right to the ambush turned towards it). Those positions are called anchor points.

Feel free to ask any question you'll like to ask.

Metron
----------------------------------------http://www.sidema.be----------------------------------------
Wow, thanks for your comments they're great :) I felt very unsure about my ideas before hearing your comments on them, so they've helped alot!

But since both of you like the second idea most(and me too), I think I'll go ahead and start implementing small pieces of code and see where it takes me. And if I struck any other design issues along the way I'll make sure you hear from me hehe.


Quote:
great to see that there are ppl out there who want to do a Settler similar game. Having been working on Settlers 4, this makes me particulary happy :)

Omg! That's amazing :) I've been playing settler games since the first one on Amiga, I just love those games!

Quote:
Do you have an idea how the code will be used? If so, then that's the most important design factor. If not, then I suggest you start with that part of the code...

For example, if you always call performWork(CUT_TREE) then you might as well just call cutTree() directly! Make that a virtual function and you'll be ok.

Heh, you're actually right! Think I have some kind of fetish for static big-lettered variables :/
Na, but actually I think the idea behind that was so that I could have a queue of different jobs, so you could execute a couple of jobs after each other.

This topic is closed to new replies.

Advertisement