anchor.diff:  
   === The Smart Way to Access Game Features
   
  -<<jme3/intermediate/simpleapplication#,SimpleApplication>> gives you access to game features such as a the rootNode, assetManager, guiNode, inputManager, audioManager, physicsSpace, viewPort, and the camera. But what if you need this access also from another class? Don't extend SimpleApplication a second time, and don't pass around tons of object references in constructors! Needing access to application level objects is a sign that this class should be designed as an <<jme3/advanced/application_states#,AppState>> (read details there).
  +xref:ROOT:jme3/intermediate/simpleapplication.adoc[SimpleApplication] gives you access to game features such as a the rootNode, assetManager, guiNode, inputManager, audioManager, physicsSpace, viewPort, and the camera. But what if you need this access also from another class? Don't extend SimpleApplication a second time, and don't pass around tons of object references in constructors! Needing access to application level objects is a sign that this class should be designed as an xref:ROOT:jme3/advanced/application_states.adoc[AppState] (read details there).
   
   An AppState has access to all game features in the SimpleApplication via the `this.app` and `this.stateManager` objects. Examples:
   
  
positive.code: 
  == Debugging and Test Phase
  
  *A <<sdk/debugging_profiling_testing#,Java Debugger>>* is included in the jMonkeyEngine SDK. It allows you to set a break point in your code near the line of code where an exception happens. Then you step through the execution line by line and watch object and variable states live, to detect where the bug starts.
  
  *Use the <<jme3/advanced/logging#,Logger>>* to print status messages during the development and debugging phase, instead of System.out.println(). The logger can be switched off with one line of code, whereas commenting out all your `println()`s takes a while.
  
  *Unit Testing (link:https://docs.oracle.com/javase/1.5.0/docs/guide/language/assert.html[Java Assertions])* has a different status in 3D graphics development than in other types of software. You cannot write assertions that automatically test whether the rendered image _looks_ correct, or whether interactions are _intuitive_. Still you should <<sdk/debugging_profiling_testing#,create simple test cases>> for individual game features such as loaders, content generators, effects. Run the test cases now and then to see whether they still work as intended – or whether they are suffering from regressions or side-effects. Keep the test classes in the `test` directory of your project, don't include them in the distribution.
  
  *Quality Assurance (QA)* means repeatedly checking a certain set of features that must work, but that might be unexpectedly broken as a side-effect. Every game has some crazy bugs somewhere – but basic tasks _must work_, no excuse. This includes installing and de-installing; saving and loading; changing options; starting, pausing, quitting; basic actions such as walking, fighting, etc. After every milestone, you go through your QA list again and systematically look for regressions or newly introduced bugs. Check the application _on every supported operating system and hardware_ (!) because not all graphic cards support the same features. If you don't find the obvious bugs, your users will, and carelessness will put them off.
  
  
negative.code: ====
  
  
  Read all about xref:ROOT:jme3/advanced/custom_controls.adoc[Custom Controls] and xref:ROOT:jme3/advanced/application_states.adoc[Application States] here.
  
  
  === Optimize Application Performance
  
  *  xref:intermediate/optimization.adoc[Optimization] – How to avoid wasting cycles
  *  xref:ROOT:jme3/advanced/multithreading.adoc[Multithreading] – Use concurrency for long-running background tasks, but don't manipulate the scene graph from outside the main thread (update loop)!
  *  You can add a xref:sdk:debugging_profiling_testing.adoc[Java Profiler] to the jMonkeyEngine SDK via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often (try to cache values to avoid this). If object creation and garbage collection counts keep increasing, you are looking at a memory leak.
  
  
  === Don't Mess With Geometric State
  