views:

1245

answers:

7

I wanted to "emulate" a popular flash game, Chrontron, in C++ and needed some help getting started. (NOTE: Not for release, just practicing for myself)

Basics:
Player has a time machine. On each iteration of using the time machine, a parallel state
is created, co-existing with a previous state. One of the states must complete all the
objectives of the level before ending the stage. In addition, all the stages must be able
to end the stage normally, without causing a state paradox (wherein they should have
been able to finish the stage normally but, due to the interactions of another state,
were not).

So, that sort of explains how the game works. You should play it a bit to really understand what my problem is.

I'm thinking a good way to solve this would be to use linked lists to store each state, which will probably either be a hash map, based on time, or a linked list that iterates based on time. I'm still unsure.

ACTUAL QUESTION:

Now that I have some rough specs, I need some help deciding on which data structures to use for this, and why. Also, I want to know what Graphics API/Layer I should use to do this: SDL, OpenGL, or DirectX (my current choice is SDL). And how would I go about implementing parallel states? With parallel threads?

EDIT (To clarify more):
OS -- Windows (since this is a hobby project, may do this in Linux later)
Graphics -- 2D Language -- C++ (must be C++ -- this is practice for a course next semester)

Q-Unanswered: SDL : OpenGL : Direct X
Q-Answered: Avoid Parallel Processing
Q-Answered: Use STL to implement time-step actions.

So far from what people have said, I should:
1. Use STL to store actions.
2. Iterate through actions based on time-step.
3. Forget parallel processing -- period. (But I'd still like some pointers as to how it
could be used and in what cases it should be used, since this is for practice).

Appending to the question, I've mostly used C#, PHP, and Java before so I wouldn't describe myself as a hotshot programmer. What C++ specific knowledge would help make this project easier for me? (ie. Vectors?)

A: 

I have played this game before. I don't necessarily think parallel processing is the way to go. You have shared objects in the game (levers, boxes, elevators, etc) that will need to be shared between processes, possibly with every delta, thereby reducing the effectiveness of the parallelism.

I would personally just keep a list of actions, then for each subsequent iteration start interleaving them together. For example, if the list is in the format of <[iteration.action]> then the 3rd time thru would execute actions 1.1, 2.1, 3.1, 1.2, 2.2, 3.3, etc.

Jason Z
And I would store these actions with the time as the key, as in an associative array?
apandit
As long as you have a fixed time frame between steps, a simple list should do. No problems with using a key, but it just seems simpler.
Jason Z
A: 

After briefly glossing over the description, I think you have the right idea, I would have a state object that holds the state data, and place this into a linked list...I don't think you need parallel threads...

as far as the graphics API, I have only used opengl, and can say that it is pretty powerful and has a good C / C++ API, opengl would also be more cross platform as you can use the messa library on *Nix computers.

mmattax
A: 

A very interesting game idea. I think you are right that parrellel computing would be benefical to this design, but no more then any other high resource program.

The question is a bit ambigous. I see that you are going to write this in C++ but what OS are you coding it for? Do you intend on it being cross platform and what kind of graphics would you like, ie 3D, 2D, high end, web based.

So basically we need a lot more information.

A: 

Parallel processing isn't the answer. You should simply "record" the players actions then play them back for the "previous actions"

So you create a vector (singly linked list) of vectors that holds the actions. Simply store the frame number that the action was taken (or the delta) and complete that action on the "dummy bot" that represents the player during that particular instance. You simply loop through the states and trigger them one after another.

You get a side effect of easily "breaking" the game when a state paradox happens simply because the next action fails.

enigmatic
A: 

Unless you're desperate to use C++ for your own education, you should definitely look at XNA for your game & graphics framework (it uses C#). It's completely free, it does a lot of things for you, and soon you'll be able to sell your game on Xbox Live.

To answer your main question, nothing that you can already do in Flash would ever need to use more than one thread. Just store a list of positions in an array and loop through with a different offset for each robot.

Iain
+3  A: 

This sounds very similar to Braid. You really don't want parallel processing for this - parallel programming is hard, and for something like this, performance should not be an issue.

Since the game state vector will grow very quickly (probably on the order of several kilobytes per second, depending on the frame rate and how much data you store), you don't want a linked list, which has a lot of overhead in terms of space (and can introduce big performance penalties due to cache misses if it is laid out poorly). For each parallel timeline, you want a vector data structure. You can store each parallel timeline in a linked list. Each timeline knows at what time it began.

To run the game, you iterate through all active timelines and perform one frame's worth of actions from each of them in lockstep. No need for parallel processing.

Adam Rosenfield
+6  A: 

What you should do is first to read and understand the "fixed time-step" game loop (Here's a good explanation: http://www.gaffer.org/game-physics/fix-your-timestep).

Then what you do is to keep a list of list of pairs of frame counter and action. STL example:

std::list<std::list<std::pair<unsigned long, Action> > > state;

Or maybe a vector of lists of pairs. To create the state, for every action (player interaction) you store the frame number and what action is performed, most likely you'd get the best results if action simply was "key pressed" or "key released":

state.back().push_back(std::make_pair(currentFrame, VK_LEFT | KEY_PRESSED));

To play back the previous states, you'd have to reset the frame counter every time the player activates the time machine and then iterate through the state list for each previous state and see if any matches the current frame. If there is, perform the action for that state. To optimize you could keep a list of iterators to where you are in each previous state-list. Here's some pseudo-code for that:

typedef std::list<std::pair<unsigned long, Action> > StateList;
std::list<StateList::iterator> stateIteratorList;
//
foreach(it in stateIteratorList)
{
  if(it->first == currentFrame)
  {
    performAction(it->second);
    ++it;
  }
}

I hope you get the idea...

Separate threads would simply complicate the matter greatly, this way you get the same result every time, which you cannot guarantee by using separate threads (can't really see how that would be implemented) or a non-fixed time-step game loop.

When it comes to graphics API, I'd go with SDL as it's probably the easiest thing to get you started. You can always use OpenGL from SDL later on if you want to go 3D.

Andreas Magnusson
Thanks for the great detail on this one. This actually looks like a good solution for this. Any recommendations on the graphics engine to use to go along with it?
apandit
I'd go with SDL as it's probably the easiest thing to get you started. You can always use OpenGL from SDL later if you want to go 3D.
Andreas Magnusson
OGRE is a great 2D73D game engine for C++
Hernán