A New Game Written in D
Kenny Shields
mail at kennyshields.net
Tue May 17 23:19:55 UTC 2022
On Tuesday, 17 May 2022 at 16:59:31 UTC, Steven Schveighoffer
wrote:
> I unfortunately can't try it, as it's not open source, and I
> have a Mac. Are there any videos of gameplay?
Hi Steven. Apologies for the lack of a macOS build, I actually
don't own any Apple hardware so my capabilities for testing on
that platform are pretty limited at the moment. That said, all
the dependencies for the engine should work on macOS, so that's
probably something that I could remedy in the future. As for the
video, I'll see if I can something up later today that showcases
the gameplay.
> Are there any plans to sell/release the engine?
No plans for selling/releasing the engine, though I would like to
be able to use it to make a game that I can actually sell at some
point.
> Can you give a small overview of the engine design?
The engine takes a pretty standard OOP approach and relies
heavily on the concept of 'managers'. There is a base
'Application' class (which can be sub-classed if needed) that
handles a lot of the heavy lifting (window creation, main loop,
input polling), and contains instances of all of the facilities
that actually make it an engine (things like resource/sound/hook
managers, filesystem abstractions and database connections).
As one would would expect with most modern engines, there is a
'scene' management system (which are referred to as contexts in
the engine) that allows for easy implementation of game logic and
rendering. Simply sub-class the base 'Context' class, and you
have access to a set of methods that you can override as needed
(update, draw, keypress, keyrelease, etc...) to implement the
functionality of the scene. When you instance a context, it is
automatically added to the engine's internal context manager, and
can be activated/deactivated at any time. Here is an example of
what that looks like:
```d
class MyContext : Context
{
this(Application app)
{
name = "MyContext";
super(app);
}
override void activated()
{
// Load resources...
}
override void deactivated()
{
// Unload resources...
}
override void update(float delta)
{
// Update stuff...
}
override void draw(RenderWindow window)
{
// Draw stuff...
}
override void keyPressed(Event event)
{
// Key events...
}
}
```
And then instancing and actually using the engine looks like this
(from USG's main.d file):
```d
void main()
{
// create application
auto params = LaunchParameters();
params.windowName = "Untitled Shooter Game";
params.windowSize = Vector2i(1920, 1080);
params.statsEnabled = false;
params.uiAntiAliasing = 0;
params.uiDefaultSkin = "default:dark";
params.windowAntiAliasing = 0;
params.windowStyle = WindowStyle.Titlebar | WindowStyle.Close;
params.entryContext = "MainMenu";
// params.entryContext = "Game";
params.dataPath = "untitled-shooter-game";
auto app = new Game(params);
// create contexts
new MainMenuContext(app);
new GameContext(app);
// start application
app.start();
}
```
Beyond what I just described, the engine contains all kinds of
components geared toward game development. These include things
like timers, faders, oscillators, a SQLite-based registry system,
a basic Lua API, no-gc vectors (really just an abstraction of
std.container.array), and even a custom UI system (which has
become almost as complex as the engine itself unfortunately). It
also has a package of modules dedicated to creating and
simulating 2D top-down worlds, complete with tile-based geometry
and threaded pathing.
It's also very important to note that SFML makes most of the
audio/graphical functionality possible, as the engine relies
heavily on it's API (through CSFML).
> Do you use the GC at all?
The engine takes a hybrid approach with it's memory management,
but yes I do use the GC for a lot of it's functionality. Almost
all of the modules that implement the 2D game world do their
allocations outside of the GC (with malloc and the relevant
emplacement functions), which allows for more granular control
over how the simulation's memory works and reduces the burden on
the GC heap. With this reduction of GC heap usage, it allows for
GC-based operations in other parts of the engine without having
to worry too much about triggering an allocation or collection
cycle.
I know GCs are a big source of contention, particularly so among
game developers, but I have to say I've never really experienced
one of the (theoretical) scenarios where a GC ruins a game's
performance or something like that, at least not with the D GC.
It seems to just be a matter of not doing crazy things (like
running heap-based operations every frame) and pre-allocating
everything that you can with pools or something similar.
More information about the Digitalmars-d-announce
mailing list