\documentclass[aspectratio=169]{beamer}

% pdfpc slides.pdf --notes=right
% comment out to disable notes
%\setbeameroption{show notes on second screen=right}

\usetheme{metropolis}

\usepackage{outlines}

\usepackage{minted}
\setminted{fontsize=\footnotesize,samepage=true}
%\usepackage{xcolor}
%\definecolor{codecolor}{HTML}{FFC300}

\usepackage[super]{nth}
\usepackage{csquotes}

\title{VEGO-Engine}
\subtitle{A student project}
\author{Benedikt, Nicole}

\begin{document}

\maketitle
\note{Tone: light hearted "What did we learn"}

\begin{frame}{Outline}
\tableofcontents
\end{frame}

\section{Context}

\subsection{The team}
\begin{frame}{Who are we?}
\begin{itemize}
    \item Group of 5 people
    \item At the start of the project we had about 1 Semester of C++ Programming under our belt
    \item All shared a common interest in C++ Programming + a curiosity for game development
\end{itemize}
\end{frame}
\subsection{The project}
\begin{frame}{The assigment}
\begin{itemize}
    \item \enquote{Development of a fantasy game console} (similar to Pico8)
    \item For simple Arcade like games (think Pong/Space Invaders)
    \item Goal was to teach how to manage and program within a larger project
\end{itemize}
\end{frame}
\begin{frame}{Our interpretation and goals}
\begin{itemize}
    \item Started out with a Minigame
    \item Realized we can split it into \enquote{Engine} and \enquote{Game Specific} Content
\end{itemize}
    \Rightarrow We could then build on what we have while simultaneously having an implementation using the engine
    
    Smart right :D ?\dots
\end{frame}
\begin{frame}
    What awaited us was about the equivalent of trying to neatly sort single spaghetti strands next to each other after
    it has previously been generously mixed with some *juicy* pasta sauce.
    
    In other words, quite a messy endeavor\dots
\end{frame}
\begin{frame}{Roadmap}
\nth{3} Semester - learning SDL

\nth{4} and \nth{5} Semester - making the engine
\end{frame}

\section{Learnings}
\subsection{Project environment}

\begin{frame}{Baby's first \texttt{CMakeLists.txt}}
\begin{itemize}
    \item On UAS: Only ever Make or no project setup
\end{itemize}
\end{frame}
\begin{frame}{Visual Studio}
Hate
\end{frame}
\begin{frame}{How the \_ do I import a library?}
\begin{itemize}
    \item git-modules
\end{itemize}
\end{frame}
\note[itemize]{
    \item SDL is a library, static compile
    \item git-modules - do not bloat contributions
}

\subsection{ECS}
% ECS slides, split into 3 sections
\begin{frame}[fragile]{We made an ECS}
Why an ECS - Entity Component System?
\begin{itemize}
    \item Encourages reusable code
    \item "Plug-and-play" to add functionality
    \item We found a video tutorial series for it
    \item Simplified implementation: Entities propagate updates to the components
\end{itemize}
\end{frame}
\note[itemize]{
    \item Reusable code mainly on engine side, but also applies to game dev components
    \item plug and play mostly an advantage for game dev - i.e. "I want physics, here are physics"
    \item \enquote{video series} - tease issue of abruptly ending
    \item Components usually only have data, and are querried by the system (hence ecS)
    \item System part used for rendering
}
\begin{frame}[allowframebreaks, fragile]{We made an ECS - Implementation}
\begin{minted}[linenos,autogobble,samepage=false]{c++}
class Entity {
private:
    std::vector<std::unique_ptr<Component>> components;
    ComponentArray componentArray = {};
    ComponentBitSet componentBitSet;
public:
    void update(uint_fast16_t diffTime) const;
    template <typename T> bool hasComponent() const {
        return componentBitSet[getComponentTypeID<T>()];
    }
    template <typename T> T& getComponent() const {
        auto ptr(componentArray[getComponentTypeID<T>()]);
        return *static_cast<T*>(ptr);
    }
    template <typename T, typename...TArgs> T& addComponent(TArgs&&...mArgs) {
        T* c(new T(std::forward<TArgs>(mArgs)...));
        c->entity = this;
        std::unique_ptr<Component> uPtr{ c };
        this->components.emplace_back(std::move(uPtr));

        componentArray[getComponentTypeID<T>()] = c;
        componentBitSet[getComponentTypeID<T>()] = true;

        c->init();
        return *c;
    };
};
\end{minted}
\end{frame}
\note[itemize]{
    \item appologize for formatting - for the sake of compactness
    \item TypeID: increments through all components - copied from video tutorial
    \item NOT beginner friendly
}
\begin{frame}[fragile]{We made an ECS - Usage}
Very easy to use:
\begin{minted}[linenos,autogobble]{c++}
auto& projectile(this->manager->addEntity());
projectile.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, scale);
projectile.addComponent<SpriteComponent>(texture, 4); // 4 => zIndex
projectile.addComponent<ProjectileComponent>(range, speed, velocity, owner);
projectile.addComponent<ColliderComponent>(0.6f);
\end{minted}
\end{frame}
\note{mention: this ease of use is our goal}

\subsection{Memory Management}
\begin{frame}[allowframebreaks, fragile]{Memory Management}
\begin{minted}[linenos,autogobble]{c++}
class Manager
{
public:
    Entity& addEntity()
    {
        Entity* e = new Entity(*this);
        std::unique_ptr<Entity> uPtr{ e };
        this->entities.emplace_back(std::move(uPtr));
        return *e;
    }
private:
    std::vector<std::unique_ptr<Entity>> entities;
}
\end{minted}
\framebreak
Does that solve memory management? Not quite:
\begin{itemize}
    \item Missing separation of concern - manager also propagates update call
    \item Does not allow "saving" existing entities
\end{itemize}
Architectural issues like this are hard to solve this late in development

However it does solve memory management\footnote{For \texttt{Entity} classes only, there are some leaks due to bad usage of the \texttt{SDL\_mixer} library}
\end{frame}
\note[itemize]{
    \item \enquote{Perfect example of why our ECS is not ideal}
    \item scene management - would replace manager - however manager is too widely used - break API consistency
    \item classic example of good on surface level only for a beginner; transition to more such examples
}

% Beginner traps
\subsection{C++ beginner traps}
\begin{frame}[fragile]{C++ - Friend or Foe?}
\enquote{I just learned about \underline{\hspace{1cm}}, so I'm going to use it everywhere\dots}

Please do not take any of our claims as factually accurate or best practice
\end{frame}
\begin{frame}[fragile]{C++ - Friend or Foe? - Ternary operator}
If used in moderation:
\begin{minted}[linenos,autogobble,samepage=false,breaklines]{c}
void TextureManager::draw( /* ... */, bool flipped)
{
    SDL_FlipMode flip = flipped ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
    // ...
}
\end{minted}
\end{frame}
\begin{frame}[allowframebreaks, fragile]{C++ - Friend or Foe? - \texttt{std::ranges}}
\begin{minted}[linenos,autogobble,samepage=false,breaklines]{c++}
    // for each tile set
    auto tileConstructorRange = std::views::iota(0)
    | std::views::take(this->mapData.tileSets->size())
    // return the tile set metadata
    | std::views::transform([&](uint16_t i) { /* ... */ })
    | std::views::transform([=, this](const TileSetData& data) {
        // for each tile on the tile set
        return std::views::iota(0)
        | std::views::take(this->mapData.mapSize->x * this->mapData.mapSize->y)
        // only take tiles that are on the ID range of the tile set
        | std::views::filter([=](uint16_t idx) { /* ... */ })
        // extract tile data
        | std::views::transform([=, this](uint16_t idx) {
            /* ... */
            return std::function<Entity*()>(
                [tilePosX, tilePosY, capture0 = *this->mapData.mapTileSize, u, v, zIndex, capture1 = data.texturePath, collision] {
                    return Map::addTile(tilePosX, tilePosY, capture0, u, v, zIndex, capture1, collision);
                }
            );
        });
    })
    // 2D view to 1D vector
    | std::views::join
    | std::ranges::to<std::vector>();
\end{minted}
\end{frame}
\note[itemize]{
    \item context: 
    \item readable (sort of), efficient (not really due to to<vector>)
    \item issues with c++23 (requires at least gcc14)
}
\begin{frame}[fragile]{C++ - Friend or Foe? - \texttt{std::bitset}}
Might be efficient, but\dots
\begin{minted}[linenos,autogobble,samepage=false,breaklines]{c++}
IntersectionBitSet intersections =
    (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(positionChange.x, 0)) |
        (this->entity->getManager().getGame()->collisionHandler ->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(positionChange.x, 0), colliders)) & IntersectionBitSet("0011")) |
    (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(0, positionChange.y)) |
        (this->entity->getManager().getGame()->collisionHandler ->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(0, positionChange.y), colliders)) & IntersectionBitSet("1100"));
\end{minted}
\end{frame}
\note{\dots not very readable}

%code example
\begin{frame}[fragile]{Hello, World!}
\begin{minted}[linenos,autogobble]{c}
#include <stdio.h>

int main()
{
  printf("Hello, World!");
  return 0;
}
\end{minted}
\end{frame}
\note{This is just a slide for testing the minted package}

\end{document}