saemideluxe / semicongine

Small, (mostly) dependency free game engine

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Semicongine

Hi there

This is a little game engine, mainly trying to wrap around vulkan and the operating system's windowing, input and audio system. I am using the last programming language you will ever need, Nim

Building

Requires Nim to be installed and glslangValidator to be downloaded to the directory of the main compilation file (e.g. into examples/ in order to compile the examples). It can be downloaded at https://github.com/KhronosGroup/glslang/releases/.

Run nim help to see a list of available build commands.

Roadmap

Here a bit to see what has been planed and what is done already. Is being updated frequently (marking those checkboxes just feels to good to stop working).

Rendering:

  • Vertex attributes, vertex data
  • Shaders (allow for predefined and custom shaders)
  • Uniforms
  • Per-instance vertex attributes (required to be able to draw scene graph)
  • Fixed framerate
  • Instanced drawing (currently can use instance attributes, but we only support a single instance per draw call)
  • Textures
  • Materials (vertices with material indices)
  • Allow different shaders (ie pipelines) for different meshes

Required for 3D rendering:

  • Depth buffering
  • Mipmaps

Asset handling:

  • Resource loading - [x] Mod/resource-pack concept - [x] Load from directory - [x] Load from zip - [x] Load from exe-embeded
  • Mesh/material files (glTF, but incomplete, not all features supported)
  • Image files (BMP RGBA)
  • Audio files (AU)
  • API to transform/recalculate mesh data

Other (required for alpha release):

  • Config files ala *.ini files (use std/parsecfg)
  • Mouse/Keyboard input handling
    • X11
    • Win32
  • Enable/disable hardware cursor
  • Fullscreen mode + switch between modes - [x] Linux - [x] Window
  • Audio playing - [x] Linux - [x] Windows Waveform API
  • Generic configuration concept (engine defaults, per-user, etc)
  • Input-mapping configuration
  • Telemetry
    • Add simple event logging service
    • Add exception reporting

Other important features:

  • Multisampling
  • Text rendering
  • Animation system
  • Sprite system
  • Particle system
  • Sound-animation
  • Paletton-export-loader
  • Arrange buffer memory types based on per-mesh-attribute type instead of per-shader-attribute type (possible?)

Other less important features:

  • Viewport scaling (e.g. framebuffer resolution != window resolution)
  • Query and display rendering information from Vulkan?
  • Game controller input handling
  • Allow multipel Uniform blocks
  • Documentation

Quality improvments:

  • Better scenegraph API
  • Better rendering pipeline API

Build-system:

  • move all of Makefile to config.nims

Documentation

Okay, here is first quick-n-dirty documentation, the only purpose to organize my thoughts a bit.

Engine parts

Currently we have at least the following:

  • Rendering: rendering.nim vulkan/*
  • Scene graph: entity.nim
  • Audio: audio.nim audiotypes.nim
  • Input: events.nim
  • Settings: settings.nim
  • Meshes: mesh.nim
  • Math: math/*
  • Telemetry: telemetry.nim (wip)
  • Resources (loading, mods): resources.nim

Got you: Everything is wip, but (wip) here means work has not started yet.

Handling of assets

A short description how I want to handle assets.

Support for file formats (super limited, no external dependencies, uses quite a bit of space, hoping for zip):

  • Images: BMP
  • Audio: AU
  • Mesh: glTF (*.gld)

In-memory layout of assets (everything needs to be converted to those while loading):

  • Images: 4 channel with each uint8 = 32 bit RGBA, little endian (R is low bits, A is high bits)
  • Audio: 2 Channel 16 bit signed little endian, 44100Hz
  • Meshes: non-interleaved, lists of values for each vertex, one list per attribute

Configuration

Or: How to organize s**t that is not code

Not sure why, but this feels super important to get done right. The engine is being designed with a library-mindset, not a framework mindset. And with that, ensuring the configuration of the build, runtime and settings in general becomes a bit less straight-forward.

So here is the idea: There are three to four different kinds of configurations that the engine should be able to handle:

  1. Build configuration: Engine version, project name, log level, etc.
  2. Runtime engine/project settings: Video/audio settings, telemetry, log-output, etc.
  3. Mods: Different sets of assets and configuration to allow easy testing of different scenarios
  4. Save data: Saving world state of the game

Okay, let's look at each of those and how I plan to implement them:

1. Build configuration

2. Runtime settings

This is mostly implemented already. I am using the Nim module std/parsecfg. There is also the option to watch the filesystem and update values at runtime, mostly usefull for development.

The engine scans all files in the settings-root directory and builds a settings tree that can be access via a setting-hierarchy like this:

setting("a.b.c.d.e")

a.b refers to the settings directory ./a/b/ (from the settings-root) c refers to the file c.ini inside ./a/b/ d refers to the ini-section inside the file ./a/b/c.ini e refers to the key inside section d inside the file ./a/b/c.ini

a.b are optional, they just allow larger configuration trees. d is optional, if it is not give, e refers to the top-level section of the ini-file.

3. Mods

A mod is just a collection of resources for a game. Can maybe switched from inside a game. Current mod can be defined via "2. Runtime settings"

I want to support mods from:

a) a directory on the filesystem b) a zip-file on the filesystem c) a zip-file that is embeded in the executable

The reasoning is simple: a) is helpfull for development, testing of new/replaced assets, b) is the default deployment with mod-support and c) is deployment without mod-support, demo-versions and similar.

Should not be that difficult but give us everything we ever need in terms of resource packaging.

4. Save data

Not too much thought here yet. Maybe we can use Nim's std/marshal module. It produces JSON from nim objects. Pretty dope, but maybe pretty slow. However, we are indie-JSON here, not 10M of GTA Online JSON: https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/

About

Small, (mostly) dependency free game engine


Languages

Language:Nim 59.7%Language:C 35.1%Language:C++ 5.2%Language:Python 0.0%