Introduction

What is Fusion?

Fusion is a code-driven 3D game engine powered by the Vulkan GPU API.

Features

  • Positional audio engine
  • Built in Mp3, FLAC, and OGG file decoding
  • Realtime colored lighting
  • Fast physics engine backed by Jolt
  • Built in player controller, no need to write one
  • Support for cubemapped skyboxes
  • Easy to use client api
  • Fast in-house build system, uses lua for configuration
  • Cross platform, Microsoft Windows, and GNU/Linux are supported
  • Built in level editor
  • Custom file formats for models
  • Custom physics collision meshes
  • Ability to replace the client API if you don't want to use it (not recommended)

Why use Fusion?

Fusion is not really a public engine(sorry), its built with simplicity in mind, modern games use graphics as a way to get away with crappy game design, Fusion dosen't include any fancy graphical effects, you can still make a good game without pathtraced, screen spaced reflected glass or whatever. Its also code-driven, YOU WILL NOT HAVE AN OPTION TO USE VISUAL CODING.

Example code

#include "Fusion/etc/parameters.hpp"
#include "Fusion/math/vector.hpp"
#include "Fusion/world/level.hpp"
#include <MesaExample/triggers/helloWorldTrigger.hpp>


HelloWorldTriggerHandler::HelloWorldTriggerHandler() {
    m_source = Fusion::Audio::addSourceFromAsset("example_sound");
};

void HelloWorldTriggerHandler::onActivate(Fusion::Parameters params){
    auto obj = params.getAudioLvlItem("Obj");

    obj.beginUpdate();

    obj.setProperty(AUDIO_SRC_ITEM_PROPERTY_VOLUME, 0.5f);
    obj.setProperty(AUDIO_SRC_ITEM_PROPERTY_PLAYING, "PLAY");

    obj.endUpdate();
}

void HelloWorldTriggerHandler::onDeactivate(Fusion::Parameters params){
}

This code handles when a trigger is activated, the trigger name needs to be registered on game start. All it does is get an audio level item from its parameters, and sets the volume to 0.5, and makes it play. We could also manually create an audio-source if we wanted too.

Mesa

Mesa is the build system for Fusion

Screenshot

About Mesa

Mesa is the cross-platform build system for Fusion, it supports G++ based compilers, and is configured in Lua.

Example build script

MesaSetWorkspaceName("MesaExample")
MesaSetCompiler("GNU_G++") -- NOTE: Change if you want
MesaSetOutputDir("gbuild")

MesaSetWorkspaceGlobals({
    GlobalIncludes = {"FusionClient/include", "FusionClientHeaders/include", "include"}
})

MesaInitWorkspace({
    Projects = {
        MesaProjectRef("FusionClient"),
        MesaProjectRef("FusionClientHeaders"),
        MesaProjectRef("Client")
    },
    Tools = {
         MesaFindTool("GPackage", {
             ClientDLLPath = "ClientGame.so"
         })
    },
    SDKs = {
        -- NOTE: You'll probably want to add your Fusion SDK here!
    }
})

MesaSetWorkspaceName :: (String)

Sets the current workspace name, should only be called once

MesaInitWorkspace :: (Table)

Creates a new workspace

-- Config value list:

MesaInitWorkspace({
    Projects = {
        -- List of workspace projects in BUILD ORDER, pulled with MesaProjectRef
    },
    Tools = {
        -- List of workspace tools, pulled with MesaFindTool
    },
    SDKs = {
        -- List of workspace SDKs pulled with MesaSDKRef
    }
})

MesaSetProjectName :: (String)

Sets the project name, should be called before MesaInitProject

MesaInitProject :: (Table)

Creates a new project, should be called after MesaInitProject

MesaInitProject({
    -- List of source files to compile
    Sources = {
        "src/main.cpp"
    },

    -- List of include directories for the project
    Includes = {
        GlobalIncludes -- See MesaSetWorkspaceGlobals
    },

    -- List of requires projects/libraries for the project
    Require = {
        MesaPkgProjectRef("FusionClient"),
        MesaPkgProjectRef("FusionClientHeaders"),
    },

    -- Optional: Generates a static, or dynamic library from the project, instead of an executable
    --PackageTarget = {
    --    OutputType = "Dynamic", -- Dynamic for a DLL/SO file, or Static for a LIB/A file
    --    OutputName = "Game", -- Name of the static/dynamic library
    --    RawOutputName = true -- Should mesa append "lib" to OutputName?
    --},

    -- Build config
    Build = {
        EnableDebugSymbols = true -- Should -g be passed to the compiler, generating debug symbols?
    }
})

MesaProjectRef :: (String)

Reference a project

MesaPkgConfig :: (String)

This feature is only avalible on GNU/Linux systems

Locate a package using pkg-config

MesaHasFeature :: (String)

Checks if the given feature is avalible, feature names listed below

  • PkgConfig, supported on Linux

MesaPkgProjectRef :: (String)

Create a package reference from a project

MesaSetCompiler :: (String)

Set the compiler identifier to use for the workspace, compiler IDs listed below

  • MinGW_G++, MinGW G++ compiler
  • GNU_G++, GNU G++ compiler

MesaSetWorkspaceGlobals :: (Table)

Set the workspace globals

MesaSetWorkspaceGlobals({
    GlobalIncludes = { "include", "FusionClient/include" }
})

MesaLog :: (String)

Log a message to the console

MesaFindTool :: (String)

Locate a mesa tool, tools should be placed in:

  • mesa_tools/TOOLNAME.mdll
  • config/mesa/tools/TOOLNAME.mdll

MesaSDKRef :: (String)

Reference and sdk located at the given position

Mesa Command Line Guide

msabuild

Main mesa build utility

Usage: MesaBuild [--help] [--version] -msa-script-file VAR [-msa-action-build] [-msa-execute-tool VAR] [-msa-action-list-tools] [-msa-action-generate-compile-commands]

Mesa build system frontend
Programmed by Interfiber <webmaster@interfiber.dev>

Optional arguments:
  -h, --help                             shows help message and exits
  -v, --version                          prints version information and exits
  -msa-script-file                       Set the mesa workspace script file location [required]
  -msa-action-build                      Perform the build action on the current workspace script
  -msa-execute-tool                      Execute a tool loaded by the workspace script [default: "NONE"]
  -msa-action-list-tools                 Lists all tools loaded by the workspace script
  -msa-action-generate-compile-commands  Generates a compile_commands.json file from the workspace script

This program is part of the Fusion game engine

Every Fusion project has a pre-generated mesa.lua, Client.project.lua, FusionClient.project.lua, and FusionClientHeaders.project.lua. The main mesa.lua script loads the projects, and sets globals

msatool

Allows execution of Mesa tools directly

Usage: MesaTool [--help] [--version] -msa-mdll-path VAR [-msa-tool-config VAR]

Execute mesa MDLL tools directly

Optional arguments:
  -h, --help        shows help message and exits
  -v, --version     prints version information and exits
  -msa-mdll-path    Set the path to the tools MDLL file [required]
  -msa-tool-config  Set the tool config [default: "Invoke=0"]

This program is part of the Fusion game engine

Fusion Client API

The powerful C++ library which backs client-sided Fusion code

Client API Triggers

Triggers are fundemental concept in Fusion, they allow for the level to perform code actions when events occur.

Trigger types

The two trigger types are:

  • ObjectEnter: Fire the trigger when an object(even the player) enters it
  • PlayerJump: Fire the trigger when the player is in contact with the trigger, and jumps

Trigger output

The trigger output is the name you use when LINK_TRIGGER_HANDLER, its the name of the trigger to dispatch

Trigger parameters

Trigger parameters allow a trigger level object to pass variables data to the client on trigger activate/deactivate. There are three types of parameters:

  • LvlObject: Pass a level object by ID to the trigger
  • Integer: Pass a static number to the trigger
  • String: Pass a static string to the trigger

Trigger parameters are stored as a key/value pair, and the client can get the values by using the parameters objects multiple get methods, by passing in the parameter name(aka key), and getting the parameter value.

Trigger flags

Trigger flags are flags on how the trigger should work in the level, they can be added in Fission's trigger flags editor.

Detailed descriptions of the trigger flags are below:

  • NoFlag: Nothing
  • AllowPhysicsObjects: Only works with ObjectEnter, trigger will also fire when a physics object interacts with it
  • DisallowRepeat: Trigger is removed once it is deactivated
  • AllowEveryTick: Trigger is fired every tick while it is activated

API Reference

Below is the complete API reference for Fusion client triggers

Best practice! Use a triggers.hpp header file

Have a header file, usually named triggers.hpp which imports all triggers, and registeres them.

#pragma once
#include "Fusion/etc/trigger.hpp"
#include "helloWorldTrigger.hpp"
#include "Fusion/game/game.hpp"

BEGIN_LINK_TRIGGER_HANDLERS

LINK_TRIGGER_HANDLER("helloWorld", HelloWorldTriggerHandler);

END_LINK_TRIGGER_HANDLERS

Begins linking trigger handlers, anything between this call and END_LINK_TRIGGER_HANDLERS is called on LINK_TRIGGER_HANDLERS.

Developer note:

This macro creates the function cInitTriggerHandlers, and END_LINK_TRIGGER_HANDLERS simply closes it

Ends linking trigger handlers, now to batch link all triggers handlers use LINK_TRIGGER_HANDLERS on game startup

Links the trigger name to the trigger handler class

Batch links all trigger handlers, this should be called once on game boot

CLASS: TriggerHandler

Base class for all trigger handlers, child classes should override onActivate(...), and onDeactivate(...)

FUNCTION: TriggerHandler::onActivate(Parameters params)

Called whenever the trigger is activated, the parameters are used to pass parameters from the level to the client

FUNCTION: TriggerHandler:onDeactivate(Parameters params)

Called whenever the trigger is deactivated, parameters are used the same way as onActivate uses them.

EXAMPLES

SWITCH LEVEL TRIGGER HANDLER

Header:

/**
    * Default trigger handler, switches the game level to ```LevelName```
*/
class SwitchLevelTriggerHandler : public TriggerHandler {
public:
    SwitchLevelTriggerHandler();

    void onActivate(Parameters params) override;

    void onDeactivate(Parameters params) override;
};

Implementation:


SwitchLevelTriggerHandler::SwitchLevelTriggerHandler() = default;

void SwitchLevelTriggerHandler::onActivate(Fusion::Parameters params) {
    Fusion::Game::switchLevel(params.getStringValue("LevelName"));
}

void SwitchLevelTriggerHandler::onDeactivate(Fusion::Parameters params) {

}

Best practice, triggers.hpp:

#include <Fusion/etc/trigger.hpp>
#include <Fusion/game/game.hpp>
#include <MyGame/triggers/switchLevelTrigger.hpp>

BEGIN_LINK_TRIGGER_HANDLERS

LINK_TRIGGER_HANDLER("switchLevelTrigger", SwitchLevelTriggerHandler)

END_LINK_TRIGGER_HANDLERS

Editor: