Engine Overview
Welcome to the Lisa Engine documentation. This guide covers the architecture and inner workings of the engine that powers games like CoolFox and NeonSignal.
Overview
Lisa Engine is a 2D platformer engine built on the libGDX framework. It implements a custom Entity-Component System (ECS) and ships as a Gradle library — consuming games add their own platform launchers (desktop, Android, iOS, …), player implementation, and game-specific entity factory.
What Lisa Engine provides
An ECS runtime with a spatial grid for collision
A library of ~50 platformer components (movement, hazards, switches, enemies, particles, …)
Level loading from Tiled TMX maps
A unified input abstraction across keyboard, touch, and gamepad
A set of menu / cutscene / dialog / settings screens
A JSON-based script system for cutscenes and abilities
Resource managers for textures, sounds, fonts, animations, levels, paths, secrets
What the consuming game provides
Platform launchers (desktop/android/ios/…)
A subclass of
EngineConfigwith the game’s name, resources, and physics constantsA subclass of
EntityFactorywith game-specificcreateX()methods (typically including the player)The
PlayerComponent(or equivalent) and any other game-specific componentsTiled maps, textures, sounds, scripts, fonts
Engine Architecture
The Big Picture
Game's Application entry point (e.g. DesktopLauncher)
↓
Engine (Lisa Engine core orchestrator)
├─ Resource Managers (Textures, Sounds, Fonts, Levels, …)
├─ Input System (Keyboard, Touch, Gamepad)
├─ Screen Manager (Game, Menu, Pause, …)
└─ Entity-Component System
├─ GameScene (world container)
├─ EntityManager (lifecycle & spatial grid)
└─ Entities (composed of components)
Core Classes
Engine (core/src/net/dynart/lisa/core/Engine.java)
The orchestrator that owns the asset manager, input multiplexer, screen lifecycle, and resource managers
Initialized by the consuming game with an
EngineConfig
EngineConfig (core/src/net/dynart/lisa/core/EngineConfig.java)
Base configuration class. The consuming game subclasses it and supplies the game’s name, the
EntityFactory, theFadeRenderer, and JSON-driven settings (physics, input, display).
EntityFactory (core/src/net/dynart/lisa/core/EntityFactory.java)
Base factory with
createX()methods for the engine’s built-in entity typesConsuming games subclass it to add their own (player, custom enemies, etc.)
Uses reflection: when the level loader sees an object of type
"player", it callscreatePlayer().
GameScene / EntityManager
GameSceneis the per-level world container.EntityManagerowns entity lifecycle and a spatial grid (160px cells) for collision queries; it also organizes entities by draw layer.
Entity-Component System
Game objects (entities) are built by composing reusable components.
Entity— a container that holds components and supports parent/child hierarchy for relative positioning. Components live in aHashMapfor fast lookup.Component— abstract base with lifecycle methodspreUpdate(),update(),postUpdate(). Components can subscribe to messages via theMessageHandlerfor event-driven behavior.
Component Library
Lisa Engine ships ~50 platformer components, organized roughly by role:
Physics & collision
BodyComponent, VelocityComponent, GridCollisionComponent, EntityCollisionComponent, WaterCollisionComponent, ColliderComponent, PlatformComponent, BlockComponent, DisappearingBlockComponent, EnemyBlockComponent
Health & damage
HealthComponent, MiniBarComponent, OxygenComponent, OverlapAttackComponent, OverlapAttackableComponent, ReviveComponent
Enemies
EnemyComponent, WalkerComponent, JumperComponent, FrogComponent, RushComponent
Hazards
SpikeComponent, ElectricSpikeComponent, CrushComponent, FallingComponent, StartFallingInDistanceComponent, StartFallingOnMountComponent
Switches & interactives
ButtonComponent, SwitchComponent, SwitchableComponent, KillSwitchComponent, KnifeSwitchComponent
Movables & transport
MovableComponent, BoxComponent, PusherComponent, MountableComponent, ConveyorComponent, TramComponent, SpringboardComponent, RailEndComponent
Bullets
BulletComponent, BulletSpawnerComponent
Rendering & effects
ViewComponent, ParticleComponent, ParticleEmitterComponent, SplashComponent, ActionComponent
Collectibles, exits, scene triggers
ItemComponent, SecretComponent, ExitComponent, ActivateOnScreenComponent, CameraLimitTriggerComponent, SceneWarpComponent
Note: The player itself is not an engine component — each game implements its own player on top of these primitives.
Level Loading
GameSceneLoader (core/src/net/dynart/lisa/core/GameSceneLoader.java)
Loads Tiled TMX maps
Parses background, main, and foreground layers
Creates entities from object layers via the
EntityFactorySets up music, camera limits, and player abilities for the scene
Handles layer separation for parallax effects
Levels are TMX files designed in Tiled, stored in the consuming game’s assets/data/levels/ and registered in resources.json.
Input System
A unified abstraction across keyboard, touch, and gamepad.
GameController(core/src/net/dynart/lisa/core/controller/GameController.java) — central input hub with a logical button set: LEFT, RIGHT, UP, DOWN, A, B, X, Y, MENU.KeyboardListener— desktop keyboard input.TouchListener— mobile touch with on-screen buttons.GamepadListener— console-style gamepad / joystick.
Bindings are user-customizable via the engine’s customize-controls screens.
Screens
The engine ships 16 screens for common game states:
Core gameplay: GameScreen, GameFadeInScreen, PauseScreen, GameOverScreen
Menus: MenuScreen, SettingsScreen
Customization: CustomizeButtonsScreen, CustomizeKeyboardScreen, CustomizeGamepadScreen, CustomizeTouchScreen
Narrative: CutsceneScreen, DialogScreen
System: LoadingScreen, LogoScreen, EmptyScreen
GameStage provides the in-game HUD overlay (score, health, pause button) on top of GameScreen.
Script System
A JSON-based command system used for cutscenes and special abilities.
Command pattern — each command implements
act(delta)and returnstruewhen finished.Composition:
SequenceCommand,ParallelCommand,SkippableCommandDialog & timing:
SayCommand(via DialogStage),DelayCommandMovement:
WalkToCommand,WalkToExitCommand,SetMovementActiveAnimation:
SetAnimationCommand,SetVisibleCommandCamera:
MoveCameraToCommand,SetCameraTargetCommand,SetCameraLimitCommandGame logic:
TriggerCommand,PlayMusicCommand,SetParentCommand
Scripts are stored as JSON in the consuming game’s assets/data/scripts/ and loaded via ScriptLoader.
Resource Management
Resource managers, owned by Engine:
TextureManager— texture atlases and individual texturesSoundManager— sound effects and music with volume controlFontManager— bitmap fontsSpriteAnimationManager— animation cachingLevelManager— level registration and retrievalPathManager— movement paths for entitiesSecretManager— secret-collectible tracking
Configuration files (provided by the consuming game)
config.json— physics constants, input mappings, platform-specific overridesresources.json— asset registry (sounds, music, textures, levels, animations)
Platform-specific sections in config.json override base values; arrays in platform sections replace rather than append.
Architecture Patterns
Composition over inheritance
Entities are not defined by class hierarchies but by the components they contain. A moving, animated, collectible object is just the right combination of components.
Spatial grid
EntityManager divides the world into 160px grid cells. Collision checks only consider entities in nearby cells, keeping detection fast even with many entities on screen.
Message / event bus
Components publish and subscribe to events through MessageHandler. This loose coupling lets systems react to events (e.g. a collectible being picked up) without hard-wiring references to each other.
Reflection-based factory
EntityFactory uses reflection to dispatch object types from Tiled to createX() methods. Add a new entity type by adding a createMyType() method to your subclass — no registration code required.
Pooling
Particles and bullets use object pools (ParticlePool, BulletPool) to reduce GC pressure in tight inner loops.
Adding a new entity type (in your game)
Define the component in your game’s components package:
public class MyComponent extends Component { @Override public void update(float delta) { /* ... */ } }
Add a factory method to your game’s
EntityFactorysubclass:public Entity createMyEntity(Parameters parameters) { Entity entity = new Entity(); entity.addComponent(new BodyComponent()); entity.addComponent(new ViewComponent()); entity.addComponent(new MyComponent()); return entity; }
Place it in Tiled — set the object type to
"myEntity"(matches the factory method name, sanscreate); add custom properties as needed.Define animations in
resources.jsonif needed.
Key File Reference
Purpose |
File Path |
|---|---|
Engine core |
|
Engine config (base) |
|
Entity factory (base) |
|
Entity / component |
|
Entity manager |
|
Level loader |
|
Script loader |
|
Game controller |
|
Version
Current Lisa Engine version: 0.1.0 (libGDX 1.14.0). Defined in the root build.gradle.