4
\$\begingroup\$

So I've reached the point in my exploration of gaming where I'd like to implement the concept of time into my little demo I've been building.

What are some common methodologies for creating the concept of time passing within a game?

My thoughts so far:

My game loop tends to spend a fair amount of time sitting around waiting for user input so any time system will likely need to be run in a separate thread.

What I've currently done is create a BackgroundWorker passing in a method that contains a loop triggering every second. This is working fine and I can output information to the console from here, etc. Inside this loop I have a DateTime object that is incremented by 1 minute for every realtime second. (the game begins in the year 01/01/01)

Is this a standard way of achieving this result or are there more tried and tested methods?

I'm also curious about how to go about performing time based actions (reducing player energy, moving entities around the game board, life/death etc).

Thanks for any pointers or advice. I've searched around, however I'm not familiar enough with the terms and so my searches are yielding little result on this one.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ What do you mean your main loop waits for the players input? Shouldn't the main loop be running and react to player input? \$\endgroup\$ Commented Feb 8, 2011 at 21:41
  • \$\begingroup\$ What kind of game are we talking about? \$\endgroup\$ Commented Feb 8, 2011 at 21:53
  • \$\begingroup\$ The game is a simple text-based console game. The main loop is always running but when it's waiting for the user to input something into the console (Console.ReadLine()), the loop comes to a pause (no code after this line is executed until the user enters something into the console window). \$\endgroup\$ Commented Feb 8, 2011 at 22:14
  • \$\begingroup\$ Are you having trouble with how to split up the game logic or keeping track of time and reacting to it? Where are you in terms of progress and what is it exactly that your having trouble with? \$\endgroup\$ Commented Feb 9, 2011 at 3:49

4 Answers 4

5
\$\begingroup\$

Most game loops I've encountered like to check an input state of some kind (not wait around for input, instead have it buffered).

I'm assuming your making some game with the Command Prompt in C#. You'll probably want to buffer input via ReadLine() in a thread safe queue. You should then implement a more normal game loop in a separate thread that checks this queue for new input every frame.

Also, you should probably keep track of time with a Stopwatch object or something that is strong performance wise. (I don't think your using DateTime.Now, but if you are it's a very bad idea)

That's how I would do it. Usually, time based actions are done via keeping track of passed time and executing a step (or the entire action itself) after certain intervals of time pass. So every certain unit of time (kept track after multiple updates) you would perhaps increment the age of the player or something of that nature. When the age is incremented, certain changes will take place (defined in the player's class perhaps).

That's just one way to do it, not necessarily the only/right way of doing it.

Edit: Once you've got your game loop, you should separate logic into separate classes (one for the player, one for a plant, etc, whatever is needed). These classes should be updated by the loop and they can keep track of their aging/changes. (they should be passed some kind of timing variable or should have a way of accessing it)

Edit2: If this is more of an architecture question (kind of like how I should structure my system so that my entities [like plants, people, etc] will age) than it's a bit harder to answer. I would have to say that you should take into consideration the structure you already have.

I would create a list of trackers for each game object. So a plant would have 3 trackers. These trackers would keep track of time and after a certain interval (predefined for each tracker) it would set off an event (passed in as a delegate perhaps). This delegate could make the plant grow older or do whatever. Also, the delegate could return true or maybe some custom object to define whether the tracker should continue to track time and maybe at what interval it should track time, among other things.

\$\endgroup\$
2
  • \$\begingroup\$ in a text based console game, performance of the DateTime class should not make any difference... For other games it might, but I've never had issues with it being too slow. As for it's accuracy, I do not know.. \$\endgroup\$
    – Nate
    Commented Feb 9, 2011 at 6:46
  • \$\begingroup\$ It's still slow. It's just a bad practice in my opinion. But yes, it probably won't be too hurtful for a console based game. \$\endgroup\$ Commented Feb 9, 2011 at 21:33
4
\$\begingroup\$

That is the standard way of getting the time from C#. And using a BackgroundWorker I think is better than multi threading it in this particular scenario.

Though I think the above comments are a bit confused as with most games, there is no waiting around for inputs its always updating.

It will be hard to perform time based actions when you aren't using a game loop of some type. You might want to reconsider your structure. You could always have the game loop keep running, even if there is no text submitted, and when there finally is you can react upon that text.

I would either do straight text-based game, or switch over to using a game loop, if you want those added features.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ In order to read from the Console window and also have the game loop continue running throughout I'm guessing the ReadLine() stuff will need to be done in another thread? As far as I can tell it's not possible to retreive user input without the loop halting until the user enters the text. ?? \$\endgroup\$ Commented Feb 8, 2011 at 23:47
  • \$\begingroup\$ If it's a console game you should use ReadLine() stuff. Have the text entered put into a Queue (make this queue thread safe). Then you can implement a normal game loop in a separate thread. \$\endgroup\$ Commented Feb 9, 2011 at 3:34
0
\$\begingroup\$

If it's text-based, why not just store the starting time in a DateTime? Then when you need the time, just subtract that value from DateTime.Now, pull the TotalSeconds from the resulting TimeSpan, then add that many minutes to the starting DateTime?

eg:

private DateTime StartTime;
const DateTime StartOfGame; // = 1/1/0001 AD

void Init()
{
  StartTime = DateTime.Now;
}

void Logic()
{
  // ...
  DateTime gameTime = StartOfGame.AddMinutes((DateTime.Now - StartTime).TotalSeconds);
  // ...
}
\$\endgroup\$
4
  • \$\begingroup\$ DateTime.Now is very bad performance wise (at least I've heard). I remember reading some where it can take a while to finish, something like 20 milliseconds? Anyway, using a stopwatch is far better performance wise in my opinion. Look at this: stackoverflow.com/questions/28637/… \$\endgroup\$ Commented Feb 9, 2011 at 3:40
  • \$\begingroup\$ I'm not really trying to get the time, more pass the time in such a way that players can age, plants can grow/die/breed and other time based events can occur. \$\endgroup\$ Commented Feb 9, 2011 at 3:41
  • 1
    \$\begingroup\$ Ah. If you're looking to trigger events at intervals, perhaps System.Timers.Timer is more what you're after? \$\endgroup\$
    – Tullo_x86
    Commented Feb 9, 2011 at 6:22
  • \$\begingroup\$ stopwatch is the way to go 100% of the time, why do things 1/2 arsed just because you think its fine. Things should be done the correct way! \$\endgroup\$ Commented Apr 13, 2017 at 0:48
0
\$\begingroup\$

With regards to your comment to Tullo

I'm not really trying to get the time, more pass the time in such a way that players can age, plants can grow/die/breed and other time based events can occur

Why not just use a timer? Once the timer runs out, a callback function could be triggered and you would then update player age, plant status, etc in that callback function automatically.

Once you are done with that, then make sure to restart the timer again for the next aging cycle.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .