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
MACRO: BEGIN_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
MACRO: END_LINK_TRIGGER_HANDLERS
Ends linking trigger handlers, now to batch link all triggers handlers use LINK_TRIGGER_HANDLERS
on game startup
MACRO: LINK_TRIGGER_HANDLER(STRING NAME, CLASS HANDLER)
Links the trigger name to the trigger handler class
MACRO: LINK_TRIGGER_HANDLERS
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: