AI Demo (Mifth)

@normen said: My question would be if you can make your application so that it doesn't remove things twice?

Sometimes it’s easier to remove all stuff like:
[java]
phiscsSpace.removeAll(rootNode);
[/java]
And then remove some controls which possibly can have some physics which will try to remove.

Yes i can redesign my app. But I have no issues with RigidBody which has no Exception.

@mifth said: Sometimes it's easier to remove all stuff like: [java] phiscsSpace.removeAll(rootNode); [/java] And then remove some controls which possibly can have some physics which will try to remove.

Yes i can redesign my app. But I have no issues with RigidBody which has no Exception.

What the original bullet library does when you try this is even worse.

@mifth I see the game is mainly done (except for AI). You didn’t use MonkeyBrains, so I will have to refactor the game. I hope, you are ok with it?

I will probably change API and add some features for MonkeyBrains, because I didn’t include integration with physics module.

@Tihomir said: @mifth I see the game is mainly done (except for AI). You didn't use MonkeyBrains, so I will have to refactor the game. I hope, you are ok with it?

I will probably change API and add some features for MonkeyBrains, because I didn’t include integration with physics module.

Sure! Refactor it as you need.

I think we need to rewrite AIUpdateManager.java a bit. As it’s not correct.

@pspeed Sorry for bothering. I was trying to implement fixed framerate = 60fps. Could you say if i did it right?
Here is my Fixed framerate class https://github.com/QuietOne/MonkeyBrainsDemoGames/blob/master/MonkeyBrainsDemo_Mifth/src/org/aitest/AIUpdateManager.java

This is important for AI testing.

@mifth said: @pspeed Sorry for bothering. I was trying to implement fixed framerate = 60fps. Could you say if i did it right? Here is my Fixed framerate class https://github.com/QuietOne/MonkeyBrainsDemoGames/blob/master/MonkeyBrainsDemo_Mifth/src/org/aitest/AIUpdateManager.java

This is important for AI testing.

On quick read, it looks ok but I think it can be simplified quite a bit… and to some advantage.

[java]
long nextUpdateTime = 0;
long frameLength = 1000000000L / 60;

public void update( float tpf ) {
long time = System.nanoTime();
if( time >= nextUpdateTime ) {
// We can do an update

    // Setup for the next frame
    nextUpdateTime = time + frameLength;
}

}
[/java]

However, like your version, this one will drift over time as any (time - nextUpdateTime) ends up being accumulated.

Instead, you can reset nextUpdateTime as:
[java]
if( nextUpdateTime == 0 ) {
nextUpdatetime = time + frameLength;
} else {
nextUpdateTime += frameLength;
}
[/java]

In this case, there will never be any error accumulated. At has the side-effect that if a frame ever takes longer than frameLength then you will get hopelessly behind. You could change it to loop through extra frames.

[java]
public void update(float tpf) {
long time = System.nanoTime();

if( nextUpdateTime == 0 ) {
    nextUpdatetime = time + frameLength;
    // do an update
} else {
    while( time >= nextUpdateTime ) {
        // do an update
        nextUpdateTime += frameLength;
    }
}

[/java]

That way won’t drift and won’t ever get behind. If your AI updates are taking longer than 1/60 of a second then end up dropping rendering frames… but at the point your AI has a lot of problems.

This also covers the case where your rendering isn’t keeping up with 60 FPS… since extra AI updates will be inserted to catch up.

Personally, I would never tie AI to the render loop anyway… but that’s a more complicated discussion.

1 Like
@pspeed said: On quick read, it looks ok but I think it can be simplified quite a bit... and to some advantage.

This also covers the case where your rendering isn’t keeping up with 60 FPS… since extra AI updates will be inserted to catch up.

Personally, I would never tie AI to the render loop anyway… but that’s a more complicated discussion.

Thanks!
Then you suggest to remove constant framerate for AI? As it can be Catched up?

@mifth said: Thanks! Then you suggest to remove constant framerate for AI? As it can be Catched up?

I do things like AI in the game loop… which is on a different thread for me.

1 Like

@mifth

I must ask, because when I looked at the some demos for jMonkey, I didn’t see much usage of AppStates. Emphasis was on update loop.

Is this common practise to everything goes to AppStates and nothing in update loop? If it does, MonkeyBrains is then not the happiest solution for AI.

@Tihomir said: @mifth

I must ask, because when I looked at the some demos for jMonkey, I didn’t see much usage of AppStates. Emphasis was on update loop.

Is this common practise to everything goes to AppStates and nothing in update loop? If it does, MonkeyBrains is then not the happiest solution for AI.

An AppState is basically just a callback for the update loop… The principle is the same, just that AppStates are by design modular.

Yep, AppStates are heavily used. I use them to load levels, add gui, restart a game, get physics etc…
And if you have StateManager - you can easily get the Appstate(physics, gui, etc.) you need.
Like this:

[java]stateManager.getState(YourClass.class);[/java]

I suggest to use Appstates for managers, levels, gui, physics, AI.

For more info: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:application_states

Ok, I have some idea, how to correct this easily, but I need to know if my reasoning is ok.

Because I didn’t know AppStates and their usage, I made Game singleton that is supposed to give tpf to all Agents that are added, and the Agents have one Behaviour that can be composite and give that behvaiour tpf and so one… So to debug one Agent, you only need to see which behaviour is not working correctly and to fixed it.

You only need to put Game.getInstance().update(tpf) in update loop to update all agents and game objects if there are any (items…).

I can just add Game to extend AbstractAppState and to “fix this thing”.

But in @mifth game you put every NPC as separate AppState. Does this affect the performance if I leave the update to the Game class?

@Tihomir said: Ok, I have some idea, how to correct this easily, but I need to know if my reasoning is ok.

Because I didn’t know AppStates and their usage, I made Game singleton that is supposed to give tpf to all Agents that are added, and the Agents have one Behaviour that can be composite and give that behvaiour tpf and so one… So to debug one Agent, you only need to see which behaviour is not working correctly and to fixed it.

You only need to put Game.getInstance().update(tpf) in update loop to update all agents and game objects if there are any (items…).

I can just add Game to extend AbstractAppState and to “fix this thing”.

But in @mifth game you put every NPC as separate AppState. Does this affect the performance if I leave the update to the Game class?

No. AIMainCharacterController class is only for the Main Character logic. The main character uses Appstate because it was easier to control camera, inputs and other things for me.

There are 2 ways you can go:

  1. Create one Appstate which will loop all NPCs to update logic. In this way you will get only one AppstateClass.

  2. Extetend AICharacterControl class and override update() method.
    Like this:
    [java]
    public class AIMainCharacterControl extends AICharacterControl{

    @Override
    public void update(float tpf) {

    // DO YOUR CODE

    super.update(float tpf);
    }
    }
    [/java]

And remember - there should be only one AppState class type. For example, there should be no 2 AIMainCharacterController classes in the StateManager list.

@Tihomir if you want i can add a simple NPC control.
So that you could continue adding AI.

You don’t need to. I have refactored a lot, so the MonkeyBrains be usable… and I’ve got a lot more things to do…

@Tihomir said: You don't need to. I have refactored a lot, so the MonkeyBrains be usable... and I've got a lot more things to do...

Ok, cool. Just remember that Appstates are global things. There should be only one appstate of a certain class.
Goodluck and ask any questions if you need.

@mifth said: Ok, cool. Just remember that Appstates are global things. There should be only one appstate of a certain class. Goodluck and ask any questions if you need.

You can have multiple app states of the same class. It just depends on what you are using them for. The state manager API limits how you can manage them in that case, too. (something I will fix someday)

They are indeed global, though.

@pspeed said: You can have multiple app states of the same class. It just depends on what you are using them for. The state manager API limits how you can manage them in that case, too. (something I will fix someday)

They are indeed global, though.

If i have multiple appStates then how i can get them?
stateManager.getState(CustomState.class); - this will give me the first CustomState class in the list.

Or i can get the list of all states and loop them?

If you will make new fix for the stateManager could you show new API about how to use it?

Anyway thanks.

@mifth said: If i have multiple appStates then how i can get them? stateManager.getState(CustomState.class); - this will give me the first CustomState class in the list.

Or i can get the list of all states and loop them?

If you will make new fix for the stateManager could you show new API about how to use it?

Anyway thanks.

You have to keep it instead of grabbing it later.

@normen said: You have to keep it instead of grabbing it later.

You mean I should keep the states in my custom list?