A generic game loop implementation in C++ based on Fix Your Timestep!
lasso is at early stages of design and development and is subject to incompatible changes. All feedback is welcome and appreciated! Detailed documentation is being built on the wiki.
This project supports the Meson build system,
so you may want to install it (although it is not required). A legacy
CMakeLists.txt
still exists, but is not
actively maintained.
A compiler with
Concepts TS
support (e.g. GCC 6 or above with options -std=c++2a
and -fconcepts
)
is required to use lasso. Then, having Meson installed,
run the following commands at the root of this project:
meson build
cd build && meson install
Alternatively, you may just put lasso.h
somewhere in
the source tree of your project.
The meson install
command above will put (install) it at /{prefix}/lasso/
(relative to the default Meson
paths).
On Linux, that is /usr/local/include/lasso/
.
Then you just need to have /usr/local/include/
in your header search path
and you are ready to #include <lasso/lasso.h>
.
Conversely, if you have somehow put lasso.h
in your
source tree, you need to #include "lasso.h"
.
lasso knows how to call into your game via the C++ concept below:
template<typename T> concept bool GameLogic =
requires (T logic,
LoopStatus const &status,
duration const &delta) {
{ logic.init() } -> void;
{ logic.simulate(status, delta) } -> void;
{ logic.render(status, delta) } -> void;
{ logic.is_done() } -> bool;
{ logic.terminate() } -> void;
};
That means you need a class
or struct
that implements the
following member functions:
void init();
, which is called once right before the loop starts and you can use it to initialize anything you need (beyond the constructor of your class);void simulate(LoopStatus const &, duration const &);
, which is called ifdelta
or more nanoseconds have passed since the last call to advance your simulation (input, physics, AI, etc.);void render(LoopStatus const &, duration const &);
, which is called once in every iteration to render what has been simulated;bool is_done();
, which is called once in every iteration to determine whether the loop should terminate;void terminate();
, which is called once right after the loop ends and you can use it to clean up anything you need (additionally to what will be done in the destructor of your class).
Additional member functions may be added to GameLogic
and its existing ones might be modified in the future.
There are no constraints on other member functions or
variables that the class may have.
Examples of classes implementing this concept can be seen in the
examples folder, especially the Game.h
.
and Game.cpp
blueprints.
After having implemented your class (let us call it T
),
running it is as simple as:
T t;
// ...
lasso::MainLoop{}.run(t); // or pass in T{} directly
The Simple and Fast Multimedia Library (SFML) must be installed to compile and run an example. If you want to enable the compilation of the examples, you may run:
meson build -Dexamples=true
cd build && ninja
or, after having initially run Meson and while at the build/
directory:
meson configure -Dexamples=true
ninja
In order for an example to locate Roboto-Regular.ttf
and hence render text, you must run the compiled executable from either the
build or the examples/
directory (or set any of them as the
working directory in your IDE; preferably the build one).