Is it possible to disable fps, stats and flybycam as default?

As awesome and easy as jME is to use . . .I find the default ON state for fps, stats and flybycam a little irritating when I use SimpleApplication.

I thought I’d share this little gem, until I can hear from someone on how to disable these items by default.

import com.jme3.app.FlyCamAppState;

void CleanStart() {
setDisplayFps(false);
setDisplayStatView(false);
stateManager.detach(stateManager.getState(FlyCamAppState.class));
}

[java]
public class MyApp extends SimpleApplication {
public MyApp() {
super(null);
}
}
[/java]

Then you will have none of the default app states. No debug keys, no fly cam, no stats display.

Note: you can also pass your own app states on this constructor instead (ie: super( new MyAppState1(), new MyOtherAppState(), …) and it will use yours instead of the defaults… or you can include some of the defaults if you still want them.

super(null) gives me a clean foundation to build on. Just what I need. Thank you pspeed.

Another approach: Use Application instead of SimpleApplication.

SimpleApplication does these things:

  • initialize StatsAppState and the FlyCamAppState
  • route keyboard and mouse input to these AppStates
  • route the ESC key to shut down the app, no questions asked
  • set up root Nodes for scene and GUI
    You’ll want to decide what parts of that list you actually want.

Here’s a rundown why one might want each even if rolling one’s own Application subclass:

  • Stats shows the counts and FPS. It’s important to gauge how much performace that latest change ate, so it’s an important development tool.
  • ESC key routing is marginal; you can always shut the application down from the IDE until you have proper exit dialogs installed.
  • FlyCam is essential as long as you haven’t installed your own in-game camera; you won’t see anything without it (as far as I understand the code, I never actually tried to run my app without a flycam). Once in-game cameras are available, the flycam is less important (but could still be useful if the in-game cameras are less mobile).
  • Root nodes are marginal, you can easily set up your own root nodes. The root nodes in SimpleApplication are configured sensibly for their respective use cases, and they provide handy standard member variables to work with. A convenience feature but very convenient.

That’s really bad advice toolforger - SimpleApplication does a lot of stuff for you (like updating geometric state etc etc). It’s very very very very rare anyone should be inheriting from application directly.

Thanks for the advice toolforger. I do however extend Application when I “place” jMe into a Swing canvas, and do my own “low-level” node and state management. So I am familiar with both Application and SimpleApplication. But as zarch explained, SimpleApplication does a lot of things for you, most importantly providing the rootNode for you, which makes it very easy to throw together a “quick and dirty” demo or test sim. The only thing about SimpleApplication that “grated” me was having to “unload” the default stuff, as I explained in my first post. The super(null) approach is one which solved my problem, and also led me to examine appStates in much more detail - specifically when used in the constructor - an approach that pspeed opened my eyes to.
As far as cameras go, I’m happiest when I slerp my own.
Replies are always appreciated - sometimes a simple statement can open my mind to new horizons.

@toolforger said: Another approach: Use Application instead of SimpleApplication.

Horrible, horrible, horrible advice. I’m a half-breath away from renaming Application to AbstractApplication with only SimpleApplication and HeadlessApplication subclasses. This is so often a HUGE problem that I’m tired of supporting folks who incorrectly subclass Application and I’d really like to temporarily break all naive code that does this… including the JME tests. (Folks like the OP who want an odd/custom swing setup can still subclass for that use-case.)

@toolforger said: SimpleApplication does these things: - initialize StatsAppState and the FlyCamAppState

So don’t include them.

@toolforger said: - route keyboard and mouse input to these AppStates

So don’t include the app states. Seriously, it’s a one line thing.

@toolforger said: - route the ESC key to shut down the app, no questions asked

You can remove this with one line, also.

@toolforger said: - set up root Nodes for scene and GUI

Yes, because users almost always get “doing it themselves” wrong in this case… and it is extremely unlikely that these would need to be different than setup by SimpleApplication.

@toolforger said: You'll want to decide what parts of that list you actually want.

Here’s a rundown why one might want each even if rolling one’s own Application subclass:

  • Stats shows the counts and FPS. It’s important to gauge how much performace that latest change ate, so it’s an important development tool.
  • ESC key routing is marginal; you can always shut the application down from the IDE until you have proper exit dialogs installed.
  • FlyCam is essential as long as you haven’t installed your own in-game camera; you won’t see anything without it (as far as I understand the code, I never actually tried to run my app without a flycam). Once in-game cameras are available, the flycam is less important (but could still be useful if the in-game cameras are less mobile).
  • Root nodes are marginal, you can easily set up your own root nodes. The root nodes in SimpleApplication are configured sensibly for their respective use cases, and they provide handy standard member variables to work with. A convenience feature but very convenient.

…and they properly have updateLogicalState(), etc. called on them at the appropriate times. Appropriate times with respect to AppStateManager, by the way. I’ve seen a few users get this one wrong and get weird “Your scene has been modified improperly” errors.

In Application you also have to manage AppStateManager yourself.

@pspeed
Refactor Application as SimpleFramework and SimpleApplication as Application. XD

Confusion, riot and country-wide strikes ensue.

Right, I missed the stuff in update().
It keeps tpf updated, updates scene state, calls the render functions.

Nothing of that was hard to transplant when I built my SimpleApplication replacement, that’s why I overlooked it.

@madjack said: @pspeed Refactor Application as SimpleFramework and SimpleApplication as Application. XD

Confusion, riot and country-wide strikes ensue.

Actually, latest thinking is to rename Application to AbstractContextManager… it fits better anyway.

Once I come up with some proper ContextStateListeners (to hook the things like reshape, focus lost, etc. that can currently only be done by subclassing Application) then I may start the refactoring and leave the current Application and SimpleApplication as empty subclassing husks of their former selves. :slight_smile:

reshape() is the one I need right now… so the listener thing may happen sooner rather than later. I will iterate it a few times in Mythruna first.

@pspeed: I agree the AppStates can be easily disabled, but those member variables in SimpleApplication that do nothing but control the AppStates just disabled are still annoying.
There are also some worrying aspects, particularly for first-time readers:

  • Some comments indicate that these member variables might be used elsewhere, but it remains unclear whether that’s JME code (relevant for newbie) or non-JME application code (irrelevant for newbie). You and me know that that’s just application code, first-time readers don’t.
  • There’s concern whether the input mappings can conflict. Closer reading reveals that these mappings aren’t in use and hence can’t conflict, first-time readers haven’t read that yet.

So it’s technically not a problem, but still disconcerting for first-time users of the code.
Maybe the comments in SimpleApplication should be edited to calm these specific worries.

Not just disabled but REMOVED… as in the app states are never added, never initialized, never run. The only side effect is some annoying null fields laying around… which I would remove if I could but it would break too many people. I really really wanted to.

I know nobody asked my advice or that it would mean anything, but I’m still gonna say it. :stuck_out_tongue:

Why not put this in the user’s hands? Just remove the states by default. If we want it, we can enable them either separately or all of them at the same time.

Something like: app.setStatsOn(true); (individual state) or app.enabletAllDebugStates(true); to enable all those relevant states at the same time.

As for breaking things… Well, usually you don’t update the engine in a released game for that reason. Anyone using new committed code from this point forward has to be updating frequently and I don’t see how adding 1-4 lines could be problematic.

Here’s the approach I chose to remove these AppStates:

  1. Wrap the FlyCam in a FlyCamAppState. Already available. (It’s really been a while since I looked into the code…) Needs some adaptations though, and SimpleApplication doesn’t use it.
  2. Move all relevant state from SimpleApplication to FlyCamAppState resp. DebugKeysAppState. The AppStates need some state injected but it wasn’t much in the end.
  3. Make a ClientApplication class that holds what’s currently in SimpleAppState, except the stuff moved to the two factored-out AppStates.
  4. Create a convenience class StdClientApplication that has the two AppStates.
  5. Deprecate SimpleApplication. Can’t change it because people are accessing member variables that are gone in StdClientApplication.

Here’s the FlyCamAppState I’m using, maybe it’s useful as a starting point for you:
[java]/**

  • Manages a FlyByCamera.
  • @author Paul Speed, Toolforger (Joachim Durchholz)
  •     Adapted from com.jme3.app.FlyCamAppState.
    

*/
public class FlyCamAppState extends AbstractAppState {

// private Application app;
private FlyByCamera flyCam;

// public FlyCamAppState() {
// }

// /**
// * This is called by SimpleApplication during initialize().
// */
// void setCamera( FlyByCamera cam ) {
// this.flyCam = cam;
// }

public FlyByCamera getCamera() {
return flyCam;
}

@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
// this.app = app;
if (app.getInputManager() != null) {
if (flyCam == null) {
flyCam = new FlyByCamera(app.getCamera());
flyCam.setMoveSpeed(1f); // NEW
flyCam.setDragToRotate(true); // NEW
}
flyCam.registerWithInput(app.getInputManager());
}
}

@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
flyCam.setEnabled(enabled);
}

@Override
public void cleanup() {
super.cleanup();
flyCam.unregisterInput();
}

}[/java]

@madjack said: I know nobody asked my advice or that it would mean anything, but I'm still gonna say it. :P

Why not put this in the user’s hands? Just remove the states by default. If we want it, we can enable them either separately or all of them at the same time.

Something like: app.setStatsOn(true); (individual state) or app.enabletAllDebugStates(true); to enable all those relevant states at the same time.

As for breaking things… Well, usually you don’t update the engine in a released game for that reason. Anyone using new committed code from this point forward has to be updating frequently and I don’t see how adding 1-4 lines could be problematic.

a) I hate adding N methods to only added functionality that is already one-line composable.
b) A proper game should be calling super() with its own app states anyway.

I actually want to get to the point where you can call new StandardApplication( list of my states ) and not have to subclass an application class at all. In that case, if you call StandardApplication() without any arguments you get a standard set of app states. This helps the people who have no clue what they are doing… because the people who have a clue would already have been doing it differently and passing the things they want.

No matter how many setFunctionOn() type stuff you add, the users who couldn’t figure out what to do before still won’t figure out what to do because the documentation is impossible to find and written in an obscure ancient language. :wink:

@toolforger said: Here’s the FlyCamAppState I’m using, maybe it’s useful as a starting point for you:

Uh… what version of JME are you running? There has been a FlyCamAppState for like a year or something.

Edit: I see that you just copied the existing one but you may want to highlight the changes.

Highlighting didn’t work :frowning:
Using Java comments instead, hold on… Done.

Essentially, I just removed unneeded functionality (and the empty constructor) and pulled the minimal initialization that still happened inside SimpleApplication over here.
The setDragToRotate call is probably specific to my code. I have windowed mode and didn’t want to get drag-to-rotate toggled whenever the user toggles between windowed and fullscreen, I reckon that would be confusing to users.

@pspeed
I know. The problem is I’m too noob oriented and a bit of oversimplification I guess. If you’re here and your intention is to make a game, we shouldn’t have to explain every little thing. You can’t do both, learn programming and make a game at the same time. If anyone argues that point, they better review their priorities.