aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-10-23 21:17:37 +0200
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-10-23 21:17:37 +0200
commitb935677c8bd2bbda35c08b50caabb952f79e8e0b (patch)
tree8c27888020b2fdc4c950b82cd01661d90fdcc99b
parentda846dea2906ae2395ebc6351cae1ca8f8d3313b (diff)
parentfe0ad1db3a166da0ff706c33cbcd4d8a52514f29 (diff)
Merge branch 'master' of https://github.com/lonkaars/crepe-docs into wouter/gameloop-design
merge
-rw-r--r--design.tex126
-rw-r--r--img/class-scripts.puml48
-rw-r--r--reqs.toml33
-rw-r--r--research.tex53
-rw-r--r--time.txt2
5 files changed, 207 insertions, 55 deletions
diff --git a/design.tex b/design.tex
index 4642f0c..0457d8b 100644
--- a/design.tex
+++ b/design.tex
@@ -52,11 +52,133 @@ This separation between game logic and rendering ensures that both simulation ac
\subsection{Scripting}
+The scripting interface was designed around a `target' \gls{api} (described by
+\cref{req:script:interface,req:script:user-class,req:script:direct-instance,req:script:direct-run}).
+An example of this \gls{api} is shown below:\noparbreak
+
+\begin{blockcode}
+class MyScript : public BehaviorScript {
+ void update() {
+ // update code here
+ }
+ // init() also exists, but is empty by default
+};
+
+{ // in scene initialization
+ GameObject & obj = ...;
+ obj.add_component<MyScript>();
+}
+\end{blockcode}
+
+The above call to \codeinline{GameObject::add_component} cannot work correctly
+without significantly increasing the complexity of the component manager, so the
+following restrictions were taken into account when creating the script system
+architecture:\noparbreak
+
+\begin{itemize}
+ \item The first template parameter passed to \codeinline{GameObject::add_component}
+ \emph{must} be a base `script \emph{component}' class, so each derived user
+ script class is instantiated in the same generic script list.
+ \item C++ does not allow passing types (i.e.~\codeinline{MyScript} in this case) as
+ function parameters, so a function call like
+ \codeinline{add_component<BehaviorScript>(MyScript)} cannot be realized.
+\end{itemize}
+
+\subsubsection{Architecture}
+
+The restrictions detailed at the start of this section are mitigated as
+follows:\noparbreak
+
+\begin{itemize}
+ \item User scripts are split into two classes---
+ \begin{enumerate}
+ \item a script \emph{interface} class (\codeinline{Script})
+ \item a script \emph{component} class (\codeinline{BehaviorScript})
+ \end{enumerate}
+ \item \codeinline{GameObject::add_component} receives the script \emph{component}
+ as template parameter
+ \item \codeinline{GameObject::add_component} now always returns a reference to the
+ component instance
+ \item The script component class has a setter function that takes a template
+ parameter for classes derived from the base script \emph{interface} class
+\end{itemize}
+
+\Cref{fig:class-scripts} shows the resulting structure as a class diagram. It
+contains the following classes:\noparbreak
+\begin{description}
+ \item[Script] This is the script \emph{interface}, and is used by the game
+ programmer to create derived script classes. All methods in this class are
+ declared virtual and have an empty implementation.
+
+ This class' methods are protected by default, and a friend relation to
+ \codeinline{ScriptSystem} is used to ensure only \codeinline{ScriptSystem} is
+ able to call these methods.
+
+ Only classes derived from \codeinline{Script} can be used with
+ \codeinline{BehaviorScript::set_script}'s template parameter \codeinline{T}. This
+ function returns a reference to the \codeinline{BehaviorScript} instance it was
+ called on so it can be chained after the call to
+ \codeinline{GameObject::add_component}.
+ \item[BehaviorScript]
+ This is the script \emph{component}, and is given as the template parameter to
+ \codeinline{GameObject::add_component}.
+
+ This class also uses a friend relation to \codeinline{ScriptSystem} to restrict
+ access to its private reference member \codeinline{script}.
+ \item[ScriptSystem] This is the system class that runs the methods implemented in
+ the derivative instances of \codeinline{Script}.
+\end{description}
+
+\begin{figure}
+ \centering
+ \includepumldiag{img/class-scripts.puml}
+ \caption{User script class diagram}
+ \label{fig:class-scripts}
+\end{figure}
+
\subsection{Audio}
-\subsubsection{Library}
+Since writing a custom real-time audio mixing engine is outside the scope of this
+project\mref and C++ does not provide a built-in cross-platform audio \gls{api}, the
+audio system inside the cr\^epe engine is implemented as a fa\c{c}ade around an
+existing audio library.
+
+\subsubsection{Libraries}
+\label{sec:audio:libs}
+
+This subsection compares various standalone audio libraries for suitability. After
+searching for libraries (search terms: `dynamic/adaptive audio', `real-time audio',
+`audio library', `game audio engine'), several libraries were found. These libraries
+were checked against the audio engine requirements \autocite{crepe:requirements} and
+then tested by writing the same benchmark-style \gls{poc} using the remaining
+qualifying libraries:\noparbreak
+\begin{enumerate}
+ \item Load a background track (Ogg Vorbis)
+ \item Load three short samples (WAV)
+ \item Start the background track
+ \item Play each sample sequentially while pausing and resuming the background track
+ \item Play all samples simultaniously
+ \item Stop all audio and exit
+\end{enumerate}
+
+Of these libraries the following were determined to be unsuitable for use in this
+project:\noparbreak
+\begin{description}
+ \item[FMOD \autocite{lib:fmod}] Is proprietary (violates \cref{req:lib:license}).
+ \item[PortAudio \autocite{lib:portaudio}] Does not handle mixing.
+ \item[miniaudio \autocite{lib:miniaudio}] Tested by implementing a \gls{poc}, but
+ dropped due to very limited codec support (WAV, MP3 and FLAC only); Also does not
+ have an \gls{api} reference (only programming manual).
+ \item[YSE \autocite{lib:yse}] Attempted to write \gls{poc}, but CMake configuration
+ in repository is broken; This project seems to have been abandoned.
+\end{description}
+
+The only library that remained after these tests is SoLoud \autocite{lib:soloud}. It
+is Zlib/LibPng licensed and provides a high-level object-oriented C++ \gls{api}.
+\Cref{sec:audio:architecture} describes the fa\c{c}ade written for this library.
-\subsubsection{Fa\c{c}ade}
+\subsubsection{Architecture}
+\label{sec:audio:architecture}
\Cref{fig:class-audio-facade} shows a class diagram of the audio fa\c{c}ade. It
contains the following classes:
diff --git a/img/class-scripts.puml b/img/class-scripts.puml
new file mode 100644
index 0000000..8fc36c9
--- /dev/null
+++ b/img/class-scripts.puml
@@ -0,0 +1,48 @@
+@startuml
+!include theme.ipuml
+skinparam Linetype ortho
+skinparam Nodesep 75
+skinparam Ranksep 30
+
+class ComponentManager <<irrelevant>>
+
+package api {
+ class Component <<irrelevant>>
+
+ class Script {
+ # init() <<virtual>>
+ # update() <<virtual>>
+ --
+ - Script()
+ }
+
+ class BehaviorScript {
+ # BehaviorScript()
+ + ~BehaviorScript()
+ --
+ + set_script<T>() : this &
+ --
+ # script : Script *
+ }
+
+ BehaviorScript -u-|> Component
+ Script .u.> BehaviorScript
+}
+
+class System <<irrelevant>>
+class ScriptSystem <<Singleton>> {
+ + get_instance() : ScriptSystem & <<static>>
+ + update()
+ --
+ - ScriptSystem()
+ - ~ScriptSystem()
+}
+
+System <|-- ScriptSystem
+ScriptSystem .[norank]> ComponentManager
+
+ScriptSystem .[norank]> api.Script : < friend
+ScriptSystem .[norank]> api.BehaviorScript : < friend
+ComponentManager .[norank]> api.BehaviorScript : < friend
+
+@enduml
diff --git a/reqs.toml b/reqs.toml
index ed0b451..a83208e 100644
--- a/reqs.toml
+++ b/reqs.toml
@@ -84,3 +84,36 @@ Windows.
# TODO: library documentation as quality factor?
# TODO: modularity over less libraries? (i.e. why don't we just SDL2 everything?)
+[script:interface]
+type = 'system'
+priority = 'must'
+description = '''
+There is a base \codeinline{Script} class that has empty default
+implementations for functions that may be implemented by the game programmer.
+'''
+
+[script:user-class]
+type = 'system'
+priority = 'must'
+description = '''
+The game programmer implements scripts by creating classes derived from the
+\codeinline{Script} class.
+'''
+
+[script:direct-instance]
+type = 'system'
+priority = 'must'
+description = '''
+Unless explicitly changed by the game programmer, derived script classes cannot
+be instantiated directly, and must be instantiated by the component manager.
+'''
+
+[script:direct-run]
+type = 'system'
+priority = 'must'
+description = '''
+Unless explicitly changed by the game programmer, methods on instances of
+\codeinline{Script} (and derivative) classes cannot be called directly, and
+must be called by the script system.
+'''
+
diff --git a/research.tex b/research.tex
index 385efbe..5dd01a6 100644
--- a/research.tex
+++ b/research.tex
@@ -427,59 +427,6 @@ licensing flexibility.
%
% \subsection{Conclusion}
-\section{Audio}
-
-The game engine is required to have an audio system
-\autocite[\ref{req:audio}]{crepe:requirements}. Since writing a custom real-time
-audio mixing engine is outside the scope of this project\mref, this section compares
-various standalone audio libraries for suitability in the engine.
-
-\subsection{Libraries}
-\label{sec:audio:libs}
-
-After searching for libraries (search terms: `dynamic/adaptive audio', `real-time
-audio', `audio library', `game audio engine'), several libraries were found. These
-libraries were checked against the audio engine requirements
-\autocite{crepe:requirements} and then tested by writing the same benchmark-style
-\gls{poc} using the remaining qualifying libraries:\noparbreak
-\begin{enumerate}
- \item Load a background track (Ogg Vorbis)
- \item Load three short samples (WAV)
- \item Start the background track
- \item Play each sample sequentially while pausing and resuming the background track
- \item Play all samples simultaniously
- \item Stop all audio and exit
-\end{enumerate}
-
-Of these libraries the following were determined to be unsuitable for use in this
-project due to various reasons:\noparbreak
-\begin{description}
- \item[FMOD \autocite{lib:fmod}] Is proprietary (violates \cref{req:lib:license})
- \item[PortAudio \autocite{lib:portaudio}] Does not handle mixing
- \item[miniaudio \autocite{lib:miniaudio}] With finished \gls{poc}, but dropped due
- to very limited codec support (WAV, MP3 and FLAC only); Also does not have an
- \gls{api} reference (only programming manual)
- \item[YSE \autocite{lib:yse}] Attempted to write \gls{poc}, but CMake configuration
- in repository is broken; This project seems to have been abandoned
-\end{description}
-
-The only library that remained after these tests is SoLoud \autocite{lib:soloud}. It
-is Zlib/LibPng licensed and provides a high-level object-oriented C++ \gls{api}.
-
-\subsection{Conclusion}
-\label{sec:audio:conclusion}
-
-Due to a severe shortage of libraries that fit our requirements, SoLoud appears to be
-the most suitable (and only) audio library for use in this project.
-
-% \section{Scripting}
-%
-% \subsection{Introduction}
-%
-% \subsection{Findings}
-%
-% \subsection{Conclusion}
-
\section{Physics}
%links
diff --git a/time.txt b/time.txt
index c814b34..205c617 100644
--- a/time.txt
+++ b/time.txt
@@ -78,6 +78,8 @@ loek: 2024-10-18 1h40m docs :: design :: scripting interface
loek: 2024-10-20 30m review :: PR review (#37)
loek: 2024-10-21 1h30m implementation :: global config interface
loek: 2024-10-21 10m review :: PR review (#7)
+loek: 2024-10-22 15m review :: incorporate feedback and merge PR (#7 and #37)
+loek: 2024-10-23 30m implementation :: refactoring
max: 2024-09-02 1h project kickoff
max: 2024-09-02 45m first project meeting