Git Product home page Git Product logo

numpad / ecs-sandbox Goto Github PK

View Code? Open in Web Editor NEW
19.0 4.0 2.0 25.87 MB

Experimental game-engine sandbox using OpenGL and ECS.

CMake 0.36% C++ 77.68% C 19.01% Objective-C 0.52% Objective-C++ 0.58% Batchfile 0.07% Shell 0.02% GLSL 0.12% Python 0.13% Lua 0.23% Kotlin 0.01% HTML 0.49% GDB 0.01% Starlark 0.18% Ruby 0.04% Swift 0.10% JavaScript 0.37% Java 0.10%
game roguelite opengl entt ecs entity-component-system 3d sandbox marching-cubes-algorithm 3d-graphics game-development game-engine gamedev

ecs-sandbox's Introduction

ecs-sandbox

Personal entity component system (ECS) sandbox. Some day this will become a fun game I want to play.

Features

  • realtime, completely destructible terrain using the marching cubes algorithm.
  • emergent gameplay trough flexible combinations of components.
  • performance. instanced rendering and efficient ecs design allow for updating and rendering hundreds of thousand entities.
  • first-class modding support using the lua programming language. if you don't like something, or are missing a feature you can always get your hands dirty and implement it yourself.
  • procedural generation. technically infinite replayability as a new, unique level is generated every run.
  • thousands of items. many different and unique base items, item combinations and random modifiers.
  • free, non-linear gameplay. you decide how you want to play, the game tries to be as emergent and permissive as possible while trying to give few restrictions. there is no hard goal or forced playstyle.

(Note: these are the features and goals I want to achieve, while the building blocks for most features are already set, nearly all of them are still WIP or not even implemented at all.)

Screenshots

A short eye-catcher showing the latest features of the game and engine, while keeping a simple history of development milestones. v0.1

Version Screenshot & Notable features
v0.1 Added basic deferred shading

Changelog

Keep track of the current development status on the feature board. Planned, in-development and implemented features will be listed there.

Less frequently updated but still important is the bug tracker. This serves as a catch-all for noting any kind of bugs appearing. While not required, a detailed description of the bug and it's cause is greatly appreciated.

v0.2 - (unreleased)

  • Added decal render system & components

v0.1 - (2020-07-10)

  • Added changelog and version tracking
  • Added deferred shading

Building

Compiling the game should be pretty straightforward, head over to the build instructions to learn more about it!
You can also simply download a prebuilt binary. Keep in mind that these get updated less frequently.

Libraries

All libraries included and/or required for the game. Some libraries are not yet used but already included as they are pretty much guaranteed to be of use.

Library Version License Description
glm 0.9.9 MIT / modified MIT The mathematics library for vectors, matrices and everything inbetween.
glfw 3.4.0 zlib Multi-platform OpenGL library for creating windows with an OpenGL context and receiving inputs.
entt 3.4.0 MIT Library for the ECS architectural pattern, also comes with a great observer pattern implementation.
dear imgui 1.82 MIT GUI library for debugging and visualization.
FastNoise 0.4.1 MIT Noise generation library with support for many different noise algorithms.
sol2 3.2.0 MIT Generating bindings for and working with Lua.
Lua ? MIT A powerful, efficient, lightweight and embeddable scripting language.
cereal 1.2 3-clause BSD A serialization library supporting many target formats, both binary and human readable.
gl3w ? public domain Simple OpenGL core profile loading library.
stb_image.h 2.22 public domain / MIT Image loading library.
FreeType 2 2.? GPLv2 / FTL Font rasterization library.
OpenAL-soft ? LGPLv2 A software implementation of the OpenAL 3D audio API.
Yoga 1.19.0 MIT Layout engine implementing flexbox.

Assets

All assets that are used in the game. Some assets currently in the project are not meant to be in the final release (because of licensing problems, or simply because they do not fit the game and are just an experiment or for debugging purposes) and will soon be completely removed. Assets listed in the table below are planned for the final release.

Asset Creator License Category
16x16 Dungeon Tileset 0x72 CC-0 texture / sprite

Resources

An (incomplete) list of the resources I used in no particular order.

Website Description
learnopengl.com The main resource I used for learning (modern) OpenGL.
docs.gl Organized version of the OpenGL reference.
OpenGL Reference Pages The official OpenGL API reference.
entt wiki The entt tutorial / API reference.
ECS back and forth An ongoing series about deeper insights into the design, implementation and usage of ECS. From the author of entt.
open.gl Another resource for learning OpenGL.
Game programming patterns Learning about architectural patterns for game engines and games in general.
opengl-tutorial.org Yet another learning resource for modern OpenGL.
The book of shaders A great book for learning more about the OpenGL shading language.
Polygonizing a scalar field. The original implementation of the marching cubes algorithm.
0fps A blog covering many topics related to game programming.
glm API documentation The glm API reference.
decals Drawing decals using deferred rendering.
more decals More information about drawing decals and their weak spots.
even more decals Even more decal information.

License

I have not yet decided on a license.
The goal of this project is mostly for learning purposes, both for me and other developers in a similar position. But as this project grows, ultimately my plan is to release it as a real game for people to buy. Therefore it is still undecided how I want to handle open-source, monetization and everything related to this. Feel free to use my project as a learning resource until I come to a decision.

ecs-sandbox's People

Contributors

numpad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ecs-sandbox's Issues

Document & maintain ECS structure

Create a document/graphic/... of some sort to describe the components, systems and events used.

Per system:

  • Tick/Execution order (ExO)
  • Short description
  • Depends on other systems? [1]
  • Type (Update, Render, Event, ...)
  • Affected Components
  • Reacts to which events?

Per component:

  • Requires other component?

Per event:

  • Short description
  • Trigger condition
  • Affected systems

[1]: Is ExO important? F.ex. RenderSystem depends on data from PositionUpdateSystem, otherwise every rendering would be a frame too late.

Viewport not updating

Steps to reproduce:

  1. Start the game, the resolution will be correct at (X*Y)
  2. Make the window fullscreen, resolution will also be correct at (X2*Y2)
  3. Bring the window to the resolution (X*Y) again by leaving fullscreen, the viewport/resolution will be incorrect and only render to about half the window.

This does not seem to happen when resizing the window by changing its size, only when the resize happens instantaneously (like fullscreen, or switching between tiled and floating in bspwm)

Fix Timestep

Currently the timestep/framerate is unrestricted if vsync is disabled.
See: Fix your timestep

  • Seperate rendering and physics update
  • Add a timestep to control the game loop

Create simple Minigame

To get a real understanding what the engine currently can handle and what still needs to be done I want to create a small minigame to test its limits.

  • Two players spawn on a thin disk.
    • Players spawn
    • Players controllable
    • Players have physics & collision
    • Disk generated
  • Bombs drop in a semi-regular interval from the sky, once they touch the ground they explode and remove a bit of terrain.
    • Bombs drop
    • Bombs collide with the Terrain
    • Bombs trigger explosion event
    • Bombs explode (no VFX, just remove terrain)
  • The players can drop throught the holes. If they drop off the disk they die.
  • The last player to live wins and the game switches to the main menu.

To make it easier to develop in the beginning:

  • Players don't interact with each other.
  • The camera is fixed.
  • No UI, Menu or anything.

Some ideas to make it more interesting later on:

  • Dynamic camera, sweep around a bit based on players position, rotate around the disk.
  • Music
  • Sound effects
  • Screenshake on explosion and death.
  • Bombs don't explode immediately and can be kicked around.
  • Players can push/kick each other.
  • Items drop, once collected they make the player faster, give him a bomb to throw, give him a jump, ...
  • Particles and explosion effects.
  • Bombs are animated and grow/shrink/change color before they explode (see Minecraft TNT)
  • Gamepad support

Juice:

  • Slow motion
  • Deep zoom to player just beginning to fall

Refactor AssetManager

The current AssetManager implementation is very basic; it has subpar code quality, bad error handling/feedback and is not extremely performant.

Ideas:

  • Should be mod friendly: Open an assetmanager for a specific dir structure (like base/{images,sounds,...} and modXY/{images,...})
  • Every scene should use its own AssetManager, this way clean up is easy. Once a scene is closed the AssetManager destroys all assets used.
  • But: Engine specific stuff (like UI etc.) shouldn't need to be reloaded every time. Solution: An AssetManager can reference a parent AssetManager, if ChildAssedManager doesn't find a resource, the parent is checked.

Examine a better way to handle Assets, topics that need a rework:

  • Replace all raw with smart pointers.
  • Reimplement all assets/filetypes as generic classes.
  • Think about error handling, are nullptrs OK? Maybe default Assets are easier to handle (like Source engine). Black/Pink texture, 1s no-sound audio, Cube as default model, ...
  • Performance improvements. Dedicated functionality for preloading, store files that are already confirmed to not exist as empty instead of trying to load them everytime.
  • Memory handling. When to clean up resources?

Performance:
Currently very flexible system, f.ex. AM::getAudio() tries to return a already loaded audio, if that is not yet loaded, call ::loadAudio() and return this instead. Does this make sense performance wise or is there a better system which is still flexible enough? Switch from path to ID keys for Asset key/value pairs.

Memory handling:
Should resources be freed after not being used for a specific amount of time and no more references to it? Or on a per-scene/level basis?

Add basic scripting

  • Integrate simple scripting into map generation
  • Build on linux
  • Build on windows (postponed)

Improve terrain rendering

Triplanar rendered terrain is really simple and boring. Add paths and other features that can be added on top of the base texture at specified positions. (decal rendering?)
Per vertex specified type of terrain, so the vertex decides which texture should be used for it.

DecalRenderSystem doesn't render right texture

Steps to reproduce:

  1. Create at least 4 entities with CPosition, CDecal, COrientation with the same Texture "FOO.png"
  2. Create one or more entities with another texture "BAR.png"
  3. Bug: Now the first 3 entities should have the wrong texture "BAR.png" (spawning more decals with another texture "BAZ.png" makes the first 3 switch to "BAZ.png")

This bug seems to appear only when no previous Decals have been created and removed from the registry.

Fix terrain handling

Currently chunks are handled pretty awkwardly, Terrain is split up in too many layers of abstraction (ChunkedWorld, ChunkedTerrain, SignedDistanceTerrain, Terrain, Grid2D).
A rework of these would be great.

Props in world

Add props that are generated with the terrain to make the world more interesting.
This includes bushes and similar static models but also dynamic stuff such as tables or barrels (3d physics engine?)

Window & State/Scene handling

Add a wrapper around the base window. Abstract settings, initialization and the gameloop into it. Support for gamestates/scenes is also required to cleanly work with menu, settings, core game and so on, think of something to work with it as flexible as possible. (Pause scene overlaps the game, transition between menu > start game and the game, ...)

  • Basic window abstraction
  • Window handling
  • Scene Management

Remove position buffer

The G-buffer currently contains world space position (rgb16f) data. This is redundand as the data can be reconstructed form the depth buffer.

  • Store depth in the required format in the depth buffer
  • Calculate world space position based on these values
  • Remove position buffer completely

Additionally, by storing the world space position we will run into precision problems at some point.

  • Figure out possible problems and turn them into a separate ticket.

Overworld

Add a overworld where the player has his personal space.
features should include:

  • different buildings
  • shops
  • NPCs
  • customizable placement of those
  • stuff to do instead of fighting in the dungeon.
  • farming
  • weapon training
  • day / night cycle
  • and much more...

Fix build on Windows

Building on Windows does no longer work as of 1473c51. Find a way to build and include LuaJIT on all platforms.

Currently(?) LuaJIT is only available through vcpkg on Windows.

  • Build on Windows
  • Build on Linux

Performance optimization

Instead of depth sorting entities based on their CPosition on the CPU before rendering back-to-front we could remove the sorting and simply discard all pixels of a CBillboard which are transparent.

Pros:

  • possible performance improvement over current system [0]

Cons:

  • No more semi-transparency [1]

[0] : Still need to benchmark this on low and high end systems. But less work on the CPU would definetly be benefitial

[1] : Semi-transparency can be made possible again, but requires work (two systems, one for semi-transparent billboards and one for "fast" billboards) and coordination between those two

Add UI

We need a generic interface to work with, this should provide the foundation for:

Menu interface

  • Menus like main menu, settings menu, load game menu...
  • Loading screens

Game interface

  • Inventory (/shop) UI
  • Dialog UI

Add controller support

The game should be as accesible as possible; Controller support is a must and will become even more important once we will implement local coop.
Controller input is just as important as mouse&keyboard, maybe it will even become the preferred/recommended input method. Both Xbox and Playstation controller icons & button images are required. The correct button image should be shown even in local coop (Player1 with PS: press X to buy, Player2 with Xbox: press A to buy)

  • Basic controller support
  • Add Xbox specific buttons
  • Add Playstation specific buttons

Move sgl files from lib/ to src/

lib/ should be exclusively for stuff not developed by me. The idea was to improve and extend the sgl library in parallel to the ecs-sandbox, while it would be better practice (also for forced reusability) it is easier to just develop it as part of the ecs-sandbox ecosystem.
Think about releasing it as a separate project later once the sgl library is mature & versatile enough.

Add special rooms

Besides normal rooms in the dungeon were the player has to fight mobs/traverse traps, it would add variation to runs to include special rooms that are optional but provide the player with more stuff to do. Those rooms should be semi-randomly added (max. 1 shop per floor, ...) and only occur from time.
Ideas for rooms:

  • Shop. Buy weapons & items.
  • Bar. Buy beer & food, more expensive than shop. Drunks can maybe attack you.
  • Casino. Play blackjack, slot machines.
  • Fight club. Fight against mini-bosses for rewards.
  • Bank. Store money / an item for the next run[0]. (Costs money, maybe you get scammed, pay even more for an insurance)
  • Quest room. Gives you a random quest to do in the current floor and rewards you.
  • Clothier. Buy cosmetics. (No effect? Keep between runs?)[1]
  • Blacksmith. Buff your weapons.
  • Witch. Buy potions that buff you. (Sometimes bad luck and they give debuffs?)
  • Hospital. Pay much money to get healed. Health care system: Pay small fee each run[0] and get 1 heal for free every floor/run.[0]

[0]: Game changing meta progression. Not yet decided if this is allowed.
[1]: Cosmetic-only meta progression. This should be fine in any case.

Implement saving and loading

The player should be able to continue playing exactly where they left, this requires the whole World and everything in it (and possibly much out of the Worlds scope) to be completely serializable.

  • All components
  • All systems
  • All events (?) [1]
  • Terrain
  • Camera (?) [2]
  • AssetManager (?) [3]
  • All entities (the registry)
  • Settings (Controls, Graphics, Audio)

[1]: Does this make sense? The only case I can currently think of is enqueued events that are buffered until next frame.

[2]: This probably makes sense. Maybe for saving while in a cutscene or something similar.

[3]: Definetly makes sense, but maybe not part of AssetManager? To load all previously active Assets. Maybe this will be handled differently.

water rendering

terrain feels to simple just floating in the air, remove the void by adding a water (or something similar) plane.

Collision detection & handling

Currently there is no concept of collisions with the terrain.
Entitys should have a collider component which detects and handles collision with terrain below them. Also this should handle collisions with walls and slopes.

particle system

implement a particle system (with possible sub systems?)
Required features:

  • One shot particle burst
  • Moving particle systems with particles positioned relative to it
  • Possible collision with floor, entities (performance?)
  • Different physics types (falling down like dirt, floating up like smoke/fire, following player, trails/beams)
  • Textured dynamically (enemy explodes into many pieces)
  • In the same registry as the world?
  • Calculate physics/collision on the GPU (?)

Shader QoL improvements

Add QoL improvements for shaders. Reloading of shader sources should be possible with minimal user changes. Templating would be great, see example 1 below.

  • Better reloading (support for reload on source changed? os independant? inotify for linux?)
  • "Templating" language (inline uniforms, includes, ...)

example 1

#version 450 core
uniform sampler2D uTexture;
in vec2 vTexCoord;

out vec4 FragColor;

void main() {
  vec3 color = texture(uTexture, vTexCoord).rgb;
  // define an inline uniform. this will be initialized with the default value and can be edited with ImGui with no further changes.
  color = color * [[float:uBrightness = 1.0]]
  FragColor = vec4(color, 1.0)
}

Engine Abstractions

We need a clear line between engine and the actual game. Additionally, the main() function is huge which seems like a bad decision.

Abstract more stuff into either engine or user code.

Meta progression decision

I need to decide if the game should tend towards a more roguelike or -lite experience. Currently there is no preferred decision as both could be interesting to play, yet currently it seems to me that a roguelite is easier to design "correctly" in terms of balance and replayability.

(When I use the terms roguelike & -lite, I mostly refer to meta-progression only)

Shader reloading leaks memory

When reloading all shaders (press & hold "p"), the game begins consuming RAM.
Probably problematic: sgl::shader#link()

Inventory

Add usable inventory, this should include:

  • players inventory
  • chest inventory
  • shop inventory for buying and selling items

Items

Add a concept of items, those can be:

  • dropped into the world
  • equipped by player and NPCs
  • stacked and dragged in inventory

Consist of:

  • image
  • stack amount
  • equippable?
  • durability?
  • stats e.g. ATK, type of damage, ...
  • sell value?
  • ...

Different types of items:

  • simple items (e.g. money)
  • weapons (durability, different stats for projectile, magic or meele)
  • ammo (different kinds: arrows for bow/crossbow, stones for slingshot, etc...)
  • armor (head, body, rings, ...)
  • potions (for throwing e.g. fire potion, for consumption e.g. healing -> should give an empty bottle after being consumed)

usable billboard rendering

  • billboards with multiple textures (texture arrays?)
  • tilesets (texcoords per vertex per instance?)
  • optimized rendering/calculating of billboards (calculate rotation for all instances, position for each and write to model matrix in fragment shader?)
  • entt::groups for rendering (?)

Automatic Builds

Automatically build the project on new tags using GitHub Actions.

  • Build for Linux
  • Build for Windows
  • Investigate required stuff for OSX Builds
  • Push builds to GitHub Releases

Camera improvements

Cameras are currently not that usable, need to rethink their design and functionality/expected tasks.

  • Give cameras an (optional) framebuffer to render to?
  • Attach FBOs to them for automatic resizing?
  • Give them more functionality
  • Clean up current camera code outside of its definition (main.cpp still does much camera work)

Fix builds

Fix builds, libraries.
Currently builds are working fine on my setup. Improve this to work on all systems with the least amount of work for the end user.

  • Remove submodules
  • Fix CMakeLists.txt to use vcpkg libraries
  • Build on linux
  • Build on windows
  • Add install instructions to README.md

Decal rendering

Add support for decal rendering. Used for terrain details, blood splatters after taking damage, etc...

  • Add DecalRenderSystem
  • Render boxes in DRS
  • Render decals
  • Render a full hardcoded texture onto decals
  • Render subrects of a texture onto decals
  • Allow multiple texture sources
  • Render decals using instancing

dialog system

Player should be able to have conversations with NPCs.
Dialogs are for example:

  • simple NPC monologue
  • accepting quests from NPCs
  • Shops (with shop inventory integration)

Docker build

Provide a docker image which is capable of building the project.
Implement a CI/CD pipeline and automatically create releases when tagging a new version / merging into master.

G-buffer work

Basic deferred shading is implemented, but the current implementation is far from optimal. I need to think about the data we need in the G-buffer, how we actually lay it out to stay efficient and especially how we organize this in code.

Todo:

  • Structure G-buffer into a class (done in #56 )
  • Express shader passes and the information they share
  • Use the existing OpenGL depth buffer instead of my own
  • Remove the world position buffer, instead reconstruct it from depth buffer when needed

Challenges:

  • The G-buffer should be fairly flexible (lower graphics settings may not need a specific buffer)
  • The execution order of render passes should be more explicitly defined (?)
  • The first, basic world/entity render pass draws to the color, normal, position, depth buffers.The second decal render pass renders to color, normal buffer but requires the depth buffer. This should be handled better in code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.