Merge notes and analysis
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
Game Engine - With Mist a maze game
|
||||
|
||||
# What?
|
||||
|
||||
### The engine
|
||||
|
||||
- A high performance - low level game engine that provides abstactions for 2d games to be built on.
|
||||
|
||||
- A scene system
|
||||
- A scene is a set of scene elements used to create it,
|
||||
- For example, a scene for menu, for game over screen, and most importantly, for the main game scene.
|
||||
- A scene element can be one of,
|
||||
- A basic geometric shape
|
||||
- A text, with localization codes and text db
|
||||
- An image
|
||||
- A game world
|
||||
- A scripted element, for stuff like minimaps
|
||||
- each element has coordinates on screen and z ordering.
|
||||
- And they can handle clicks / keyboard events and have scripts attached to each.
|
||||
|
||||
- The bus
|
||||
- any event can be fired on the bus by any object and then used by other objects for actions like enemy attacking player or something,
|
||||
- they can be scoped with lifetime rules for tighter control and avoiding a event mess
|
||||
|
||||
- A game world is just the game world (everything is coordinates in the world map relative, and this object controls the camera), \
|
||||
and it can be defined as topdown or side (for z ordering rules).
|
||||
- everything is an entity
|
||||
- with specail entities for tiling spritesheets where a set of tiles can be defined and the engine will place the right kind of tile based on the scenario \
|
||||
(for example in a maze if i define a spritesheet with tiles for corner / edge peices and then tell the maze as a grid of cells with 1 for wall and 0 \
|
||||
for empty it will automatically place the correct tile from that list.)
|
||||
- and support for maze generation and solving algorithms, which can be used with tiling entity to create maze maps but also just usable for anything.
|
||||
|
||||
- Every entity is just a set of components added to it to form something in a game "world"
|
||||
- An entity joins together components to create an entity
|
||||
- Components are:
|
||||
1. Body
|
||||
- Shape (Dynamic or static)
|
||||
- Mass, physics interactions
|
||||
- Coordinates
|
||||
2. Spritesheet (state based or singleton)/(animated or static)
|
||||
- State based is for like player sprite can switch between states like facing direction etc.
|
||||
- It will have an api to load and manage game sprites with animations handled automatically.
|
||||
- The developer can define sprite locations for static and for dynamic a list of files or pixel \
|
||||
areas within a bitmap image for each animation frame and the fps of the animation.
|
||||
3. Render, only for those that dont use a Spritesheet
|
||||
- Can be used for rendering a box or other simple shapes / text for fine grained control, this is automatically handled if a spritesheet exists.
|
||||
4. Controlles
|
||||
- Can be used to connect a script to run on every game loop for this object (delta based)
|
||||
- Event Subscription
|
||||
- Can be used to subscribe to global / scoped events in the game event bus. (input can be handled through this or in update)
|
||||
5. Light
|
||||
- Light level info for fog light shader
|
||||
- In debug mode the collisions will be visible and other info like coords etc. logged for that game "world"
|
||||
|
||||
- It will have a physics engine for physics calculations like collisions, velocity, friction, forces, los, etc. attached to the game world
|
||||
- It applies to all objects with collision bodies
|
||||
- It has a center property that explains where the objects center is relative to the shape, and the size of the shape
|
||||
- it has a mass which shows its inertia
|
||||
- And they can be static or dynamic, rigid is used for walls and dynamic is for player / enemies etc. \
|
||||
with an api to simulate a force on a dynamic object, with collision handling with other static objects to stop it and with other dynamic \
|
||||
objects for firing collision events (for exmple checking if player collides with enemy)
|
||||
- it also has setting for adding gravity (added for side view games.), or defining friction force relative to a coefficient defined per object for texturing.
|
||||
- Calculations for interacting these objects in the world and updating their positions based on velocity / forces each game loop.
|
||||
|
||||
- Lighting support for fog based systems and shaders for common scenarios like clouds / fog and api to create custom shaders
|
||||
- A light system to render torches/light systems
|
||||
- With api to implement shaders for special effects
|
||||
- These are GPU accelerated shaders
|
||||
- owned by world
|
||||
|
||||
- An api for game "world" persistence. and generic data store.
|
||||
|
||||
- Normal classes / logic can be written outside and reused in the system.
|
||||
|
||||
- The scripting is done in mruby with most common ruby gems available. (the actual project will be in c++)
|
||||
- The scene can be defined and setup in a markup-style custom ruby DSL.
|
||||
|
||||
- And special predefined scenes for menu / settings types with settings having predefined settings for keybinds used.
|
||||
- And the godot style project settings where we can define key value pairs with datatype for value that can be used as globals. \
|
||||
and interfaced through autogenerated settings scene, or hidden but used as globals internally.
|
||||
|
||||
- And as a sample game implemented using it I will make mist.
|
||||
|
||||
### Mist - A maze game
|
||||
|
||||
- The main focus of the game is to show off all features of this engine.
|
||||
- It also focuses on maze generation and solving with choices to select different types of maze generation algorithms and solving ai for npc's
|
||||
- The main game has 4 modes
|
||||
1. _Classic_ - A finite maze is generated on world creation and player has to fight enemies, collect resources / weapons and find the exit to win
|
||||
2. _Tutorial_ - A smaller map with basic elements and npc's for player to inteact with and tooltips for helping them learn how the game works
|
||||
3. _Infinite_ - A maze is procedurally generated as the player walks using predefined seeds and memory optimizations to allow storing such information, \
|
||||
the goal is to get as far from spawn as possible without dying.
|
||||
4. _Editor Mode_ - A mode in which teh user controls the map itself and can test out various maze generation algorithms and place npcs / rooms and tweak \
|
||||
game rules to create custom game scenarios.
|
||||
|
||||
# Who?
|
||||
|
||||
- This game engine is targeted towards basic to intermediate indie developers trying out 2d game development for 2d open world like scenarios with \
|
||||
physics etc. (in both topdown or side view mode)
|
||||
- They can use the scene editor to make scene setups for all the visible stuff in teh game and then write scripts for behaviour of it using ruby syntax, \
|
||||
which is a high level OOP interpreted langauge with a low learning curve due to its simple to learn syntax, and tons of helper functions for rapid development.
|
||||
- It could be used by educators for teaching game development basics to students and getting hands on experience.
|
||||
- This engine also indirectly effects the gamers, the end users as they are the ones to feel any performance costs when enjoying the games.
|
||||
+190
-55
@@ -196,49 +196,11 @@ we'll be splitting the survey into 2 sections, one for indie developers and one
|
||||
|
||||
## Results
|
||||
|
||||
Summarization of survey results and its limitations
|
||||
Summarization of survey results / not done yet as not enought data collected.
|
||||
|
||||
## What more is needed?
|
||||
### Limitations
|
||||
|
||||
Other features that a game engine should have
|
||||
|
||||
core:
|
||||
|
||||
- app, defined with fixed heght/width and aspect ratio is maintained with letterboxing, and fps
|
||||
|
||||
- scenes
|
||||
- elements in scenes (in screen coordinates)
|
||||
- ElementText
|
||||
- ElementRect
|
||||
- ElementImage
|
||||
- ElementWorld - (It is a view through a camera)
|
||||
|
||||
- The world has to have an ecs system buitl in it
|
||||
- components are type definitions (and thier instances are stored in cache efficient arrays)
|
||||
- systems use queries to select components (with filtering) and can perform bulk operations on them
|
||||
- entities - an id and position which can relate to compoenent instances
|
||||
|
||||
- The world can render everything in view based on camera, and everything inside here is in world coordinates
|
||||
|
||||
- shaders, layers on top of the world, (per world, not possible per entity)
|
||||
|
||||
extra:
|
||||
|
||||
- physics (forces, mass, movement and collisions)
|
||||
- Localization
|
||||
- keymappings (and settings)
|
||||
- tilesets
|
||||
- sprite system (tiled, animated, static etc.)
|
||||
- 9 segment ui system
|
||||
- audio playing
|
||||
- network interface, with a lib to stream data rom & a server instance also built into the packer binary (should allow ruby scripting the backend)
|
||||
- persistence store
|
||||
- rng helpers
|
||||
- tweening helpers
|
||||
- layout system (with tree like grouping of elements that inherit transform of parent)
|
||||
- video player (ffmpeg texture and audio streams) (requires ffmpeg at runtime)
|
||||
|
||||
- super simple neural network system (with training and runtime phases) (if i have enough time)
|
||||
(of the results)
|
||||
|
||||
## Hardware
|
||||
|
||||
@@ -251,20 +213,135 @@ for software make sure it works on linux and make it theoretically work on other
|
||||
|
||||
#### why use a rendering lib
|
||||
|
||||
(source an article on setting up windows for x11/wayland/windows api)
|
||||
To set up and render something to the screen in the first place we need a system to be able to do so.
|
||||
|
||||
I plan of supporting development for windows/linux where linux has 2 main systems for window management (X11 / wayland).
|
||||
|
||||
Which means if i were to build for those i'd have to learn the protocol and methods of setting up/doing window actions like input/screen rendering for each of these systems seperately.
|
||||
But each of these systems have different interfaces:
|
||||
|
||||
But if i instead use a library that automatically detects and uses the appropriate system on the device without hardcoding the protocol manually, it would make building the core process of teh project far simpler instead of wasting time building seperate rendering systems for each of these manually.
|
||||
For example this is how the api works on windows:
|
||||
|
||||
```c
|
||||
// Register the window class.
|
||||
const wchar_t CLASS_NAME[] = L"Sample Window Class";
|
||||
|
||||
WNDCLASS wc = { };
|
||||
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = CLASS_NAME;
|
||||
|
||||
RegisterClass(&wc);
|
||||
|
||||
// Create the window.
|
||||
|
||||
HWND hwnd = CreateWindowEx(
|
||||
0, // Optional window styles.
|
||||
CLASS_NAME, // Window class
|
||||
L"Learn to Program Windows", // Window text
|
||||
WS_OVERLAPPEDWINDOW, // Window style
|
||||
|
||||
// Size and position
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
|
||||
NULL, // Parent window
|
||||
NULL, // Menu
|
||||
hInstance, // Instance handle
|
||||
NULL // Additional application data
|
||||
);
|
||||
|
||||
if (hwnd == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
```
|
||||
|
||||
source: https://learn.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window
|
||||
|
||||
x11:
|
||||
|
||||
```c
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
bool quited = false;
|
||||
|
||||
void on_delete(Display * display, Window window)
|
||||
{
|
||||
XDestroyWindow(display, window);
|
||||
quited = true;
|
||||
}
|
||||
|
||||
extern int main(int argc, char *argv[])
|
||||
{
|
||||
Display * display = XOpenDisplay(NULL);
|
||||
if (NULL == display) {
|
||||
fprintf(stderr, "Failed to initialize display");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Window root = DefaultRootWindow(display);
|
||||
if (None == root) {
|
||||
fprintf(stderr, "No root window found");
|
||||
XCloseDisplay(display);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Window window = XCreateSimpleWindow(display, root, 0, 0, 800, 600, 0, 0, 0xffffffff);
|
||||
if (None == window) {
|
||||
fprintf(stderr, "Failed to create window");
|
||||
XCloseDisplay(display);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
XMapWindow(display, window);
|
||||
|
||||
Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(display, window, & wm_delete_window, 1);
|
||||
|
||||
XEvent event;
|
||||
while (!quited) {
|
||||
XNextEvent(display, &event);
|
||||
|
||||
switch(event.type) {
|
||||
case ClientMessage:
|
||||
if(event.xclient.data.l[0] == wm_delete_window) {
|
||||
on_delete(event.xclient.display, event.xclient.window);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
source: https://gist.github.com/m1nuz/8f8f10a7f8715b62fe79#file-simple-x11-window-c
|
||||
|
||||
wayland:
|
||||
|
||||
https://github.com/zezba9000/WaylandClientWindow
|
||||
https://wayland-book.com/protocol-design/wire-protocol.html
|
||||
As wayland is much more structured as a protocol than just a library setting a window up for it requires much more boilerplate if done from scratch.
|
||||
And it requires much more in depth knowledge of how the protocol works, which would be out of the scope of what this project aims for.
|
||||
|
||||
As you can see each one has a vastly different setup and hardcoding each one manually would take time and focus away from more neccessary parts of the project.
|
||||
|
||||
But if i instead use a library that automatically detects and uses the appropriate system on the device, it would make building the core process of the project far simpler instead of wasting time building seperate rendering systems for each of these manually.
|
||||
|
||||
#### why use SDL3 / what options there are
|
||||
|
||||
- raylib vs sdl - https://gist.github.com/raysan5/17392498d40e2cb281f5d09c0a4bf798
|
||||
- & glfw
|
||||
|
||||
(industry standard)
|
||||
|
||||
#### SDL_TTF and SDL_Image & SDL_mixer / why i use them
|
||||
|
||||
(talk about custom harbuzz / open type fonts setup and hwo it is much more complicated than using such a library that simplifies it.)
|
||||
@@ -333,23 +410,24 @@ The engine could compile the developers scripts into mruby bytecode when buildin
|
||||
|
||||
## Requirements
|
||||
|
||||
- then a draft of the requirements with justification of each based on the previous sections, along with information on how id use a seperate packer system
|
||||
- App, defined with fixed heght/width and aspect ratio is maintained with letterboxing, and fps
|
||||
|
||||
Requirements v1:
|
||||
|
||||
- A game loop capable of handling any max fps given to it.
|
||||
- A scene system
|
||||
- A scene is a set of scene elements used to create it,
|
||||
- For example, a scene for menu, for game over screen, and most importantly, for the main game scene.
|
||||
- A scene element can be one of,
|
||||
- A rectangle
|
||||
- A text
|
||||
- A text, with localization codes and text db
|
||||
- An image
|
||||
- A game world
|
||||
- A pixel scripted element, for stuff like minimaps (called Surface).
|
||||
- A sdl command batch element, for something that batches a bunch of image/rect/text into one element. (Called Render)
|
||||
- A scripted element, for stuff like minimaps
|
||||
- each element has coordinates on screen and z ordering.
|
||||
- And they can handle clicks / keyboard events and have scripts attached to each or the scene itself.
|
||||
- And they can handle clicks / keyboard events and have scripts attached to each.
|
||||
|
||||
- The bus
|
||||
- any event can be fired on the bus by any object and then used by other objects for actions like enemy attacking player or something,
|
||||
- they can be scoped with lifetime rules for tighter control and avoiding a event mess
|
||||
|
||||
- A game world is just the game world (everything is coordinates in the world map relative, and this object controls the camera), \
|
||||
and it can be defined as topdown or side (for z ordering rules).
|
||||
- everything is an entity
|
||||
@@ -358,9 +436,66 @@ Requirements v1:
|
||||
for empty it will automatically place the correct tile from that list.)
|
||||
- and support for maze generation and solving algorithms, which can be used with tiling entity to create maze maps but also just usable for anything.
|
||||
|
||||
##
|
||||
- Every entity is just a set of components added to it to form something in a game "world"
|
||||
- An entity joins together components to create an entity
|
||||
- Components are:
|
||||
1. Body
|
||||
- Shape (Dynamic or static)
|
||||
- Mass, physics interactions
|
||||
- Coordinates
|
||||
2. Spritesheet (state based or singleton)/(animated or static)
|
||||
- State based is for like player sprite can switch between states like facing direction etc.
|
||||
- It will have an api to load and manage game sprites with animations handled automatically.
|
||||
- The developer can define sprite locations for static and for dynamic a list of files or pixel \
|
||||
areas within a bitmap image for each animation frame and the fps of the animation.
|
||||
3. Render, only for those that dont use a Spritesheet
|
||||
- Can be used for rendering a box or other simple shapes / text for fine grained control, this is automatically handled if a spritesheet exists.
|
||||
5. Light
|
||||
- Light level info for fog light shader
|
||||
- In debug mode the collisions will be visible and other info like coords etc. logged for that game "world"
|
||||
- Systems are scripts run every game loop on a set of entities (or globally) based on queries.
|
||||
|
||||
- It will have a physics engine for physics calculations like collisions, velocity, friction, forces, los, etc. attached to the game world
|
||||
- It applies to all objects with collision bodies
|
||||
- It has a center property that explains where the objects center is relative to the shape, and the size of the shape
|
||||
- it has a mass which shows its inertia
|
||||
- And they can be static or dynamic, rigid is used for walls and dynamic is for player / enemies etc. \
|
||||
with an api to simulate a force on a dynamic object, with collision handling with other static objects to stop it and with other dynamic \
|
||||
objects for firing collision events (for exmple checking if player collides with enemy)
|
||||
- it also has setting for adding gravity (added for side view games.), or defining friction force relative to a coefficient defined per object for texturing.
|
||||
- Calculations for interacting these objects in the world and updating their positions based on velocity / forces each game loop.
|
||||
|
||||
- Lighting support for fog based systems and shaders for common scenarios like clouds / fog and api to create custom shaders
|
||||
- A light system to render torches/light systems
|
||||
- With api to implement shaders for special effects
|
||||
- These are GPU accelerated shaders
|
||||
- owned by world
|
||||
- shaders, layers on top of the world, (per world, not possible per entity)
|
||||
|
||||
- An api for game "world" persistence. and generic data store.
|
||||
|
||||
- Normal classes / logic can be written outside and reused in the system.
|
||||
|
||||
- And special predefined scenes for menu / settings types with settings having predefined settings for keybinds used.
|
||||
- And the godot style project settings where we can define key value pairs with datatype for value that can be used as globals. \
|
||||
and interfaced through autogenerated settings scene, or hidden but used as globals internally.
|
||||
|
||||
- Extra useful features:
|
||||
|
||||
- Localization
|
||||
- keymapping system (and settings)
|
||||
- tilesets
|
||||
- sprite system (tiled, animated, static etc.)
|
||||
- 9 segment ui system
|
||||
- audio playing
|
||||
- network interface, with a lib to stream data rom & a server instance also built into the packer binary (should allow scripting the backend)
|
||||
- rng helpers
|
||||
- tweening helpers
|
||||
- layout system (with tree like grouping of elements that inherit transform of parent)
|
||||
- video player (ffmpeg texture and audio streams) (requires ffmpeg at runtime)
|
||||
|
||||
###
|
||||
|
||||
- then any limitations / problems that can arise with the choices in this list and how i might tackle them or ignore them
|
||||
- personal limitations, time, and in contrast my skill level and how it should be a breeze fo rmy level
|
||||
|
||||
- then define success criteria for major bits in the requirements as a final list then switch over to design stage
|
||||
- then define success criteria for major bits in the requirements as a final list (ie. how do i decide it that point is ticked off)
|
||||
|
||||
Reference in New Issue
Block a user