From c1c0df012141d1d9c8646e803238e5ea535ae9ce Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Fri, 4 Oct 2024 10:32:28 +0200 Subject: added gameloop subsection and intro --- design.tex | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'design.tex') diff --git a/design.tex b/design.tex index 1e42c03..f786f40 100644 --- a/design.tex +++ b/design.tex @@ -25,6 +25,17 @@ workflows. \section{Overview} \subsection{Core} +\subsubsection{Game Loop} +Problem Statement\ + +In the context of game development, a robust game loop is essential for maintaining consistent gameplay and ensuring that game logic, physics, and rendering are executed in a synchronized manner. Without a well-defined game loop, issues such as inconsistent frame rates, unresponsive input handling, and unpredictable behavior can arise, leading to a poor user experience. Therefore, the implementation of a game loop within a game engine is crucial for providing a stable foundation upon which game developers can build their projects. +Game Loop Design\ + +The game loop is integrated directly into the engine to streamline development and minimize timing issues for game developers. Two separate update functions are employed. A fixed-time update is used with a consistent time delay per update call for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. By performing physics calculations at regular intervals, game logic and physics are decoupled from frame rate, ensuring consistent behavior across different hardware. + +Rendering and animations are handled separately on a per-frame basis. +A delay and delta time calculation are applied to create consitent visual behavior, even when frame rates vary. +This separation between game logic and rendering ensures that both simulation accuracy and visual fluidity are optimized. \subsection{Patterns} -- cgit v1.2.3 From da846dea2906ae2395ebc6351cae1ca8f8d3313b Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Wed, 23 Oct 2024 21:17:26 +0200 Subject: made changes to introduction gameloop --- design.tex | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'design.tex') diff --git a/design.tex b/design.tex index 587174f..4642f0c 100644 --- a/design.tex +++ b/design.tex @@ -28,10 +28,15 @@ workflows. \subsubsection{Game Loop} Problem Statement\ -In the context of game development, a robust game loop is essential for maintaining consistent gameplay and ensuring that game logic, physics, and rendering are executed in a synchronized manner. Without a well-defined game loop, issues such as inconsistent frame rates, unresponsive input handling, and unpredictable behavior can arise, leading to a poor user experience. Therefore, the implementation of a game loop within a game engine is crucial for providing a stable foundation upon which game developers can build their projects. +In the context of game development, a robust game loop is essential for maintaining consistent gameplay and ensuring that game logic, physics, and rendering are executed in a synchronized manner. +Without a well-defined game loop, issues such as inconsistent frame rates, unresponsive input handling, and unpredictable behavior can arise, leading to a poor user experience. +Therefore, the implementation of a game loop within a game engine is crucial for providing a stable foundation upon which game developers can build their projects./ + Game Loop Design\ -The game loop is integrated directly into the engine to streamline development and minimize timing issues for game developers. Two separate update functions are employed. A fixed-time update is used with a consistent time delay per update call for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. By performing physics calculations at regular intervals, game logic and physics are decoupled from frame rate, ensuring consistent behavior across different hardware. +The game loop is integrated directly into the engine to streamline development and minimize timing issues for game developers. +Two separate update functions are employed. A fixed-time update is used with a consistent time delay per update call for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. +By performing physics calculations at regular intervals, game logic and physics are decoupled from frame rate, ensuring consistent behavior across different hardware. Rendering and animations are handled separately on a per-frame basis. A delay and delta time calculation are applied to create consitent visual behavior, even when frame rates vary. -- cgit v1.2.3 From cf7a38d87164a9be78efd8c045acd43422a1be04 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 26 Oct 2024 08:51:31 +0200 Subject: design gameloop, design --- design.tex | 55 +++++++++++++++++++++++++++++++++++------------ img/event-uml.drawio.png | Bin 0 -> 217362 bytes img/gameloop-class.puml | 35 ++++++++++++++++++++++++++++++ img/gameloop-flow.puml | 27 +++++++++++++++++++++++ 4 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 img/event-uml.drawio.png create mode 100644 img/gameloop-class.puml create mode 100644 img/gameloop-flow.puml (limited to 'design.tex') diff --git a/design.tex b/design.tex index 0457d8b..6b936a1 100644 --- a/design.tex +++ b/design.tex @@ -25,27 +25,53 @@ workflows. \section{Overview} \subsection{Core} -\subsubsection{Game Loop} -Problem Statement\ -In the context of game development, a robust game loop is essential for maintaining consistent gameplay and ensuring that game logic, physics, and rendering are executed in a synchronized manner. -Without a well-defined game loop, issues such as inconsistent frame rates, unresponsive input handling, and unpredictable behavior can arise, leading to a poor user experience. -Therefore, the implementation of a game loop within a game engine is crucial for providing a stable foundation upon which game developers can build their projects./ +\subsection{Patterns} -Game Loop Design\ +\section{Design} +\subsection{Game Loop} +\subsubsection{Problem statement:} +The game loop is integrated into the engine to simplify development and minimize timing issues. By embedding the game loop within the engine, uniform execution of engine systems is ensured. +Two separate update functions are employed: a fixed-time update with a consistent time delay per call is used for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. +This approach decouples physics calculations from the frame rate, allowing consistent behavior across different hardware configurations. +\subsubsection{Design:} +As illustrated in Figure \ref{gameloop-flow}, the game loop continues to call the fixed update function as long as sufficient time is available. +Delta time, calculated using the time between the start of the last frame and the current frame, is used to measure the duration of each frame. This value is converted into a time-based unit, enabling other systems or game developers to create behavior independent of frame rate. + +Rendering and animations are handled separately on a per-frame basis. A delay, in conjunction with the delta time calculation, is applied to maintain consistent visual behavior, even when frame rates vary. This separation of game logic from rendering ensures that both simulation accuracy and visual fluidity are optimized. +As seen in figure Figure \ref{gameloop-class} to access the deltaTime anywhere in the system a timerClass is created using a singleton desing pattern which ensures only one instance of the class is created; the gameloop updates the timing and delta time of this class to ensure it is accurate. +The gameloops two main functions are the setup() and loop(). The first is called when the game starts and handles all startup procedures this function only runs once. +The loop() function keeps looping as long as the game is running. Within this function are the functions: processInputs for handling user input(mouse,keyboard,other controllers),fixed update,frame update and render function. +\begin{figure} + \centering + \includepumldiag{img/gameloop-flow.puml} + \caption{Gameloop Flowchart Diagram} \label{gameloop-flow} +\end{figure} -The game loop is integrated directly into the engine to streamline development and minimize timing issues for game developers. -Two separate update functions are employed. A fixed-time update is used with a consistent time delay per update call for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. -By performing physics calculations at regular intervals, game logic and physics are decoupled from frame rate, ensuring consistent behavior across different hardware. +\begin{figure} + \centering + \includepumldiag{img/gameloop-class.puml} + \caption{Gameloop Flowchart Diagram} \label{gameloop-class} +\end{figure} +\subsection{Event system} +\subsubsection{Problem statement:} +\subsubsection{Problem Statement:} +The game engine utilizes the Entity-Component-System (ECS) architecture, where components store data, and systems process that data to apply changes. Each system is responsible for managing a specific domain, such as physics in the physics system and rendering in the rendering system. To facilitate communication between systems without introducing direct dependencies, a method of inter-system communication is required to maintain loose coupling. -Rendering and animations are handled separately on a per-frame basis. -A delay and delta time calculation are applied to create consitent visual behavior, even when frame rates vary. -This separation between game logic and rendering ensures that both simulation accuracy and visual fluidity are optimized. +Additionally, a mechanism that allows one object's trigger to elicit responses from multiple other objects is beneficial for game developers, providing greater flexibility in designing interactions within the game. -\subsection{Patterns} +\subsubsection{Design:} +The solution to the aforementioned problems is an event system that facilitates communication between systems and utilizes BehaviorScripts to handle various types of events. The event system includes several pre-defined events, all derived from a parent Event class, capable of handling user input and application-level events, such as window resizing. -\section{Design} +Furthermore, a specific event is designated for the collision handler within the physics system, which can be triggered when two objects collide. The event system also allows developers to create custom events, such as "onPlayerDeath," and assign callback functions that execute when the event is triggered. +When such an event occurs, the EventManager calls the assigned callback function, executing the associated code to handle the event's consequences +\begin{figure} + \centering + \includegraphics[width=\linewidth]{img/event-uml.drawio.png} % or specify a custom width + \caption{event system class diagram} + \label{fig:event-uml} +\end{figure} \subsection{Rendering} \subsection{Physics} @@ -204,6 +230,7 @@ contains the following classes: \subsection{Physics} + \section{Tools} \section{Conclusion} diff --git a/img/event-uml.drawio.png b/img/event-uml.drawio.png new file mode 100644 index 0000000..9eab458 Binary files /dev/null and b/img/event-uml.drawio.png differ diff --git a/img/gameloop-class.puml b/img/gameloop-class.puml new file mode 100644 index 0000000..c9d7917 --- /dev/null +++ b/img/gameloop-class.puml @@ -0,0 +1,35 @@ +@startuml +class LoopManager { + +static LoopManager& getInstance() + + +void loop() + +void setup() + -void render() + -void processInput() + -void fixedUpdate() + -void update() + -bool gameRunning + -LoopManager() +} + +class LoopTimer { + +static LoopTimer& getInstance() + +void start() + +void update() + +float getLag() + +float getFixedDeltaTime() + +void advanceFixedUpdate() + +void enforceFrameRate() + +float getDeltaTime() + -float lag + -float fixedDeltaTime + -float deltaTime +} + +LoopManager --> LoopTimer : uses +LoopManager : loop() +LoopManager : |-- processInput() +LoopManager : |-- fixedUpdate() +LoopManager : |-- update() +LoopManager : |-- render() +@enduml diff --git a/img/gameloop-flow.puml b/img/gameloop-flow.puml new file mode 100644 index 0000000..1a46cd7 --- /dev/null +++ b/img/gameloop-flow.puml @@ -0,0 +1,27 @@ +@startuml +title Game Loop Flowchart + +start + +:Initialize LoopManager; +:Start LoopTimer; + +repeat + :Update LoopTimer; + :Check for Events; + :Process Input; + + while (Lag >= Fixed Delta Time?) is (yes) + :Perform Fixed Update; + :Advance Fixed Update; + endwhile + + :Perform Normal Update; + :Render Frame; + +repeat while (Game Running?) + +:Game exit logic; + +stop +@enduml -- cgit v1.2.3 From 0bed01a4e2e820b8974207145cd2eb3430864ad7 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 2 Nov 2024 20:54:17 +0100 Subject: eerste opzet --- design.tex | 105 ++++++++++++++++++++++++++++++++++++++---------- img/event-sequence.puml | 16 ++++++++ 2 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 img/event-sequence.puml (limited to 'design.tex') diff --git a/design.tex b/design.tex index 4e46388..131031f 100644 --- a/design.tex +++ b/design.tex @@ -116,17 +116,49 @@ the main part of the \gls{ecs}. The design of these eight systems in combination \section{Design} \subsection{Game Loop} \subsubsection{Problem statement:} -The game loop is integrated into the engine to simplify development and minimize timing issues. By embedding the game loop within the engine, uniform execution of engine systems is ensured. -Two separate update functions are employed: a fixed-time update with a consistent time delay per call is used for game logic and physics, ensuring predictable behavior regardless of fluctuations in frame rates. -This approach decouples physics calculations from the frame rate, allowing consistent behavior across different hardware configurations. +A game loop is essential for maintaining a continuous flow of game actions, ensuring that updates to game logic, physics, and rendering occur in a synchronized manner. Without a game loop, the game would lack consistent timing and leading to unpredictable behavior. +The game loop is mainly responsible for these 2 purposes: +\begin{itemize} + \item Updating all systems in the correct order. + \item Making sure the gameloop timer is up to date +\end{itemize} +The game loop can be external where the user has the ability to update the systems themselves or an intergrated game loop which is managed by the gameloop. +Both of these approaches have advantages and disadvantages when it comes to flexibility and reliability. + + \subsubsection{Design:} -As illustrated in Figure \ref{gameloop-flow}, the game loop continues to call the fixed update function as long as sufficient time is available. -Delta time, calculated using the time between the start of the last frame and the current frame, is used to measure the duration of each frame. This value is converted into a time-based unit, enabling other systems or game developers to create behavior independent of frame rate. +The game loop of this engine is integrated into the engine, this is done for the following reasons: +\begin{itemize} + \item \emph{Simplify development} The user only has to call startGame(). + \item \emph{Uniform system calls} The systems are always updated in the same order limiting overwrites and undefined system behavior. + \item \emph{Reliable timer update} Each cycle the game loop timer is always updated limiting timing issues. +\end{itemize} +As seen in figure \ref{gameloop-flow} the gameloop is divided into different steps. +\begin{itemize} + \item \emph{Update loop timer} The loop timer gets updated and the expected frame time is calculated. + \item \emph{Check events} Queued events get dispatched and callback functions are handled acordingly. + \item \emph{Process input} The input system is called and user input is processed. + \item \emph{Fixed update} A fixed loop for timing sensitive systems such as physics. + \item \emph{Update} A per frame update for all per frame updates. + \item \emph{Render} Calling the render system to render the frame. +\end{itemize} +This is done as illustrated in Figure \ref{gameloop-flow}, the game loop continues to call the fixed update function as long as sufficient time is available. +Delta time, calculated using the time between the start of the last frame and the current frame, is used to measure the duration of each frame. +This value is converted into a time-based unit, enabling other systems or game developers to create behavior independent of frame rate. -Rendering and animations are handled separately on a per-frame basis. A delay, in conjunction with the delta time calculation, is applied to maintain consistent visual behavior, even when frame rates vary. This separation of game logic from rendering ensures that both simulation accuracy and visual fluidity are optimized. +Rendering and animations are handled separately on a per-frame basis. A delay, in conjunction with the delta time calculation, +is applied to maintain consistent visual behavior, even when frame rates vary. As seen in figure Figure \ref{gameloop-class} to access the deltaTime anywhere in the system a timerClass is created using a singleton desing pattern which ensures only one instance of the class is created; the gameloop updates the timing and delta time of this class to ensure it is accurate. The gameloops two main functions are the setup() and loop(). The first is called when the game starts and handles all startup procedures this function only runs once. -The loop() function keeps looping as long as the game is running. Within this function are the functions: processInputs for handling user input(mouse,keyboard,other controllers),fixed update,frame update and render function. +The loop() function keeps looping as long as the game is running. +The gamedeveloper start the game engine/game using the code example below: +\begin{blockcode} + Gameloop loop; + loop.start(); +\end{blockcode} +This starts calls the setup() and loop() functions and starts the game loop timer; +To get the current frames Delta time \codeinline{LoopTimer::getInstance().getDeltaTime()} can be used which will return the expected frame time. + \begin{figure} \centering \includepumldiag{img/gameloop-flow.puml} @@ -139,28 +171,59 @@ The loop() function keeps looping as long as the game is running. Within this fu \caption{Gameloop Flowchart Diagram} \label{gameloop-class} \end{figure} \subsection{Event system} -\subsubsection{Problem statement:} \subsubsection{Problem Statement:} -The game engine utilizes the Entity-Component-System (ECS) architecture, where components store data, and systems process that data to apply changes. Each system is responsible for managing a specific domain, such as physics in the physics system and rendering in the rendering system. To facilitate communication between systems without introducing direct dependencies, a method of inter-system communication is required to maintain loose coupling. - -Additionally, a mechanism that allows one object's trigger to elicit responses from multiple other objects is beneficial for game developers, providing greater flexibility in designing interactions within the game. - -\subsubsection{Design:} -The solution to the aforementioned problems is an event system that facilitates communication between systems and utilizes BehaviorScripts to handle various types of events. The event system includes several pre-defined events, all derived from a parent Event class, capable of handling user input and application-level events, such as window resizing. - -Furthermore, a specific event is designated for the collision handler within the physics system, which can be triggered when two objects collide. The event system also allows developers to create custom events, such as "onPlayerDeath," and assign callback functions that execute when the event is triggered. - -When such an event occurs, the EventManager calls the assigned callback function, executing the associated code to handle the event's consequences +The game engine utilizes the Entity-Component-System (ECS) architecture, where components store data, +and systems process that data to apply changes. Each system is responsible for managing a specific domain, +such as physics in the physics system and rendering in the rendering system. +To facilitate communication between systems without introducing direct dependencies, +a method of inter-system communication is required to maintain loose coupling. +Additionally, a mechanism that allows one object's trigger to manipulate adn affect multiple other objects is beneficial for game developers, providing greater flexibility in designing interactions within the game. + + +\subsubsection{Architecture:} +The sollution to connect the various systems and BehaviorScripts together without inducing high coupling is an event system that facilitates communication between systems and BehaviorScripts using various types of events. +The event system includes several pre-defined events, all derived from a parent Event class, capable of handling user input and application-level events, such as window resizing. +Furthermore, a specific event is designated for the collision handler within the physics system, which can be triggered when two objects collide. +The event system also allows developers to create custom events, such as "onPlayerDeath," and assign callback functions that execute when the event is triggered. \begin{figure} \centering - \includegraphics[width=\linewidth]{img/event-uml.drawio.png} % or specify a custom width + \includegraphics[width=\linewidth]{img/event-uml.drawio.png} \caption{event system class diagram} \label{fig:event-uml} \end{figure} -\subsection{Rendering} +the event system as seen in \ref{fig:event-uml} includes several parts such as: +\begin{description} + \item[eventManager] The manager has the functions to subscribe/trigger/queue/dispatch events. It also stores all callback functions corresponding to specific event. + The manager is a singleton and can therefor only exist once so all events are stored in one place. + \item[IEventWrapper] This is a EventWrapper \emph{interface} which is used to store all the different templated eventshandlers in one map in the event manager. + this wrapper contains the logic to convert the parent class \emph{event} to the correct subclasses. It also contains a variable onSuccessDestroy which can be set to destroy the callback call onces completed. + This can be used to make a one time only event. + \item[Event] This is the parent class where all specific event classes are derived from. Each event contains a + \begin{itemize} + \item \emph{\codeinline{static std::uint32_t getStaticEventType()}} to set type during compiling. + \item \emph{\codeinline{virtual std::uint32_t getEventType() const override }} function to manage the type conversion during runtime. + \end{itemize} + Other functions can be freely added when creating a custom function. + When an event is triggered a specific derived class must be used to indicate which event is triggered. A reference to this event is then transfered to all callback functions subscribed. +\end{description} +The EventManager is a singleton so all all callbacks are stored in one place and it can be called everywhere in the system or game. +The user can use the EventManager for the following functions: +\begin{itemize} + \item \emph{Subscribe:} This subscribes a function pointer or lambda function to a given event. The function can be subscribed either to all event triggers or a specifc ID. + \item \emph{Trigger:} This triggers a given event and all callbacks correlating to this event are executed immediately. + \item \emph{Queue event:} This queues an event to be executed at a fixed time during the gameloop. + \item \emph{Unsubscibe:} This removes the callback function from the event and it will no longer be executed. +\end{itemize} +Figure \ref{fig:event-seq} shows that when a specific function is triggered or dispatched using the callback(eventHandler) is executed. +\begin{figure} + \centering + \includepumldiag{img/event-sequence.puml} + \caption{Sequence diagram for event calling} + \label{fig:event-seq} +\end{figure} % \subsection{Physics} - +\subsection{Rendering} \subsection{Scripting} The scripting interface was designed around a `target' \gls{api} (described by diff --git a/img/event-sequence.puml b/img/event-sequence.puml new file mode 100644 index 0000000..2555f33 --- /dev/null +++ b/img/event-sequence.puml @@ -0,0 +1,16 @@ +@startuml +skinparam SequenceParticipantPadding 15 + + +participant EventHandler +participant Publisher +participant EventManager + +EventHandler -> EventManager : Subscribe event +Publisher -> EventManager : trigger event + +EventManager -> EventHandler : execute callback function +Publisher -> EventManager : Queue Event +EventManager -> EventHandler : dispatching queued events +EventHandler -> EventManager : unsubscribe event +@enduml -- cgit v1.2.3