Determinism

I have some extensive AI running in my game, and basically it runs differently every time.

I only create 1 Random object, and set the seed to 0.
I use no physics whatsoever.
strictfp keyword is on every class
I am using setting.setFrameRate(60);

Was wondering if anyone knew of anything, JME or just Java related that I do not know about to help make my game deterministic?

Edit: it runs with no input from me, other than controlling the camera, which has no impact on anything other than my view. Also no hash sets/maps or w/e are used.

Deterministic = don’t use tpf. Use a fixed tpf of your own calculation.

Otherwise, tpf will still vary and you still may get different results.

I’m not using tfp in simpleUpdate(float tfp)

So is there a problem or are you just asking the question just in case?

No problems that I can see causing it to run differently each time, I’m just asking more experienced programmers than I (2 years internet taught) if beyond what I mentioned could there be anything else cuasing the non-deterministic behaviour that comes to mind?

Beyond the floats, the 1 Random with a seed of 0 each time and updating at 60fps with no delta value I cannot think of anything else that could cause this.

So it is or isn’t running differently each time?

If you control all of the inputs and make them deterministic then the output will also be deterministic… at least mathematically. But if you are seeing something non-deterministic then we’d need to know what you mean by that to help trouble shoot the issue.

My game is NOT deterministic.

Sorry if I’ve been vague, here is some context.

The game is a sport simulation, at the moment 2 teams play in a square arena, there are 2 players, 1 on each team, and a ball. I designed the game with determinism in mind because I want to be able to re-run games with the same initial players and get the exact same result - so the game could be replayed and everything would happen the same. Despite all the measures I took which I listed in my first post, the games do not pan out the same.

I put this timer in my simpleUpate method so that the simulation (which I have no input into beyond flyimg the camera around to view it) would run for 60 seconds (game is running at fixed rate with the settings.setFrameRate(60))


updateTimer++;
if(updateTimer > 3600)
{
    System.out.println("end of game");
    System.out.println("ball: "+ball.getPos().toString());
    System.out.println("player1: "+playerTeam.players[0].getPos().toString());
    System.out.println("player2: "+enemyTeam.players[0].getPos().toString());
    System.exit(0);
}

And the results I get are different everytime, significantly. Both teams can win : / I have no idea how this can be happening, since there is only 1 random object for which i setSeed(0); and nothing changes between the times I run it. I have no idea what I could be doing wrong.

Having thought about it, could using code like

P.distanceSquared(q) (p and q being some Vector3f objects) give me different results?

I also use Math.pow, FastMath.DEG_TO_RAD*x and a FastMath.sqrt

I’m wondering if I might need to use strictfp keyword on the classes like Vector3f?

You must be introducing a variable somewhere because otherwise math is deterministic. strictfp does not matter, nor does Math.pow() or whatever. If you plug the same source data into them then they will always give you the same result.

So, somewhere you are relying on frame time when you shouldn’t be or you have multiple threads or something. We can’t say… but without some variable input then you should get the same result every time. Find where the results start to vary and trace back, I guess.

1 Like

Thanks, good to know. I guess ill start cutting code out

i think you should think about it in another manner

you can create any type game you like, with or without physics, but you should never use “start and go through all actions the same as before”, you will go to trouble in many things

  1. precision errors combined with timing (if you dont use tpf, it is worse more)
  2. slight difference at start can create huge difference at the end
  3. what if you want your replay to go backwards, or jump into the middle replay’s time ?
  4. you will build game arount one principle, and things will go messy more and more

i would recommend you to grab key-states, lets say every 1 second, of the game, this allows you to do almost anything
then you know state of whole level every 1 second and you can rebuild whole game exactly as you want it to be

in “normal gameplay” physics is moving obects
in “replay gameplay” you are setting objects’ positions and rotations based on previously generated key-states, even if one state is somehow “damaged”, next state could “repair” scene

yes it can be jerky or somewhat unprecise but i think it can be improved (maybe using physics and correcting it every second) and you will have bulletproof replay what shows everytime exactly same thing and you dont need to optimise code in any way, you dont even need to take any replay code into consideration while coding game.

and this or similar replay system you can integrate into any jme3 game i think

hope it helps :slight_smile:

1 Like

Oh I’m an idiot, found it. Yes I had the balls position linked to the position of an animation when it was thrown.

When I set my game to say, settings.setFrameRate(10);, the animations still run at the same speed independent of fps (I know this is normally ideal and I’m developing oddly but…), is there a way I can change this so animations run according to FPS?

maybe setSpeed(1f); ? From now on, play this animation slower (<1f) or faster (>1f), or with default speed (1f).

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:animation

but its up to you to develop odd code that produce speed factor, maybe some factor of tpf

There is an update(float tpf, TempVars vars) in AnimChannel, ideally id like to just change that tfp to 1 so its the same every time, but I cant edit that. Is there a way I can do it without er, recompiling source or w/e?

Think I have managed it by creating a custom Timer that just returns the value I want instead of calculating tpf. Seems to be working atm, thanks for everyones input.

ok you have managed this small victory.

but i, as potential player, wants to show last 1 minute of my remarkable gameplay to my friend, but i want to skip first 5 boring minutes… will it be possible? and what about when i have long gameplay and wants to do some jumping in time? and reverse play? or instant replay camera for some stunts? maybe you simply abandon features because your small victory and players will prefer fraps and youtube over your replay, making it useless.

sorry for my offensivity

No I appreciate your input, but the nature of the game is such that only rewinding and fast forwarding are desired/possible, and they are now in the game (even with this system). States without doubt are a better option in the majority of circumstances, especially if there is any networking involved, but I really think this outcome is better in this case.