Changelog LITIengine v0.4.12-alpha

The LITIengine Changelog for the release v0.4.12-alpha.

Fixes

  • Fixed an issue that caused the screenlocation of the ScreenManager not to be updated
  • Fixed an issue in the AStarGrid implementation.
  • Fixed an issue that causes AStarNode costs not to be reset after a path finding operation was executed.
  • Fixed a potential ArgumentNullException in the RenderComponent that could occur when switching to other applications
  • Fixed a bug with the RangeAttribute that caused the max modifier not to be applied to the max value.
  • Fixed an issue with SpeechBubbles not being removed from the active list anymore.
  • Fixed an issue that caused the IEntity bounding box not be updated when x/y or location were set.
  • Fixed an issue that caused interrupted Gamepad hotplug threads not to be stopped properly.
  • Fixed an issue with Emitters being rendered while not in the viewport
  • #116 Adjusted tileset loading to work on Unix/Linux computers
  • Fixed an issue with the Sound dataLine being opened while already opened
  • #123 Fixed an issue that caused wavy rendering when clamping to map

Features / Improvements

  • Squeezed out a few more frames by improving the caching mechanisms for sprites.
  • Removed the parallel MapLayer rendering because it produced more overhead than it saved rendering time.
  • Affected entities of Abilities are now always sorted independent of whether multi-target is enabled.
  • Tiles now only evaluate their flipped state once when the constructor is called.
  • Slightly improved the performance of the RenderComponent.
  • Improved the performance of the UpdateLoop and RenderLoop
    • The UpdateLoop is no longer using a stream to iterate all updatables.
  • Added the possiblity to render the AstarGrid and the Path that is found by the algorithm.
  • Improved fallback path finding when the target AStarNode is not walkable
  • The AStarGrid.assignPenalty method is now protected to be able to overwrite it.
  • Extended the IMobileEntity implementation to calculate the velocity for the current tick.
  • Implemented TimeUtilities.nanoToMs method to convert nano seconds to ms.
  • Implemented Gamepad.onReleased event.
  • Make use of Gamepad default deadzones in the GamepadEntityController.
  • Extended the Environment with the possiblity to retrieve an IEntity of a particular type by its id/name .
  • Implemented the possibility to check whether a resource string is present.
  • Implemented the possibility to check whether a speechbubble is currently active for an entity.
  • Implemented methods on the RenderEngine that allow to scale an image via AffineTransform.
  • Extended the IAnimationController with the possibility to provide an AffineTransform.
  • Implemented the possibility to override MapObject loading functionality
    • Previously, a lot of logic was implemented internally within the MapObjectLoaders, so child implementations would have to re-implement some basic stuff on their own.
      With this change, every MapObjectLoader has a createXXX method that can be simply overwritten in case one just wants to adjust the created instance of provide a custom child implementation.
  • Implement the possibility to scale Props to the size of the IEntity.
  • Extended the ICombatEntity with a method that allows to check whether it was hit in a specified time span.
  • Add new Valign and Align values.
  • #74 Implemented the possibility to set the origin Align and Valign for Emitters.
  • Implemented the possibility to provide the CollisionType for raycasts.
  • Clean up Animation implementation to no longer use a Spritesheet that was being unloaded (either removed or updated).
    • Previously the Animation class would still have a reference to the old deprecated Spritesheet.
    • Spritesheets now have a isLoaded() flag that indicates whether they are (still) loaded in the current game instance.
  • Implemented a method that allows to check whether a specific image extension is supported by the engine. (ImageFormat.isSupported).
  • #75 Implemented the possibility to control whether particles fade.
    • Previously this was active for normal particles and it wasn’t possible to disable the behavior.
      With this change, it is possible to define whether particles should fade out over the course of their TTL.
      This also works for sprite particles now.
  • Improved the Particle implementation by some collision related options.
    • With this change the particles can support continuousCollision if required. Note that this is very performance crucial and should be only used when absolutely necessary.
  • Extended SoundPlayback with method to check whether it is currently playing.
  • Improved performance for raycast collision checks.
  • #113 Implemented possibility to set a custom gain for a SoundPlayback.
  • The SoundEngine is now using the Input.getLoop() to update the sounds.
    • This was necessary to support adjusting sounds while the main GameLoop is paused.
  • Extended the IEnvironment with the possibility to search IEntiteis by multiple Tags.
  • Extended the IScreenManager with the possibility to get its center point.
  • Extended IMouse with method to set location by two double values.
  • Extended the Emitter implementation with the possiblity to specify a graphics quality that is required at minimum to render an Emitter.
  • #119 The OrthogonalMapRenderer is no longer rendering invisible MapLayers
  • Expose the setBackground(Color) method for the RenderComponent.
  • Custom MapObject properties are now serialized in alphabetical order.
  • The order of a Layer is now saved as custom property instead of an unsupported XML-attribute.
  • Implemented a Tag annotation that can be used to provide default tags for a custom IEntityimplementation
  • Registering a MapObjectLoader no longer requires a type
    • The MapObjectType is already provided by the IMapObjectLoader.getMapObjectType method and therefore all MapObjectLoader implementations already have this information which makes it redundant to specify in separately when registering a new MapObjectLoader.
  • Implemented possibility to provide an AffineTransform for the CursorImage

Changes

  • Added a new namespace de.gurkenlabs.litiengine.pathfinding that contains all path finding implementations
    • Added a new sub-namespace for the AStar implementation de.gurkenlabs.litiengine.pathfinding.astar
    • Previously this was all located under de.gurkenlabs.litiengine.physics
  • Lowered the DEFAULT_MAX_DISTANCE for sounds to be heared from 250px to 150px.
  • An entity SoundPlayback now evaluates its position by the center of the entity.
  • Remove the Sound.find method and rename the Sound.load method to Sound.get for
    • For sounds, its not necessary to differentiate between the two because actually the load method just reused the find method as default and only loaded something if the sound wasn’t already present.
  • Moved the Direction enum to the more general namespace de.gurkenlabs.litiengine.
  • Rename the Particle.getLocation method to Particle.getRenderLocation.
  • Setting the location on a GuiComponent now also updates its children
  • Pulled out all Font related attributes of the Appearance
    • Font information and Text alignment on a GuiComponent, for example, are strongly dependent on each other, making it necessary to have them in one place.
      Introduce a GuiProperty “defaultFont” to facilitate Font setup.

Major overhaul on the AmbientLight and Shadow Rendering

We now basically create an additional dynamically created tile layer and render the individual tiles.
When a light/shadow is added/removed/moved or changed only the affected tiles are updated on the dynamic layer.

Previously an image of the size of the entire map had to be redrawn which resulted in a major performance issue and made actually dynamic lighting almost impossible.

The Game is now processing command line arguments when being initialized

The Game.init(String...args) now optionally takes in command line arguments from the applications main method.
There are two default command line arguments at the moment that are being processed:

  • -release : If set, this argument disables all debugging functionality. This is particularly useful for deployment
  • -nogui: If set, this argument will not spawn a JFrame. This can be usesful for e.g. a gameserver or unit tests

Major refactoring on the whole event management

With the previous implementation, it wasn’t possible to remove listeners from the event handling because we only provided a lambda implementation. With this change, large parts of the engine were refactored to provide proper add/remove methods.

Also, this changed reuses EventListener class as base class for all custom engine listeners.
We’ve provided either adapter implementations or more fine granular listeners that only provide certain callbacks to allow the user of the API to decide what he actually wants to listen to.

There are still some events in the engine that need to be refactored in the future.

#118 Change MapObject position and size from int to float.

Add a custom XmlAdapter that makes sure that the float values are serialized like integers (without decimal digits) when they are technically integers.
This was necessary to keep the format consistent with the tiled map format.

#125 Overhaul of the GameInfo

This change takes care of the inconsistencies of the GameInfo class.
It not only provided information about the game but also the defaultRenderScale and even some unused fields.

We’ve also extended the GameInfo with more detailed information about the game (e.g. publisher or website) and additionally provided the possibility to add custom properties for even more project specific information.

#129 Overhaul on the EntityController management

Problem
Previously, the whole management of controllers that are related to entities was really inconsistent.
They were also managed globally, although an entity instance always had to be present in order to retrieve them. There were also some issues with the EntityControllerManager returning wildcard types whilst this essentially added no value.
The basic interfaces for the controllers were all generic as well which required such an implementation.

Goal
Make the basic controller interfaces non-generic while keeping the syntactic sugar to have a generic implementation for the actual classes.
With this change, the controllers are managed similar to a component-based system and can be directly used/set/retrieved from an IEntity.

Also, this refactoring adds a method that allows to simply scale the sprite for an IEntity with a simple method on the IEntityAnimationController.

#130 Refactoring on the Environment rendering pipeline

Re-work the whole implementation of the Environment's rendering pipeline.

It is now more straight forward and less confusing to understand:

BACKGROUND-> GROUND-> SURFACE-> NORMAL -> (static shadows) -> OVERLAY-> (ambient light) -> UI

We still keep the named RenderType enum because it makes it easier to understand compared to e.g. an alternative approach with just numbers. Also it transfers the original design idea for the rendering pipeline.

IRenderable implementations can now be registered for any of the RenderType values.

Internally, the Environment.render method does the following for every RenderType (besides RenderType.NONE):

  1. Render all Map Layers of that type
  2. Render all registered IRenderable implementations of that type
  3. Render all added IEntities of that type
  4. Call-back on the EnvironmentRenderListener.rendered listeners for that type
  5. If dbg_logDetailedRenderTimes = true: track the time it took to execute the rendering

Regarding issue #128: It’s now possible to render something behind GROUND layers using RenderType.BACKGROUND or the related call-back:

Game.getEnvironment().addRenderListener(RenderType.BACKGROUND, (g, t) -> {
  // render something on the graphics object g
 });

utiLITI

  • Fixed an issue with collision spinners not working properly
  • Added type prompt to the search box.
  • #102 Adjusted entity counter in Layer Toolbar when adding/deleting entities on a layer
  • #110 Adjusted map selection properly when (re)importing maps
  • Dragging entities no longer reloads them from the environment and instead just sets the location on the already present entity.
  • #112 Extended the editor with Drag&Drop support for resources
  • #99 The FileDialog is now reused to keep the configuration for importing resources.

Misc

  • A ton of SonarQube fixes
  • Improved source code documentation
  • Added a CodeClimate badge