Skip to main content Home Creators johannesrabauer fxgl-skills fxgl-game-lifecycle
fxgl-game-lifecycle Bootstrap and structure an FXGL game application — set up GameApplication subclass, configure initSettings, initGameVars, initInput, initGame, initPhysics, initUI, and onUpdate. Use this skill when creating a new FXGL game, adding engine services, configuring window size/title, setting application mode, or wiring the game loop.
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/JohannesRabauer/fxgl-skills --skill fxgl-game-lifecycleThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository Add particle systems and visual effects to an FXGL game — configure ParticleEmitter with function-based setters (setVelocityFunction, setAccelerationFunction, setExpireFunction, setScaleFunction, setSpawnPointFunction); use built-in factory emitters (fire, explosion, smoke, rain); apply image-textured particles with multiplyColor / toColor; write custom per-particle physics via setControl; attach TrailParticleComponent for motion trails; apply SlowTimeEffect for bullet-time; apply WobbleEffect for screen-shake; stack multiple effects with EffectComponent; build fireworks displays. Use this skill when adding explosions, fire, smoke, rain, motion trails, impact bursts, bullet-time slow-motion, screen shake, or any particle-based visual polish.
Start a new FXGL project through a bounded Socratic discovery flow, then turn the answers into a docs-first starter specification with ADRs, an arc42-lite architecture summary, and Mermaid use-case diagrams before scaffolding the project itself. Continue using the same questioning approach for initialization choices, and require documentation updates plus automated tests for every implemented step.
Build a Breakout or Arkanoid style game in FXGL — control a paddle horizontally, keep a ball at constant speed, bounce it off walls, paddle, and bricks, load brick layouts from level data, angle the reflection based on paddle hit position, handle lives and bottom-drain loss, spawn falling power-ups, and finish the level when all breakable bricks are destroyed.
Related occupations SOC
Based on SOC occupation classification
name fxgl-game-lifecycle description Bootstrap and structure an FXGL game application — set up GameApplication subclass, configure initSettings, initGameVars, initInput, initGame, initPhysics, initUI, and onUpdate. Use this skill when creating a new FXGL game, adding engine services, configuring window size/title, setting application mode, or wiring the game loop.
triggers ["create FXGL game","GameApplication","initSettings","initGame","game loop","FXGL project setup","engine service","game bootstrap"] compatibility Java 17+, FXGL 21.x, Maven or Gradle. JavaFX runtime must be on the module path.
category fxgl/fundamentals tags ["fxgl","java","javafx","fundamentals","game","lifecycle"] metadata {"author":"fxgl-skills","version":"1.0","fxgl-version":"21.1"} allowed-tools ["Read","Write","Edit","Bash"]
FXGL Game Lifecycle
Overview
Every FXGL game extends GameApplication and launches via launch(args).
The engine calls lifecycle methods in strict order — honour that order or face NPEs.
Lifecycle Order (guaranteed by engine)
launch(args)
└─ initSettings(GameSettings) ← configure window, services, achievements
└─ initGameVars(Map) ← declare all typed world variables
└─ initInput() ← register keyboard/mouse actions
└─ initGame() ← spawn entities, load level, register factories
└─ initPhysics() ← set gravity, collision handlers
└─ initUI() ← build HUD nodes
└─ [game loop starts]
└─ onUpdate(double tpf) ← runs every frame
Rule: Never call getGameWorld(), getPhysicsWorld(), or getInput() inside
initSettings() — those services are not yet initialised.
Minimal Working Game
import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import static com.almasb.fxgl.dsl.FXGL.*;
public class MyGame extends GameApplication {
@Override
protected void initSettings (GameSettings settings) {
settings.setWidth(1280 );
settings.setHeight(720 );
settings.setTitle("My Game" );
settings.setVersion("0.1" );
}
@Override
protected void initGame () {
entityBuilder()
.at(400 , 300 )
.view(new javafx .scene.shape.Rectangle( , , javafx.scene.paint.Color.BLUE))
.buildAndAttach();
}
{
launch(args);
}
}
40
40
public
static
void
main
(String[] args)
initSettings — Key Options @Override
protected void initSettings (GameSettings settings) {
settings.setWidth(1280 );
settings.setHeight(720 );
settings.setTitle("My Game" );
settings.setVersion("1.0" );
settings.setMainMenuEnabled(true );
settings.setGameMenuEnabled(true );
settings.setEnabledMenuItems(EnumSet.of(MenuItem.NEW_GAME, MenuItem.SAVE, MenuItem.LOAD, MenuItem.EXIT));
settings.setApplicationMode(ApplicationMode.DEVELOPER);
settings.setDeveloperMenuEnabled(true );
settings.setProfilingEnabled(true );
settings.setFullScreenAllowed(true );
settings.setFullScreenFromStart(false );
settings.addEngineService(QuestService.class);
settings.addEngineService(SaveLoadService.class);
settings.getAchievements().add(new Achievement ("First Kill" , "Kill an enemy" , "kills" , 1 ));
}
initGameVars — World Variable Declaration All variables used elsewhere must be declared here. Missing a variable declaration
causes IllegalArgumentException on first access.
@Override
protected void initGameVars (Map<String, Object> vars) {
vars.put("score" , 0 );
vars.put("lives" , 3 );
vars.put("speed" , 200.0 );
vars.put("paused" , false );
vars.put("playerName" , "" );
}
initInput — Binding Actions @Override
protected void initInput () {
onKey(KeyCode.A, () -> getPlayer().translateX(-5 ));
onKey(KeyCode.D, () -> getPlayer().translateX(5 ));
onKeyDown(KeyCode.SPACE, () -> shoot());
onKeyUp(KeyCode.SHIFT, () -> stopSprint());
onBtnDownPrimary(() -> spawnProjectile());
}
initGame — Entity & World Setup @Override
protected void initGame () {
getGameWorld().addEntityFactory(new MyEntityFactory ());
setLevelFromMap("level1.tmx" );
spawn("player" , 100 , 100 );
spawn("enemy" , 500 , 300 );
entityBuilder().buildScreenBoundsAndAttach(40 );
Entity player = getGameWorld().getSingleton(e -> e.isType(EntityType.PLAYER));
getGameScene().getViewport().bindToEntity(player, getAppWidth() / 2.0 , getAppHeight() / 2.0 );
}
initPhysics — Gravity & Collision Handlers @Override
protected void initPhysics () {
getPhysicsWorld().setGravity(0 , 1200 );
onCollisionBegin(EntityType.PLAYER, EntityType.COIN, (player, coin) -> {
coin.removeFromWorld();
inc("score" , +10 );
});
onCollisionBegin(EntityType.PLAYER, EntityType.ENEMY, (player, enemy) -> {
inc("lives" , -1 );
if (geti("lives" ) <= 0 ) showGameOver();
});
}
initUI — HUD @Override
protected void initUI () {
Text scoreText = getUIFactoryService().newText("" , Color.WHITE, 24 );
scoreText.textProperty().bind(getip("score" ).asString("Score: %d" ));
addUINode(scoreText, 20 , 40 );
Text livesText = getUIFactoryService().newText("" , Color.RED, 24 );
livesText.textProperty().bind(getip("lives" ).asString("Lives: %d" ));
addUINode(livesText, 20 , 70 );
}
onUpdate — Game Loop @Override
protected void onUpdate (double tpf) {
spawnTimer += tpf;
if (spawnTimer > 3.0 ) {
spawn("enemy" , random(0 , getAppWidth()), -50 );
spawnTimer = 0 ;
}
}
private double spawnTimer = 0 ;
Custom Engine Services
public class ScoreService extends EngineService {
private int highScore = 0 ;
@Override
public void onGameReady () { }
public int getHighScore () { return highScore; }
public void updateHighScore (int score) { highScore = Math.max(highScore, score); }
}
settings.addEngineService(ScoreService.class);
FXGL.getService(ScoreService.class).updateHighScore(geti("score" ));
Gotchas
Asset directory : all assets must be under src/main/resources/assets/. FXGL
auto-prefixes this path. Writing getAssetLoader().loadTexture("textures/player.png")
resolves to assets/textures/player.png on the classpath.
launch(args) is final — do not override it. Override lifecycle hooks instead.
initSettings runs before JavaFX Application.start() — avoid any JavaFX node
creation here.
Kotlin DSL : use import com.almasb.fxgl.dsl.* and GameApplication() — same hooks,
same order. The FXGLForKt file provides Kotlin-specific extension functions.
Application mode : always ship with ApplicationMode.RELEASE. The developer menu
and profiler are disabled automatically.
Module path for JavaFX : add --module-path and --add-modules javafx.controls,javafx.fxml
to JVM args in your build file if running outside a module-aware launcher.
initGameVars is mandatory for reactive properties : getip("score") throws
IllegalArgumentException if "score" was not declared in initGameVars.
World reset : calling getGameController().startNewGame() re-runs all init* hooks.
Avoid storing state in instance fields unless you reset it in initGameVars.
Quick Reference DSL method Description getApp()Returns the GameApplication instance getAppWidth() / getAppHeight()Window dimensions in pixels getAppCenter()Point2D of the window centregetSettings()Read-only settings snapshot getGameController()Control game state (startNewGame, exit, pause) tpf()Time per frame of the last frame (seconds)