14
\$\begingroup\$

I have a project to make a real-time strategy game from scratch. I am still at the early planning stage, but I have been programming a little to see the mechanics.

I know how to program. I also have a good idea of how I will structure the game classes and the Rule-Based (state-machine) AI for the computer player.

I want to develop Doctrines, which will give a specific behavior to a specific unit (but can be used on many units at the same time), such as Scout, Follow Mission Route, hold Position (attack any approching enemy or retreat if overwhelmed), etc...

The doctrines will only apply to the units, so it will have a unit perspective, and not be aware on the whole map sitatuation.

The Computer AI will analyse the entire visible map and decide on which soctrine to assign each unit depending on another set of rules.

I am doing this in C# with OpenGL.

For now, I don't have much, only a few things in tests before I begin my main conception. I have a game loop where all the game processing (where I will call the update mouvement, combat, rendering, etc, one after the other) will happen, it is called very often if the Application.Idle event.

Now, I was wondering. Since there will be a lot of things to process in the gameloop, should the Computer AI and the Units select their actions in that loop or will it be too slow?

If I want all things to be simultaneous, Should I create a separate Thread for the computer AI? Or even a separate thread for every unit?

I don't have much experience with multi-threading. What would be the best approach for this?

\$\endgroup\$
6
  • \$\begingroup\$ Unrelated - considered Ogre3D instead OpenGL? \$\endgroup\$
    – Daniel Mošmondor
    May 15, 2011 at 7:36
  • \$\begingroup\$ Actually, no, I never heard of it. I'm using OpenGL because that's what I was taught in my classes. Can Ogre3D do 2D too? I suppose it can, but we never know... \$\endgroup\$
    – Mathieu
    May 15, 2011 at 7:44
  • \$\begingroup\$ Yes it can, it even has its own GUI toolkit (cegui). For example, TorchLight is built with it. It can save you time because it wraps nicely AROUND OpenGL. ogre3d.org/tikiwiki/MOGRE \$\endgroup\$
    – Daniel Mošmondor
    May 15, 2011 at 8:07
  • \$\begingroup\$ "Or even a separate thread for every unit" Hell no. The overhead of a thread is much too big. For one there is the reserved memory for the stack of the thread(1MB by default). And thread switches are expensive too. \$\endgroup\$
    – CodeInChaos
    May 15, 2011 at 12:41
  • \$\begingroup\$ migrated per meta.gamedev.stackexchange.com/questions/434/… \$\endgroup\$ May 18, 2011 at 8:25

4 Answers 4

3
\$\begingroup\$

What does "from scratch" mean? Can you use something like XNA instead with DirectX?

You should be rendering something between 30 and 60 frames per second to have fluid motion. There is really no need to have more fps.

If rendering + logic takes less less than the 16ms that 60fps gives you, then there should be no need for an AI thread.

If you won't have enough time between rendering the frames then you are going to have to think really carefully on what must be updated every frame and what does not.

I'd guesstimate that the "doctrines" part should be as simple and efficient as possible so that it can be updated every frame, at least for visible units and other units nearby. The units that do not influence the visible units directly can be updated less frequently (and, correspondingly, with a greater delta T).

The main AI has more work to perform, as it has to process all the units on the map and figure out a strategy, so it should require most of the computation time. It is the first candidate for a separate thread.

Note that you might want to add another layer between the two, something like an squad level AI. Basically, each unit's AI should make sure the unit responds "intelligently" to the immediate situation, so it needs to be fast and responsive. The squad AI is responsible for the "intelligent" actions of several units, spread across several seconds, like finding a bridge if the squad needs to cross a river. And the main AI should direct the actions of lots of squads over a long period of time.

Especially if you don't have a lot of experience, don't do threading if you don't have to. This will be complicated as it is without an extra burden. You can learn multithreading as a separate project, or as an extension of this one once it is in a working state. Good luck!

\$\endgroup\$
0
\$\begingroup\$

Have a separate thread for AI. But not for every unit since it would consume too much OS resources and synchronization would be a nightmare.

Make sure the AI thread would find an opportunity to execute. Don't take it lightly, if the main thread does too many things, it may never find that opportunity! If you simply give higher priority to AI thread, then the game becomes unresponsive, which is unacceptable.

So, carefully select sync points and/or events in main loop and allow the AI thread to complete its calculations while the main thread stops. For example, if the user unit sees another AI unit, sync it, so your unit sees an updated unit vice versa.

\$\endgroup\$
0
\$\begingroup\$

I am also working on a RTS game from scratch. I haven't tested it yet, but my idea was to run unit AI in the main game loop for all units that are currently visible to the player (in the part of the screen that the player actually see's or near the border of that screen), as it is more likely that the player will move the screen a bit.

The other units are checked in a separate thread, and I have two priorities: 1. Units that are in places which are visible to the user if he moves the screen there. 2. Units that are in hidden areas (not yet explored and "fog of war").

For units in the seconds priority, i run the loop less often, and compensate by moving them retrospectively when needed.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Sounds very complicated. \$\endgroup\$
    – Eric
    May 15, 2011 at 13:19
  • \$\begingroup\$ Your idea sounds fine except for the first part about moving units into and out of the main game loop. All AI should be done in it's own loop, where you can select to skip the loop every x iterations on low priority units. \$\endgroup\$
    – Olhovsky
    May 18, 2011 at 20:25
0
\$\begingroup\$

Whether you need to multithread or not, it might be a good idea to prepare the AI to be multithreaded.

Your main thread would update the world, tick the physics, etc, and then would populate a data structure that represents the AI's view of the world: position of units, state of resources, etc. This data structure would cache the main systems, rather than just hold pointers to them. This is sometimes called a synchronisation point.

Pass this data structure to the AI, and only allow it to reason on the contents of this structure. If you find the AI needing more info, add it to the structure. In AI parlance this is often called a blackboard but could also be referred to as a cache. Never let the AI write to the cache, the output should come through a seperate data structure.

This setup will allow you to parallelise the game because the AI no longer has any direct dependency on the other game systems. Those systems don't need to be threadsafe and you should never get locks. You can safely run the renderer or something while the AI whirrs away.

As a secondary benefit, you can in future extend the cache by decaying the information you get from the other systems over time, simulating uncertainty rather than exact knowledge.

\$\endgroup\$

You must log in to answer this question.