target audience

Written by

in

Advanced LITIengine Tutorial: From Setup to Final Build LITIengine is a pure 2D Java game engine that eliminates the bloat of traditional frameworks by avoiding native libraries. It relies entirely on standard Java 2D APIs. This advanced guide steps through establishing a robust project architecture, engineering a custom entity system, building a dynamic lighting system, and compiling a production-ready build. 1. Professional Project Architecture

A scalable LITIengine project requires an explicit separation of assets, configurations, and core gameplay states. Modern Build Configuration (pom.xml)

Initialize your project using standard Maven layout. Ensure you target Java 17 or higher to leverage modern language features like records and enhanced switches.

4.0.0 com.game advanced-liti-game 1.0.0 17 17 0.5.1 UTF-8 de.gurkenlabs litiengine ${litiengine.version} org.apache.maven.plugins maven-compiler-plugin 3.11.0 Use code with caution. Directory Structure

Organize your project to keep game logic completely separate from static assets:

advanced-liti-game/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/game/ │ │ │ ├── core/ # Game initialization and screens │ │ │ ├── entities/ # Custom entities and behaviors │ │ │ └── systems/ # Custom managers and listeners │ │ └── resources/ │ │ ├── sprites/ # .png sheets and .info files │ │ ├── maps/ # .tmx maps and .tsx tilesets │ │ └── audio/ # .ogg sound effects and music └── pom.xml Use code with caution. 2. Advanced Entity Engineering

LITIengine uses annotations to bind entities directly to map data created via the Tiled editor. For advanced gameplay mechanics, extend the base Creature class to implement combat and custom state logic. Implementing a Custom Boss Entity

The following class builds a custom boss entity complete with auto-registering metadata, combat statistics, and custom rendering offsets.

package com.game.entities; import de.gurkenlabs.litiengine.Direction; import de.gurkenlabs.litiengine.annotation.AnimationInfo; import de.gurkenlabs.litiengine.annotation.CombatInfo; import de.gurkenlabs.litiengine.annotation.EntityInfo; import de.gurkenlabs.litiengine.annotation.MovementInfo; import de.gurkenlabs.litiengine.entities.Creature; import de.gurkenlabs.litiengine.entities.EntityControllers; import de.gurkenlabs.litiengine.graphics.animation.IEntityAnimationController; @EntityInfo(width = 64, height = 64) @MovementInfo(velocity = 90) @CombatInfo(hitpoints = 500, team = 2) @AnimationInfo(spritePrefix = “boss-reaper”) public class BossReaper extends Creature { private boolean isEnraged; public BossReaper() { this.isEnraged = false; // Optimize collision box relative to the 64x64 sprite bounds this.setCollisionBoxWidth(32); this.setCollisionBoxHeight(48); this.setCollisionBoxAlign(Direction.CENTER); // Intercept damage events for phase transitions this.onHit(event -> { if (this.getHitPoints().get() < 250 && !isEnraged) { triggerEnragePhase(); } }); } private void triggerEnragePhase() { this.isEnraged = true; this.getVelocity().setBaseValue(150); // Dynamically alter animation behavior via custom controllers IEntityAnimationController<?> controller = this.animations(); if (controller != null) { controller.add(this.getAnimationPrefix() + “-enraged”); } } public boolean isEnraged() { return this.isEnraged; } } Use code with caution. 3. Atmospheric Systems & Event Orchestration

LITIengine includes an ambient light system that can be manipulated in real time to build dark dungeons or dynamic weather systems.

package com.game.systems; import de.gurkenlabs.litiengine.Game; import de.gurkenlabs.litiengine.graphics.AmbientLight; import de.gurkenlabs.litiengine.graphics.LightSource; import de.gurkenlabs.litiengine.environment.Environment; import java.awt.Color; public class EnvironmentController { private final AmbientLight ambientLight; public EnvironmentController() { this.ambientLight = Game.world().environment().getAmbientLight(); } /Changes the map to a deep night profile and attaches a local * light source directly to an active entity. / public void transitionToNight(de.gurkenlabs.litiengine.entities.IEntity targetEntity) { // Set deep blue/black ambient overlay Game.world().environment().setAmbientColor(new Color(10, 15, 30, 235)); // Spawn a point light directly centered over our target entity LightSource lantern = new LightSource(120, new Color(255, 180, 50, 180), LightSource.Type.BREATHING, true); lantern.setX(targetEntity.getX()); lantern.setY(targetEntity.getY()); Game.world().environment().add(lantern); lantern.attachTo(targetEntity); } } Use code with caution. 4. Initializing the Game Loop and Screens

Tie your components together inside a custom Screen manager. This code bootstraps the engine, registers custom entity factories for Tiled integration, and boots directly into gameplay.

package com.game.core; import com.game.entities.BossReaper; import com.game.systems.EnvironmentController; import de.gurkenlabs.litiengine.Game; import de.gurkenlabs.litiengine.environment.Environment; import de.gurkenlabs.litiengine.gui.screens.GameScreen; import de.gurkenlabs.litiengine.resources.Resources; public class GameMaster { public static final String GAME_SCREEN_NAME = “PLAY”; public static void main(String[] args) { // Initialize engine metadata Game.info().setName(“Advanced Odyssey”); Game.info().setSubTitle(“Built with LITIengine”); Game.info().setVersion(“v1.0.0”); Game.init(args); // Map custom entity class to Tiled Map Editor custom types Game.environment().registerCustomEntityType(BossReaper.class); // Load packed asset files Resources.load(“maps/dungeon-master.litidata”); // Set up the window parameters Game.window().getRenderComponent().setBackground(java.awt.Color.BLACK); Game.window().setTitle(Game.info().getName()); // Register game view screens GameScreen gameplayScreen = new GameScreen(); Game.screens().add(gameplayScreen); // Trigger environment setup on map load Game.world().onLoaded(environment -> { BossReaper boss = environment.getCreature(BossReaper.class, “boss-spawn-point”); if (boss != null) { EnvironmentController envController = new EnvironmentController(); envController.transitionToNight(boss); } }); Game.start(); // Load target environment and show screen Game.world().loadEnvironment(“dungeon-level-1”); Game.screens().display(gameplayScreen); } } Use code with caution. 5. Production Compilation and Final Build Packaging

Distributing a pure Java 2D engine means producing a standalone runtime environment or a shaded JAR executable. Use the maven-shade-plugin to assemble all assets and external classes into a single file. Production Build Plugin configuration

Append the following configuration code directly into the section of your project’s pom.xml:

org.apache.maven.plugins maven-shade-plugin 3.5.0 package shade com.game.core.GameMaster : META-INF/.SF META-INF/.DSA META-INF/.RSA Use code with caution. Compiling and Testing the Binary

Open a terminal at the root project directory and compile your code using standard Maven lifecycles:

# Clean historical builds and build the absolute executable shaded JAR mvn clean package # Test your generated executable jar locally java -jar target/advanced-liti-game-1.0.0.jar Use code with caution.

For cross-platform systems that do not have a pre-installed Java Virtual Machine, use jlink or tools like jpackage (included in JDK 16+) to bind the compiled JAR directly with a stripped-down platform-specific JRE. This lets you distribute the application as a seamless .exe, .app, or .deb file. If you want to continue refining this build, let me know:

Do you need help formatting Tiled property strings to match LITIengine annotations? Tell me which mechanic or system you want to develop next.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *