Final Force II - Modernised Retro Arcade Shooter


- Final Force 2 -
A retro-inspired scrolling shoot 'em up dragged in to the modern era.


A shoot em up inspired by retro shmups such as R-Type, Gradius, ThunderForce III and IV, among many others.


Fake / Pseudo 3D Engine for unparalleled parallax scrolling and depth.
Multiple ships and weapons with which to destroy your foes.
Several different stages/worlds, each with its own challenges.
Environmental obstacles.
Secrets, Bonuses, Power Ups.
Branching stages, more than one way to pass through stage.
Bosses! (of course).
Super Weapons.
Classic CRT Effects for an authentic arcade monitor experience.
Stats tracking.
In-game Level Editor.

Dev Log Teaser : Fake 3D Game Engine Preview Video

This is an early (very early) demo/test/prototype of the fake 3D engine in action.
Screen Shots/Mockups




2018-10-09 : Video of animation test for spaceship model
*NEW* 2018-10-20 : Level Editor : Rotating objects via mouse

Stay tuned for more to come...

Website :
Last edited:
It looks neat, but i can see the screen-filling foreground asteroid getting irritating after a while
Thanks for the feedback, those pesky asteroids will be dealt with, the video was just meant to show off the parallax effects. I quickly threw a bunch of random objects all over the place as a demo.

We definitely want the players view of the action to be clear in the actual game!


Looks great already ! Guess its a lot of early placeholder art there ! How far in dev are you ?
Wow really loving the 3D effects on the background <3
Thanks, you ain't seen nothing yet!

Looks great already ! Guess its a lot of early placeholder art there ! How far in dev are you ?
Yep, its just place holder art for testing, nothing final yet.

This current build of the engine is only a few weeks work in my spare time. There have been some previous prototypes that I've put time into as well, but I've had to re-write the engine a few times as I kept running into roadblocks where it couldn't do everything I wanted.

Man this game just oozes with awesome style!
Thanks! Again, there is nothing final at all here...just wanted to show off mainly the 3d effect. I'm quite happy with it and hope to show off more advanced stuff here in time.

Always like a good shooter.
Yeah, hoping to make a solid shooter here, with a few extra's added to make it interesting.
Video: Animated Player Ship

Today I added a proper player ship, complete with animations. Built a short segment of a level using the in-game level editor so you can see the spaceship in action.

Remember while viewing the video, everything is still a work in progress. I just threw together the level layout in a couple of minutes. Also, for example the bullet stream pouring out is just a quick WIP for demo purposes. The main thing for this one is the player ship animations.

Thanks for watching!



Looks really good. :) The roll is a nice effect for continuous vertical motion.
Might be fun to see a bit of thruster flare when moving right as well.


Man that looks awesome! Please keep the updates rolling. I'd love to see more of this no matter how minor are the things you add.
Video : FF2 Editor - Rotating level objects using the mouse

The in-game editor/level builder still needs some additions to make the work flow smoother.

First step is to implement object manipulation similar to how art software lets you transform images via the mouse using handles around the outside of the object.

This video shows the ability to rotate level objects using the mouse.

Being a coder, I had previously hacked together some code to use combination of key presses and mouse movements. However, after feedback decided to go ahead and do it in a more standardised way.

Following is the code I used to implement the rotation function.

I've created a "Handle Manager" object, that will manage the rotation/resizing/scaling/mirroring/flipping.

I've tried to keep it as uncoupled as possible, so it can just be plugged into the existing editor functions. I just need
to drop this object into the room that is being edited and voila! It works.

Incidentally, I'm trying to write the entire editor so it can be disabled/enabled without affecting the rest of the game. All the Editor objects are on their own layer called "Editor". If I build the game in release mode, this layer is automatically disabled when the game starts, so the Editor is not available in the actual game...yet. We haven't decided yet if we'll include the Editor in the release of the game, although we think it would be a good idea at some point.

Handle Manager Create Event
/// @description Object Handles Manager Create Event
// Handles the object handles for rotating/resizing objects
// At the moment, just rotation is implemented.

// Set the min and max distance the mouse needs to be
// from the bounding box of the object to trigger the
// object rotation function.
min_rotate_distance = 16;
max_rotate_distance = 64;

// List of current handle modes implemented
enum GrabMode

// Current handle mode
mode = GrabMode.None;

// Is the user holding down the mouse button(dragging)
dragging = false;

// Record the initial angle of the object before rotation
start_angle = 0;

// Measure the change in angle based on the mouse starting position,
// and where it currently is.
angle_change = 0;
Handle Manager Step Event
/// @description Handle Manager Step Event

// Check that the oPlacer object exists [oPlacer is the main editor controller object]
// NOTE : valid() is a helper function, it checks that an instance id is not set to noone,
//        and that the instance exists.
if ( valid(oPlacer) )
    // Grab the currently in-focus object from the Editor
    // target is an instance id of one of the level objects.
    var target = oPlacer.focused_object;
    // Check that the in-focus object is valid.
    if ( valid ( target ) )
        // If the user is not currently dragging (they haven't started rotation yet)
        if ( !dragging )
            with ( target )
                // ROTATION ACTIVATE CHECK
                // Check if the mouse is greater than the min distance for rotation to take place.
                var min_left  = bbox_left   - other.min_rotate_distance;
                var min_top   = bbox_top    - other.min_rotate_distance;
                var min_bot   = bbox_bottom + other.min_rotate_distance;
                var min_right = bbox_right  + other.min_rotate_distance;
                var max_left  = min_left  - other.max_rotate_distance;
                var max_top   = min_top   - other.max_rotate_distance;
                var    max_right = min_right + other.max_rotate_distance;
                var max_bot   = min_bot   + other.max_rotate_distance;
                // Check if the mouse is greater than the min distance for rotation to take place.
                if ( !point_in_rectangle(mouse_x, mouse_y, min_left, min_top, min_right, min_bot) &&
                      // and check if the mouse is less than the max distance for rotation to take place.
                      point_in_rectangle(mouse_x, mouse_y, max_left, max_top, max_right, max_bot) )
                    // Mouse is in position - so change the cursor and mode to show the user they can
                    // initiate rotation by left-clicking and dragging.
                    other.mode = GrabMode.Rotate;
                    o_cursor.image_index = 4
                    // ** oPlacer.ignore_editor ** NOTE:
                    // This tells the main editor object to ignore clicks temporarily
                    // Otherwise, when the user clicks to rotate the object, and their click would
                    // have selected another object, or in the case of there being nothing under the
                    // cursor, deselecting all objects, it would prevent the rotation tool from working.
                    // TODO : Would prefer to have this uncoupled from the editor like this eventually.
                    oPlacer.ignore_editor = true;        
                    // Cursor is not "in the zone" for rotating, so reset the mouse cursor to normal
                    // and resume normal editor functions.
                    other.mode = GrabMode.None;
                    oPlacer.ignore_editor = false;
                    o_cursor.image_index = 0
        // Check for dragging
        if ( mouse_check_button_pressed(mb_left) )
            dragging = true;
            start_angle = point_direction(target.x, target.y, mouse_x, mouse_y)
            target_start_angle = target.angle;

        // Check for stop dragging
        if ( mouse_check_button_released(mb_left) )
            dragging = false;
            mode = GrabMode.None;
            oPlacer.ignore_editor = false;
            o_cursor.image_index = 0

        // Calculate how far the mouse angle has changed from the point where dragging started.
        if ( dragging )
            var current_angle = point_direction(target.x, target.y, mouse_x, mouse_y)
            angle_change = angle_difference(start_angle, current_angle)
        // Apply the appropriate action.
        switch ( mode )
            case GrabMode.None:
            case GrabMode.Rotate:
                target.angle = target_start_angle - angle_change;
        debug_draw("DRAGGING : " + string(dragging))
        debug_draw("ANGLE CHANGE : " + string(angle_change))