Upgrade Guide 4.0.0



Breaking changes in 4.4.0 are limited to usage with OpenFL 8. OpenFL 3.6.1 (Legacy or Next) is still fully supported. The breaking changes when upgrading to OpenFL 8.0.0 and Lime 6.3.0 are as follows:

  • There is no support for blend modes (FlxSprite.blend). This is because drawQuads() (the rendering API replacing drawTiles() in OpenFL 8), doesn't support them. In some cases, blend modes may be emulated using shaders. An example of this can be seen in our BlendModeShaders demo.
  • Like already the case in OpenFL 3.6.1 + Next, the flixel.effects.postprocess API is not supported in OpenFL 8. As a replacement, a shader filter can be applied to the FlxGame instance or a FlxCamera as shown in the Filters demo.
  • OpenFL 3.6.1 with -Dnext had support for per-sprite, per-camera or game-wide GLSL shaders. All of these are still fully supported, but the syntax has changed a bit.

Here's a simple example of a shader found in FlxBunnyMark:

With OpenFL 3.6.1 + Next:

import openfl.display.Shader;

class Invert extends Shader
    @fragment var fragment = '
        void main()
            vec4 color = texture2D(${Shader.uSampler}, ${Shader.vTexCoord});
            gl_FragColor = vec4((1.0 - color.r) * color.a, (1.0 - color.g) * color.a, (1.0 - color.b) * color.a, color.a);

    public function new()

With OpenFL 8:

import flixel.system.FlxAssets.FlxShader;

class Invert extends FlxShader
        #pragma header

        void main()
            vec4 color = flixel_texture2D(bitmap, openfl_TextureCoordv);
            gl_FragColor = vec4((1.0 - color.r) * color.a, (1.0 - color.g) * color.a, (1.0 - color.b) * color.a,   color.a);

    public function new()

To summarize the differences, shaders should...

  • extend flixel.system.FlxAssets.FlxShader instead of openfl.display.Shader
  • use @:glFragmentSource() metadata for the shader source rather than a @fragment var
  • have #pragma header before main()

Attributes have changed as follows:

With OpenFL 3.6.1 + Next With OpenFL 8
${Shader.uSampler} bitmap
${Shader.vTexCoord} openfl_TextureCoordv
${Shader.uTextureSize} openfl_TextureSize

You may also have noticed that in the invert shader example, texture2D() has been replaced with flixel_texture2D(). The former still works, but when using flixel_texture2D() in per-sprite shaders, the alpha and color transforms of a FlxSprite are already applied on the returned color, which was previously not supported. The effect of this can be seen when activating shaders as well as toggling "Simple" to "Complex" in FlxBunnyMark:

With OpenFL 3.6.1 + Next With OpenFL 8

Further shader examples can be found in these demos, which are all compatible with both OpenFL 3.6.1 + Next and OpenFL 8:


  • FlxTween.manager is now FlxTween.globalManager.
  • FlxTimer.manager is now FlxTimer.globalManager.
  • FlxCamera's scroll bounds now account for zoom. This means that you may need to adjust calls to setScrollBounds(), setScrollBoundsRect() or changes to the minScrollX / Y / maxScrollX / Y properties if they manually accounted for zoom.
  • The active variable of objects in flixel.util.helpers now defaults to true instead of false.


This guide is intended for users upgrading projects from version 3.3.x to 4.0.0. For non-breaking changes, please refer to the changelog.

The minimum required Haxe version for this release is 3.2.0.

A lot of changes can be handled with a simple find-and-replace in the editor of your choice.

elapsed argument added to update()

The function signature of update() changed to update(elapsed:Float). FlxG.elapsed is still available, but it is recommended to use the argument value instead.

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
override public function update():Void override public function update(elapsed:Float):Void
super.update(); super.update(elapsed);
x += 100 * FlxG.elapsed; x += 100 * elapsed;

Introduction of flixel.math

A new flixel.math package was added. A number of flixel.util classes have been moved there:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
import flixel.util.FlxMath import flixel.math.FlxMath
import flixel.util.FlxPoint import flixel.math.FlxPoint
import flixel.util.FlxVector import flixel.math.FlxVector
import flixel.util.FlxRect import flixel.math.FlxRect
import flixel.util.FlxAngle import flixel.math.FlxAngle
import flixel.util.FlxVelocity import flixel.math.FlxVelocity
import flixel.util.FlxRandom import flixel.math.FlxRandom

Move of "typed" classes:

Typed classes have been moved into the modules of the non-typed versions:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
import flixel.group.FlxTypedGroup import flixel.group.FlxGroup
import flixel.group.FlxTypedSpriteGroup import flixel.group.FlxSpriteGroup
import flixel.effects.particles.FlxTypedEmitter import flixel.effects.particles.FlxEmitter
import flixel.ui.FlxTypedButton import flixel.ui.FlxButton

Changed integer constants to enums:

ActionScript 3 does not have enums, which is why a lot of these "value sets" were implemented using integer constants. For improved type-safety and to better fit the Haxe coding style, they have been converted to enums:

As long as it's not ambiguous, Haxe allows using just the enum value name without the enum's name. In the first case, the enum also does not need to be imported. For example, this means that both of these syntaxes are valid:


Which of these two styles is used is mostly a matter of personal preference.

FlxCamera shake modes:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxCamera.SHAKE_BOTH_AXES flixel.util.FlxAxes.XY
FlxCamera.SHAKE_HORIZONTAL_ONLY flixel.util.FlxAxes.X
FlxCamera.SHAKE_VERTICAL_ONLY flixel.util.FlxAxes.Y

FlxCamera follow styles:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxCamera.STYLE_LOCKON FlxCameraFollowStyle.LOCKON
FlxCamera.STYLE_NO_DEAD_ZONE FlxCameraFollowStyle.NO_DEAD_ZONE
FlxCamera.STYLE_TOPDOWN FlxCameraFollowStyle.TOPDOWN

FlxText border styles:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxText.BORDER_NONE FlxTextBorderStyle.NONE

FlxTilemap auto-tiling options:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxTilemap.ALT FlxTilemapAutoTiling.ALT
FlxTilemap.AUTO FlxTilemapAutoTiling.AUTO
FlxTilemap.OFF FlxTilemapAutoTiling.OFF

FlxBar fill directions:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0

FlxG.html5 browser types:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
HTML5FrontEnd.OPERA FlxBrowser.OPERA

Changed String constants to abstract enums:

Some static String constants have been changed to abstract enums. This is not a breaking changes, since the old String values are still compatible, but for the sake of type safety it is recommended to use the enum values instead:

As with regular enums, the enum name may be omitted.

FlxText alignment:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
text.alignment = "left"; text.alignment = FlxTextAlign.LEFT;
text.alignment = "center"; text.alignment = FlxTextAlign.CENTER;
text.alignment = "right"; text.alignment = FlxTextAlign.RIGHT;

FlxG.keys keys:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxG.keys.anyPressed(["SPACE", "W"]) FlxG.keys.anyPressed([FlxKey.SPACE, FlxKey.W])
FlxG.keys.anyPressed(["SPACE", "W"]) FlxG.keys.anyPressed([SPACE, W])


HaxeFlixel 3.3.x HaxeFlixel 4.0.0
getScreenXY() getScreenPosition()
cachedGraphics graphic
resetFrameBitmaps() removed (set dirty to true to regen graphic)
getFlxFrameBitmapData() updateFramePixels()
loadGraphicFromTexture() removed (assign a frames collection to frames)
loadRotatedGraphicFromTexture() removed (assign a frames collection to frames)


HaxeFlixel 3.3.x HaxeFlixel 4.0.0
bounds minScrollX, minScrollY, maxScrollX and maxScrollY
setBounds() setScrollBoundsRect()
follow()'s Offset argument removed


loadMap() has been split up into loadMapFromArray() and loadMapFromCSV().


callAll() and setAll() have been removed - use forEach() instead:

// 3.3.x
group.setAll("scrollFactor", FlxPoint.get(0, 0));
// 4.0.0
    basic.scrollFactor.set(0, 0);


The hardware IDs of the different controller types are now mapped to a common FlxGamepadInputID. This avoids the need of having to handle multiple controller types - this now happens automatically under the hood.

// 3.3.x
if (gamepad.pressed(XboxButtonID.A) ||
    gamepad.pressed(OUYAButtonID.O) ||
    gamepad.pressed(LogitechButtonID.TWO)) {} 
// 4.0.0
if (gamepad.anyPressed([FlxGamepadInputID.A])) {}
// or
if (gamepad.pressed.A) {}

It is still possible to use the IDs from the flixel.input.gamepad.id classes via the functions with the Raw suffix.

Because of the poor driver support, the PS3 ID class / support for PS3 controllers have been removed.


Timers cannot be started right at construction anymore, instead you need to call start():

// 3.3.x
new FlxTimer(time, onComplete, loops);
// 4.0.0
new FlxTimer().start(time, onComplete, loops);


FlxPath#start() no longer takes a FlxObject argument, instead, FlxObject now has a path property. This means FlxObject takes care of updating the path, taking care of the issue that paths are not paused along with the objects they work on in substates.

// 3.3.x
var path = new FlxPath().start(object, points);
// 4.0.0
object.path = new FlxPath().start(points);

FlxColor / FlxColorUtil refactor:

FlxColor is now an abstract, which means it can be used like an object, while the underlying type is still a regular Int. The static FlxColorUtil functions can now be used as member methods or properties:

// 3.3.x
var color:Int = 0x008080;
// 4.0.0
var color:FlxColor = 0x008080;

The amount of colors presets (FlxColor.RED etc..) has been reduced.

FlxEmitter refactor:

FlxEmitterExt has been merged into FlxEmitter. For circular emitters, FlxEmitterMode.CIRCLE can be used.

Most properties are now FlxRangeBounds objects which have a min and a max FlxRange object.

The separate color component Bounds have been merged into a FlxRangeBounds<FlxColor>.

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
at() focusOn()
on emitting

FlxParticle changes:

Most properties are now FlxRange objects which have a start and an end value (for example velocityRange).

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
maxLifespan lifespan
lifespan age (counts up instead of down)

FlxRandom refactor:

FlxRandom can now be instantiated and the static functions are now member methods. A pre-created instance is available via FlxG.random.

Some methods have also been renamed or removed:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxRandom.intRanged(min, max) FlxG.random.int(min, max)
FlxRandom.floatRanged(min, max) FlxG.random.float(min, max)
FlxRandom.chanceRoll(chance) FlxG.random.bool(chance)
FlxRandom.weightedGetObject() removed (getObject() now has a range argument)
FlxRandom.colorExt() removed

FlxAngle changes:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
FlxAngle.getAngle(point1, point2) point1.angleBetween(point2)
FlxAngle.angleLimit() removed (use FlxMath.bound() instead)

There have been several changes to FlxAngle.rotatePoint():

  • the y-axis is no longer inverted
  • rotation is now clockwise
  • moved to FlxPoint (rotate())
// 3.3.x
var angle = 45;
var point = FlxPoint.get(10, 5);
FlxAngle.rotatePoint(x, y, pivotX, pivotY, angle, point);
// 4.0.0
var angle = 45;
var point = FlxPoint.get(10 + x, 5 + y);
var pivot = FlxPoint.weak(pivotX, pivotY);
point.rotate(pivot, angle);

FlxMath changes:

HaxeFlixel 3.3.x HaxeFlixel 4.0.0
newAmount = FlxMath.wrapValue(value, amount, max + 1) newAmount = FlxMath.wrapValue(value + amount, min, max)
FlxMath.getDistance(point1, point2) point1.distanceTo(point2)


HaxeFlixel 3.3.x HaxeFlixel 4.0.0
import flixel.text.FlxTextField import flixel.addons.text.FlxTextField
FlxPoint#inFlxRect() FlxPoint#inRect()
FlxRect#containsFlxPoint() FlxRect#containsPoint()
flixel.plugin.MouseEventManager flixel.input.mouse.FlxMouseEventManager
flixel.util.loaders.CachedGraphics flixel.graphics.FlxGraphic
FlxArrayUtil.getRandom() FlxG.random.getObject()

FlxVelocity's accelerateTowards*()-functions now only take a single maxSpeed argument (instead of x and y).

The complete option of FlxTween is now called onComplete.


Not all flixel-addons changes are covered here. Please check the changelog for the rest.

FlxNapeState refactor:

FlxNapeState is now FlxNapeSpace and no longer extends FlxState. This makes it possible to use the flixel.addons.nape package along with other FlxState subclasses (for example FlxUIState).

// flixel-addons 1.x.x
import flixel.addons.nape.FlxNapeState;

class PlayState extends FlxNapeState
    override public function create():Void
// flixel-addons 2.0.0
import flixel.FlxState;
import flixel.addons.nape.FlxNapeSpace;

class PlayState extends FlxState
    override public function create():Void