Plant growth

Hi,

Just added in when trees grow - basically you plant certain type of seed, after a period of time, it starts growing. Now at the moment, I’m just using a simple integer value for the grow time, I guess it be better if I could realistically in virtual game terms set a given time period, such as grow in a day or something, (can’t possibly do it grow in 1 years time, lol!). I was thinking of getting the start time when something is planted, set that in the tree class, then set an end time, something like:

Something like this: (When seed is planted)


long lEndTime = new Date().getTime() + 1000;

Then when lEndTime is reached, grow tree. I could also use a timer event (extend the TimerTask). What I want it to do is grow the trees at the same rate
on every computer it runs on.

Advice is much appreciated.

Thanks

I’d not use actual points in calendar/wallclock time (which could be tampered with when adjusting the local system clock), but instead use time intervals which you increment/decrement in delta steps with your game loop ticks.
So basically this means when the seed is planted you set some “timeToGrow” to ‘D’ where D is your interval in some time unit.
Then with every tick of your game loop you get the delta time interval elapsed since the last tick (via the monotonic clock System.nanoTime()) and decrement the timeToGrow by that amount (scaled to the appropriate time unit). Once timeToGrow is equal to or smaller than zero, you start to grow your plant.
This also survives savegames: When you want to store and restore the state of your game from some persistent storage without relying on the system’s clock (for example when you submit your savegame to another person), you would just store and restore that ‘timeToGrow’ along with your other necessary state.

Here is an example of how such a single-threaded (no Timer TimerTask or multi-threading or anything) event processing with an externally controlled clock using a “tick()” method could look like: http://pastebin.java-gaming.org/be0cd6b41411d

How to use:


// Create Events object with callback
Events<String> events = new Events<String>(new EventCallback<String>() {
    public void onSnapshot(String userData, long timeToEvent) {
    }
    public void fireEvent(String userData, long delta) {
        System.err.println("Event fired: " + userData);
    }
});

// Game loop
long lastTime = System.nanoTime();
while (true) {
    long thisTime = System.nanoTime();
    long deltaInMs = (thisTime - lastTime) / 1000000L;
    lastTime = thisTime;
    if (seedWasPlanted) {
        // Add some event fired in 2 seconds (any time unit can be used)
        events.addEvent("Plant growing!!!", 2000);
    }
    // Do your game logic and rendering and such...
    // process events:
    events.tick(deltaInMs);
}

That is a bad idea. Don’t ever use incremented/decremented timestamp if it will need to be saved/loaded later. The idea that the author had is much better than the one you suggested. My only suggestion would be to have ‘gameTime’ variable, which is basically like the current time of the device, but you can choose when to advance it.


class Game
{
	public static float Time;

	public void update(float deltaTime) {
		if (!notPaused) {
			// this way its possible to control how the time flows
			// throughout the game. For example, if the game is currently
			// paused or something, you can choose not to advance the game.
			Time += deltaTime;
		}

		// .. update plant logic and stuff later
	}
}

class Plant
{
	private float endTime;
	public void update() {
		if (Game.Time >= endTime) {
			// plant is grown!
		}
	}

	public void startGrowing() {
		int growthTime = 100; // 100 seconds
		endTime = Game.time + growthTime;
	}
}

I fail to see how your approach is in any way different than mine. :slight_smile:
What hinders you to conditionally call Events.tick() as well? The only thing you add is a simple “if(gameIsPaused) then don’t tick()”

I never used Events class before, could you give an example that has for example 2-3 events implemented for different game objects? Would you use a single instance of Events, or would each object need to have a separate Events instance?

My complaint with your method is that using a decremented/incremented timestamp has a big drawback, which is that it must be advance each game tick. This might not be a problem for a small game, but if your game grows, you might start getting performance problems on certain platforms (mobile for example) if you update thousands of game objects each game tick, when you could only update the ones that are visible on screen. There is another drawback, which is that when you serialise the game object, it will be different each time, because it changes with each game tick.

[quote]but if your game grows, you might start getting performance problems on certain platforms (mobile for example) if you update thousands of game objects each game tick
[/quote]
Yes, you made a good point there and I tried to take care of that. The idea is, if you have events that should fire in certain time intervals, then you would register all events (can be millions of events) in a single Events class.
At each tick() the Events class then only checks whether the next event (closest to ‘now’) is reached. It does not check whether all events should be fired, but only the “next one.” (realized via a PriorityQueue at insertion)

[quote]There is another drawback, which is that when you serialise the game object, it will be different each time, because it changes with each game tick.
[/quote]
This is actually a good thing. Because when you serialize a game state with an event that says “I want to run in two seconds” and then two days later you deserialize/load that savegame afterwards, that event is being run in two seconds from then.
You cannot implement this with a calendartime-based system.
So, when doing a snapshot, you record at which time interval (relative to the point in time at which the snapshot was taken) the event should run.