Rynek systemów operacyjnych na PC jest podzielony na trzech głównych graczy, tworzy to zapotrzebowanie na silniki do gier, które są wszechstronne i działają tak samo, niezależnie od platformy. Niniejsza praca inżynierska przedstawia projekt i implementację nowego silnika do gier opracowanego z myślą o grach typu "dopasuj 3", gatunku który jest zarówno popularny, jak i stosunkowo łatwy do wdrożenia, mimo to nadal nie ma wyspecjalizowanego silnika open-source pod gry "dopasuj 3". Silnik został zbudowany w oparciu o bibliotekę graficzną OpenGL i system zarządzania oknami glfw, zapewniając zaawansowane możliwości graficzne przy jednoczesnym zachowaniu kompatybilności między platformami. Silnikowi przyświecają dwa cele: prostota obsługi dla deweloperów i solidna wydajność. Architektura skupia się na wykorzystaniu dobrych praktyk, nowoczesnego kodu C++ i sprawieniu że czytanie kodu silnika będzie łatwe i zrozumiałem dla develiperów. W rezultacie twórcy gier mogą skupić się na tworzeniu gier typu "dopasuj 3" bez konieczności nauki programowania, umożliwiając artystom bez zaplecza technicznego, którzy chcą stworzyć wyjątkowe doświadczenie. Niniejsza praca opisuje motywacje, tło, dokumentację i przypadki użycia na trzech głównych platformach: Linux, Windows i MacOS. Silnik demonstruje użyteczność, możliwość dostosowania do różnych platform i zapewnia narzędzia niezbędne do tworzenia prostych gier typu "dopasuj 3". Niniejsza praca stara się wypełnić lukę w wyspecjalizowanych silnikach gier wideo open-source.
With three major operating systems on PC, there exists a need for game engines that are versatile and platform-agnostic. This thesis introduces the design and implementation of a new game engine developed with match-three games in mind, which is a game genre that is both popular and relatively easy to implement, despite this there is still no specialized open-source match three game engine. The engine is built upon the foundations of the OpenGL graphics library and the glfw windowing system, ensuring advanced graphics capabilities while retaining platform compatibility. There are two goals for the engine: simplicity of use for developers, and robustness in performance. The architecture focuses on using good practices, modern C++ code and making the code developer friendly. As a result, game developers can focus on crafting match-three games without need to learn programming, empowering artists without technical background who want to create an unique experience. This work provides motivation, background, documentation and use-case across three major platforms: Linux, Windows, and MacOS. The engine demonstrates usability, adaptability to different platforms, and provides the tools necessary for creation of simple match-three games. This thesis is trying to fill the gap of specialized open-source video game engines.
Among us, computer science students, video games were—and still are—one of the driving forces pushing us into the field of IT. Video games allow people with technical background to express their artistic side and create visually stunning projects. In particular "Match Three" games, characterized by their intuitive mechanics and satisfying gameplay, have attracted millions of players around the globe. They offer statisfying experience of aligning three or more similar game pieces, often resulting in gratyfying chain reactions. This lead to success of titles like "Candy Crush Saga" and "Bejeweled", staple titles for both mobile and desktop market.
\begin{figure}[h]
\includegraphics[scale=0.5]{allgates}
\caption{Minecraft redstone offers introduciton to logical gates \cite{raspberrypi2023}}
Match three games are from technological point of view relatively easy to make, despite that there is no dedicated open-source game engine designed just for them. This engineering thesis aims to fill this void, to give back to the world of game developers and open-source projects.
Another motivation is a chance to learn one of the most popular graphical API - OpenGL, It is a graphical API which proved useful again and again with video game engines, rendering engines or for desktop applications.
While game engines can be created for multiple game genres, this thesis focuses on Match Three genre. This decision comes from its ease of implementation, combined with relatively high popularity and applicability on all platforms. We will focus on core logic, rendering techniques, and controls focused on Match Three games.
Another important part of the thesis is multiplatform game development. We will focus on three major desktop operating systems: Windows, Mac, and GNU/Linux. The challenges associated with creating an uniform gaming experience across these platforms, taking into consideration differences in architecture, functionality and graphics.
This thesis will make biggest use of OpenGL API together with libraries: GLFW, GLAD, FreeType, stb\_image, and ft2build. In order used for platform-independed creation of windows, context and handling inputs, loader for OpenGL, library for rendering text, library for loading images and library for building free type sources. Later in the thesis we will dvelfe deeper into those libraries
Since the engine aims to be simple and robust, it will not contain every possible feature or optimization like in commercial-grade game engines. The primary intent is to create a solid structure for which further advancements can be made.
In conclusion, this thesis goal is to provide an understanding of multiplatform Match Three game engine development. By setting managable boundaries, it aims to dive deep into specific challenges, tools, and solutions, providing valuable insights for aspiring engine developers. Next sections will further describe the objectives, methodologies, and findings of this exploration into the world of game development.
Clear objectives allow for accomplishments that can be measured. Therefore it is important to define goals that underpin this thesis. In this section, we describe the primary goals of this thesis.
The foremost objective is to design a core multiplatform engine architecture. This demands a good understanding of the operating systems differences, from their system calls to their graphics pipelines. The engine should be modular and scalable, in order to make sure that the core mechanics and logic can be implemented across Windows, Mac, and GNU/Linux platforms.
With numerous libraries at our disposal, an important goal is to combine them into the engine in a cohesive manner. We will make use of GLFW for window management, GLAD for OpenGL function pointers, FreeType and ft2build for text rendering, and stb\_image for image handling. In addition to integrating them into an engine, these libraries must operate in such a way that they complement each other to improve the engine's overall performance and capability.
Architecture and libraries used form the skeleton, the Match Three mechanics are the most important part of the engine. The aim is to create algorithms and techniques to take care of typical Match Three functionalities – from matching detection to gravity-induced piece drops and chain reactions.
While the first objective is the engine's development, a broader goal is to expand upon created engine. By addressing challenges and sharing solutions, this thesis hopes to offer an example for engine developers. Whether they wish to enhance this engine or create new game engines. This thesis tries to improve their understanding of the topic
The world of video games is vast and varied, Offering anything from massive multiplayer role playing games to small mobile puzzles. Match Three games offer players a blend of strategy, pattern recognition, and instant gratification. To better understand the significance of our task in creating a multiplatform Match Three game engine, it's important to trace how the genre evolved, understanding its roots, its development, and its appeal.
Match Three games owe their existence to the broader genre of tile-matching video games. The earliest entrants in this category were games like "Tetris" in the 1980s, where players manipulated falling blocks to create complete lines. "Tetris" kickstarted games focused on spatial reasoning and pattern recognition.
Expandin on this formula, 1980s and 1990s saw games like "Columns" and "Dr. Mario". These games introduced the mechanic of matching three or more identical items, but they were still using the falling-block paradigm. The true prototype of modern Match Three mechanics can be credited to "Shariki," a 1994 game where players swapped adjacent pieces to form chains of three or more identical items.
In 2001 game titled "Bejeweled" came out. Simplifying and refining the mechanics of "Shariki", "Bejeweled" was the first mainstream success of Match Three genre. It provided intuitive gameplay, visually appealing graphics and set the benchmark for games that followed.
The success of "Bejeweled" lead to several innovation. Developers experimented with various twists on the core mechanics. Games introduced power-ups, barriers, objectives, and narrative elements. "Candy Crush Saga", released in 2012, integrated a level-based progression system, increasing the genre's complexity and depth.
The evolution of Match Three games is interlocked with technological improvements in the gaming industry. Initially developed to PCs and consoles, the rise of mobile devices opened a new opportunities for the genre. The touch interface of smartphones and tablets proved to be an ideal medium for the drag-and-swap mechanics of Match Three games.
At the same time, browser-based games, using technologies like Flash, allowed players to engage with Match Three puzzles without heavy downloads or installations. As technology progressed, the need for engines that worked on multiple platforms – mobile, browser, consoles and desktop – became apparent.
Despite multiple competing genres, Match Three games remain popular. Their success can be attributed to their 'easy to learn, hard to master' trait. The games offer immediate rewards – the satisfaction of creating a match, beauty of pieces disappearing, and the strategic depth of planning several moves ahead. Additionally, the modular nature of their design allows for easy adaptation, whether it's incorporating a narrative, integrating with popular cultures, or tailoring to specific demographics.
In conclusion, the history of Match Three games is a proof to their adaptability and universal charm. They established themselves as one of the most recognizable genres in mobile and desktop gaming, they continue to gather players. This perspective marks significance of engines tailored to Match Three games specificaly.
Game developres try to reach wider audiences by ensuring that their creations are accessible across a variety of operating systems. Multiplatform game development aims to deliver the same experience to different user bases. This section describes challenges and methodologies connected with multiplatform game development.
There are three main operating systems, Windows, Mac, and GNU/Linux which together are responsible for over 90\% of desktop market share \cite{marketShareChart}, the potential to reach a bigger audience increases when a game is made available across all of these platforms.
\begin{figure}[H]
\centering
\includegraphics[scale=0.50]{chart.png}
\caption{Desktop OS market share worldwide \cite{marketShareChart}}
In order to face multiplatform development challenges, we use a set of tools and libraries. Libraries like OpenGL offer an unified graphics rendering solution, while GLFW enforces consistent window management and input handling. stb\_image, and ft2build are other libraries that offer consistent behavior across platforms for handling images and font rendering.
\item Modular Design: By dividing the game engine into distinct modules, developers can isolate platform-specific code, ensuring that core logic remains unchanged by platform dependencies.
\item Continuous Integration and Testing: Automated testing across platforms can identify inconsistencies, ensuring that the game offers an uniform experience.
\item Community Engagement: Using the community that uses the game engine across multiple platforms offers developers insights into existing bugs and potential optimizations
With the cloud gaming on the rise, ressurection of web-based games, and increasingly powerful mobile devices, multiplatform development's scope is constantly expanding. There will be newer platforms and more varied devices to handle. The goal will remain the same: ensuring that games offer a consistent, engaging, and seamless experience, independent of the platform.
Multiplatform game development requires technological knowledge and good design. By understanding its challenges and methodologies, developers are better equipped to face-on multiple platforms of modern gaming. This foundation will become crucial later into the development of our multiplatform Match Three game engine.
The gaming industry has seen rise of various game engines, each offering a unique set of tools and functionalities for different needs. While these engines have facilitated the creation of iconic games, they also come with certain limitations, especially concerning specific genres or platforms. This section will describe prominent game engines and analyze their shortcomings, providing a reference for our multiplatform Match Three game engine.
Unity is one of the most popular game engines available today. It's known for its versatility, supporting a wide range of platforms, from PCs to consoles to mobile devices.
\item Strengths: Plenty of community resources, a vast asset store, and an intuitive interface make Unity a popular choice among both beginners and professional developers.
\item Limitations: Unity's all-purpose nature might introduce unnecessary load for simpler games, like Match Three titles, potentially impacting performance.
\item Learning Curve: Its advanced features can be overwhelming for beginners.
\item Simpler Genres: As with Unity, for a simple game like Match Three game, the engine might be too sophisticated, leading to longer load times and increased resource consumption compared to custom solution.
RPG Maker and Ren'Py are examples of game engines focusing on one genre of games.
RPG Maker focues on top-down rpg games, while ren'py aims to ease the process of making visual novel games. Both of those engines were used with commercial and critical success, with creation of games like "To The Moon" and "Doki Doki Literature Club". Their limitations are both their strenght and weaknesses, allowing to speedup development process but blocking the developer for leaving the area of interest for those engines.
While each game engine has its unique strengths and weaknesses, some common limitations come apparent when considering the development of a specialized game like a Match Three title, those engines either do not allow for match three development (RPG Maker or Ren'Py) or deliver match three titles with too much technological bloat (Unity/Unreal/Godot)
While existing game engines offer a lot of tools and capabilities, there exists a space for specialized engines made for specific genres. Recognizing the limitations of mainstream engines explains development of our multiplatform Match Three game engine, which tries to fix these gaps while providing an easy development.
Game engines serve as the backbone for game development, providing a selection of tools and features that simplify the process of creating a game from scratch. At the heart of every game engine lie its core components, which define its capabilities, flexibility, and performance. This section explains those elements that we are going to implement in our engine.
The rendering engine is responsible for all visual aspects within a game. It takes the game's data – including textures and shaders – and converts them into pixels on the screen.
\item Role: Processes user inputs from various sources, like a keyboard, mouse, gamepad, or touch screen. Translates these inputs into in-game actions or commands.
\item Key Features: Detects multiple simultaneous key presses, supports touch gestures, and allows for input remapping.
Each component of game engine plays a different role, in combination they ensure that the game runs smoothly, offers an enjoyable experience, and responds to user interactions. These core parts form the foundation upon which our multiplatform Match Three game engine will be built and updated.
Game engines need graphics libraries, those libraries provide the necessary tools to bring visual elements to the screen. Among these libraries, OpenGL (Open Graphics Library) has established itself as one of the most popular choices for graphics rendering. This section explores the role of OpenGL in game development, focusing on library functionalities and how they can be used.
OpenGL is a cross-language, cross-platform application programming interface (API) designed for rendering vector graphics. Initially developed by Silicon Graphics in the 1990s, it is now taken care by the non-profit technology organization, the Khronos Group. It is platform-agnostic which makes experience consistent across different platforms.
\item Role: OpenGL communicates directly with a system's GPU (Graphics Processing Unit) and translates the game's data into visual elements displayed on screen.
\item Key Features: Supports techniques such as texture mapping, anti-aliasing, and shader programming.
\item Role: As hardware evolves, new extensions can be added to OpenGL without changing the entire API. This makes OpenGL relevant, independent of technological improvements.
\item Key Features: These extensions can be used to utilize latest graphics hardware capabilities, making games look and perform their best.
\item Role: OpenGL ensures that games look consistent across different platforms, easing the process of multiplatform game development.
\item Key Features: It abstracts underlying platform-specific differences, allowing developers to focus on creating the game without need to adapt to platform-specific constraints.
\item Role: Enhances OpenGL capabilities by working with libraries like GLFW for window management, GLAD for handling extensions, and more.
\item Key Features: Provides an unified development environment, where various tools and libraries work together under OpenGL, again simplifying the process of game development.
In summary, OpenGL combines software and hardware, enabling developers to create experiences with enough precision and speed. Understanding impact of OpenGL will make explaining our own game engine inner workings much easier.
In order to reach as wide an audience as possible, developers try to develop a game for multiple platforms – mostly Windows, Mac, and GNU/Linux. Creating multiple platforms game engine is filled with challenges and considerations. This section explores difficulties of multiplatform game development, describing what developers must be conscious of when targeting multiple operating systems.
\item Role: Ensuring the game runs smoothly across different hardware setups, from different GPU architectures to memory configurations.
\item Key Features: Developers need tools to abstract these hardware-software differences, allowing the game engine to react dynamically based on the platform.
In the arena of game development, libraries related to window management and input handling play crucial role. GLFW offers an interface for developers to create interactive applications. This section offers an introduction to GLFW, explaining into its origins, functionalities, and relevance in game development.
GLFW, which stands for Graphics Library Framework, was a response to the need for an open-source library that simplifies the challenges of window management and input handling, especially for OpenGL applications. Initially developed to provide a more straightforward alternative to existing solutions, GLFW has grown in popularity due to its simplicity, efficiency, and cross-platform capabilities.
\item Window Management: GLFW's manages window creation, querying, and manipulation. It allows developers to focus on their game logic rather than handling platform-specific windowing.
\item Input Handling: GLFW provides a system to capture and process user inputs. It forms for keyboard strokes, mouse movements, or even joystick inputs, GLFW makes sure that user interactions are detected and communicated to the application efficiently.
\item Context Management: Especially relevant for OpenGL applications, GLFW helps create contexts, manage profiles, and handle extensions, for easier development experience.
\item Role: It functions as the companion to OpenGL, offering an environment where OpenGL can work more efficiently by addressing system-specific challenges that are outside OpenGL's specification.
\item Role: GLFW is a consistent interface for developers, regardless of the target platform. This ensures uniformity in window creation, input handling, and other functionalities across different operating systems.
GLFW proves useful to many game developers, especially those using OpenGL. Its ability to handle window management, input processing, and other tasks ensures that developers can focus on crafting game mechanics and narratives.
GLAD is a robust and flexible loader-generator designed for OpenGL. It ensures the dynamic loading of OpenGL functions based on the specific version and extensions a developer chooses. GLAD was developed to automate handling OpenGL extensions.
OpenGL's is an extensible API. With changes in hardware, new functionalities are introduced through extensions without changing the core API. This creates new challenges on their own.
\item Key Features: Handling these extensions requires dynamic loading at runtime, so that the game can access and utilize these advanced functionalities.
\item Role: Provided with the OpenGL version and extensions, GLAD generates C/C++ code to load these extensions dynamically at runtime. This removes the need to manually address each extension, reducing errors and inefficiencies.
\item Key Features: GLAD supports multiple languages and specifications. It is also up-to-date with the latest OpenGL specifications, making it compatible with newest graphics capabilities.
GLAD interacts with both OpenGL and GLFW, creating an unified development environment. Once GLFW creates the OpenGL context, GLAD is utilized to load the necessary functions. This collaboration ensures that GLFW handles the platform-specific instructions, while GLAD focuses on OpenGL's extensibility.
\item Font Parsing and Loading: Before rendering, fonts need to be parsed and loaded. FreeType supports many font formats, ensuring broad compatibility.
\item Glyph Rendering: FreeType is good at converting individual glyphs into bitmaps, handling anti-aliasing and hinting to create clear, sharp text rendering.
\item Font Metrics and Kerning: Rendering text isn't just about individual glyphs. The spacing between them (kerning) and their metrics are crucial for readability and aesthetics, and FreeType is able to deliver this functionality.
ft2build serves as an essential interface, allowing for the inclusion and deployment of FreeType headers in development projects. ft2build was created to ease the integration process of FreeType 2.
While FreeType takes charge of fonts, stb\_image is a solution for image loading and decoding, popular for its simplicity and compactness. It is part of the stb collection of single-file libraries.
\item Image Loading: It is capable of handling popular formats like JPEG, PNG, BMP, and more, this way developers can incorporate multiple types of graphical assets into their game
\item Simplicity and Efficiency: stb\_image has minimalistic design. With just a single header file, developers can use its capabilities without employing complex dependencies or configurations.
In the heart of every video game lies the game loop. This cycle dictates the game's pacing, ensuring that events, updates, and rendering processes all appear in a correct order. Game loop functions together with state management, which ensures the game behaves consistently in response to player actions and internal events. This section will focus on both the game loop and state management and how they influence our multiplatform Match Three game engine.
\item State-Driven Rendering: What the game displays during each loop iteration depends on its current state. For instance, the game may render a main menu, gameplay screen, or a 'game over' message based on its active state.
\item State Transitions: Player inputs or internal events can trigger state changes. The game loop continually checks for such triggers and initiates the necessary transitions.
\item Match-Three Logic: The game engine will manage states specific to match-three mechanics, like checking for matches, handling cascades, and introducing new game pieces.
Game development consists of art and logic, where visual assets behave based on game code. Ensuring these assets are well-organized, efficiently loaded, and rendered is vital for any gaming experience. This section explores asset management and rendering.
\item Format Compatibility: Not all asset formats are supported uniformly across platforms. Ensuring assets are in universally compatible formats and using libraries like stb\_image that unify asset formats among different operating systems is crucial.
\item Optimization: Different platforms may have varying memory capacities and processing power. Assets might need to be optimized, resized, or compressed to respond to those limitations.
\item Match-Three Specifics: Given the genre, the engine must effectively manage assets like gems, power-ups, grid structures, and cascade animations and then render them in a visually pleasing way.
Main trait of video game is interactivity. Game must have the ability to capture, interpret, and respond to user input, whether it is the click of a mouse, the press of a keyboard key, or the swipe on a touchscreen. Managing those interactions is called event handling. In this section we will describe event handling and user input, and their role in our game engine.
\item Intuitive Matching: Selecting and swaping game pieces should be easy and convenient, with the engine accurately capturing and responding to these interactions.
\item Feedback Loop: Upon receiving an input, the game engine must also provide immediate feedback, such as highlighting a selected piece, initiating a combo move or playing animation.
Operating systems (OS) are a middle ground between human interaction and hardware functionality. With Windows, Mac, and GNU/Linux operating systems as the most popular desktop environments, a multiplatform game engine must work under each of them. This section describes differences between these operating systems and how our engine can handle them.
\item File Systems: Windows primarily offers NTFS, MacOS stores files using APFS, and GNU/Linux has multiple options like ext4, Btrfs, and many, many more.
\item Window Management: Windows uses a floating window system, MacOS has its unique mission control, and Linux distributions can use anything from floating, fixed to no graphical interface at all.
\item Input Methodologies: Multi-touch gestures work different under MacOS than under Windows. Linux, depending on its distribution and desktop environment, may have a the same or different approach altogether.
Certain hardware, sometimes crucial to game engine like graphics card or keyboad, might be optimized for one OS over the others, or might not be supported entirely.
The accessibility, performance, and support of middleware and third-party libraries can differ, while some libraries are universally compatible, others might be OS-specific, another problem might be with the update cycle, the frequency of libraries updates can vary, impacting game engine compatibility and performance.
Multitude of operating systems poses challenges for game engine developers. By understanding these differences, developers can make sure that the game functions across different platforms.
Hardware and its associated drivers act as the final execution devices for any game engine. When creating a game engine, developer must keep in mind a variety of hardware configurations and their driver implementations. This section focuses on understanding these differences and how we can challenge them.
\item Proprietary vs. Open-Source: While NVIDIA provides proprietary drivers, AMD and Intel often offer open-source alternatives for Linux. There are also community driven, universal, open-source drivers.
\item Update Frequencies: Hardware vendors release driver updates at different intervals, each update possibly affects game performance and compatibility.
To address these challenges, our engine adopts abstraction layers: by utilizing existing libraries and solutions (OpenGL, GLAD and GLFW), our game engine is ready for easier adjustments for specific hardware.
For our Match Three game engine, we aimed to create a simple core, capable of ensuring basic gameplay and small codebase allowing developers to extend or modify the engine's capabilities as needed. This section describes the implementation of the Match Three game engine.
\item Platform Independence: Core engine functionalities independent of any specific platform, allowing for easy porting across Windows, MacOS, and GNU/Linux.
Very first operation of our engine is to initliaze GLFW context, window and openGL, we set version of glfw to 3.3, resizable window and the profile depending on whether the engine got initialized on MacOS, or Linux/Windows, we set the windows width and height based on values from constants file
\subsubsection{Main Loop}
\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance=2cm]
\useasboundingbox (-5,0) rectangle (5, -11); % Set a custom bounding box
Game parameters, from graphics settings to gameplay variables, are stored in constants.cpp file, which can be modified, to apply the changes the engine must be compiled again.
\textbf{constants} namespace: Used for constants that are used over the project, for example colors, colors are hold in open gl vector of 3 values (for RGB colors)
\textbf{text} namespace: Parameters concerning text display positions on screen.
\begin{lstlisting}[style=C++Style]
struct Point {
float x;
float y;
};
namespace text {
constexpr Point LIVES_POSITION = {5.0F, 5.0F};
...
}
\end{lstlisting}
\textbf{textures} namespace: Provides paths to texture files and their respective identifiers, in this examples gems are named as: "g" for gems, number of gem and then color of gem
Game class defined in game.h and game.cpp is the main and biggest class in the project, it brings together all other classes and functionalities of the engine.
\subsubsection{Includes}
\begin{lstlisting}[style=C++Style]
#include "./constants.hpp"
#include "./filesystem.h"
#include "./game_level.h"
#include "./game_object.h"
#include "./post_processor.h"
#include "./resource_manager.h"
#include "./sprite_renderer.h"
#include "./text_renderer.h"
\end{lstlisting}
\paragraph{Constructor}
Constructor initializes game window size, empties clicked keys, sets game state to game menu, sets initial level map and retrieves max turns from constants file
\begin{lstlisting}[style=C++Style]
Game::Game(ScreenDimensions screen)
: State(GAME_MENU),
Keys(),
KeysProcessed(),
Width(screen.width),
Height(screen.height),
Level(0),
MaxTurns(constants::MAX_TURNS),
Turns(0)
{}
\end{lstlisting}
\subsection{Game initialization}
\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance=2cm]
\useasboundingbox (-5,0) rectangle (5, -11); % Set a custom bounding box
Two shaders are used throughout the project, one for rendering sprites (gem tiles) and one for generating post processes (for example shaking the map when tiles get matched) \\
More on the shaders usage later when we will be discussing postProcessor and Shader clasess
Levels are loaded automatically from the levels folder, game assumes that every file with extension ".lvl" is a level file and adds it to an array of levels
Game is ended either when the player exceeds maximum move limit (game lost) or when points limit is reached (game won), otherwise the game continues, notice how first we check for win condition then for loss condition, this makes the gameplay a little bit more satisfying and fair.
\subsection{Controls}
Game allows to move through the grid to highlight a tile, then after clicking "enter" a tile is selected, then by using arrows or WSAD keys user can highlight the tile that will be swapped when again "enter" gets clicked
\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance=2cm]
\useasboundingbox (-5,0) rectangle (5, -7); % Set a custom bounding box
\node (start) [startstop] {Highight tile (WSAD or arrow keys)};
Game level class takes a 2D array of game objects instances (tiles), receives inputs from game class and reacts to them, it handles removing, swaping, adding new tiles on a map and checking for sequences of tiles. It also loads the level file and translates it to in game object
\paragraph{Reading file}
Game level class goes through each line of level file. \\
It loads each row to a vector of unsigned int as the level file contains rows of numbers representing tile type
\begin{figure}
\begin{lstlisting}
4 2 3 2 4 3 3 1 3 3
1 1 2 1 1 2 1 3 1 1
4 1 4 3 3 4 4 3 2 3
4 3 3 4 3 3 2 1 2 1
3 2 3 1 4 4 3 2 4 2
4 2 1 3 3 2 2 3 1 1
4 3 2 1 2 2 3 3 4 4
1 4 3 2 1 4 3 2 1 4
3 4 3 3 4 4 1 2 3 1
2 3 2 2 1 2 3 3 4 2
\end{lstlisting}
\caption{Exemplary level file}
\end{figure}
\paragraph{Level initialization}
Initializing level takes the loaded vector of ids and creates game objects based on the window dimensions (so that the tiles fill the window evenly), textures are based on the tile id,
we assume that all levels are square so the width and height of the window is always the same.
\subsection{Highlighting, selecting and swapping tiles}
There are four steps in order for the tile to be swapped, logic of fulfilling this conditions is handled in game level class
\paragraph{Highlighting tile}
First the tile must be highlighted, game level makes sure that only one tile is highlighted by keeping the index of highlighted tile and changing it whenever user inputs a change
\paragraph{Selecting tile}
Then the tile must be selected, again game level has a special parameter just to keep track of which tile is selected
\begin{lstlisting}[style=C++Style]
void GameLevel::selectPiece() {
this->Bricks.at(selectedTile).Selected = true;
...
}
void GameLevel::unselectPiece() {
this->Bricks.at(selectedTile).Selected = false;
this->unswapAll();
}
\end{lstlisting}
\paragraph{Which tile will be swapped}
Then the user must choose which tile will be swapped, game level does not keep special parameter for that, it just automatically deselects all tiles in the selected tile neighboorhood if user choose any other tile
When 3, 4 or 5 tiles get match in a row or column, matching function removes those tiles, fills the empty space with blocks from above and fills the final empty space with randomly generated tiles
\paragraph{Finding matches}
To simplify finding matches first game objects tiles is transformed into vector of ids, then this vector is converted into vectors of columns and rows and finaly those vectors are checked for matches
\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance=2cm]
\useasboundingbox (-5,0) rectangle (5, -9); % Set a custom bounding box
\node (start) [startstop] {Find matches};
\node (pro1) [process, below of=start] {Convert to ids vector};
\draw [arrow] (start) -- (pro1);
\node (pro2) [process, below of=pro1] {Convert to rows and columns ids vectors};
After finding matches, blocks where matches appear are set to be replaced by replacing their tile ids with -1
\paragraph{Replacing blocks}
After setting tiles to be replaced, algorithm goes through blocks with ids equal to -1, checks if there are any blocks above, if yes it replaces the block from above with block from below, if there is no block above, it generates one randomly
\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance=2cm]
\useasboundingbox (-5,0) rectangle (5, -11); % Set a custom bounding box
\node (start) [startstop] {Processing matches};
\node (dec1) [decision, below of=start, yshift=-1cm] {Block id is -1?};
There are several libraries: OpenGL, GLFW, stb\_image and freetype being integrated into engine, they are simply included at the top of any files that need them.
Match Three game challenges players to align identical items in rows or columns of three or more. This section describes how the Match Three logic and mechanics were implemented within our game engine.
\item Item Diversity: While classic Match Three games primarily used jewels or candies, our engine supports any kind of 2d image assets user wants to use, these assets can later be processed by user created shaders
\item Move Validation: Not every swap leads to a match. The engine predicts potential matches before finalizing a move, ensuring players don't make invalid swaps.
\textbf{DirectX}& Microsoft & Windows, Xbox & Harder, requires understanding of underlying mechanisms & Non-free \\
\hline
\textbf{OpenGL}& Khronos Group & Windows, Linux, Mac OS, Android, iOS, major consoles (especially with OpenGL ES) & Easiest, lacks some advanced features & Open source (similar to BSD) \\
\hline
\textbf{Vulkan}& Khronos Group & Modern platforms, successor to OpenGL & Hardest, newest & Open source (Apache License 2.0) \\
\item Image Loading: stb\_image simplifies the task of loading and processing various image formats, from PNGs and JPGs to more complex formats, making asset integration much easier.
In order to gauge the usability of our game engine, we decided to create a sample match three game using royalty free assets. First part of this process was game design
Game utilizes full functionality of our engine, player needs to match three or more gems, chaining matches or achieving higher combos grants the player higher score
\item Optimized Performance: Tailored specifically for a Match Three game, the engine could be highly optimized for this genre, reducing unnecessary overheads. Using OpenGL and plain C++ also added to engine speed
\item Ray Tracing: Using ray tracing can provide more realistic lighting, shadows, and reflections, increasing visual depth with little cost to an engine user.
\item Advanced Particle Systems: Enhancing particle effects can create more immersive environments, from weather effects to more dynamic game elements.
\item Physics Enhancements: More advanced physics simulations can improve feel to game interactions, from simple collisions to complex motion dynamics.
\item OS Versality: We successfully developed a game engine that operates across Windows, Mac, and GNU/Linux platforms, addressing the title of this thesis.
\item Addressed Platform-specific Challenges: Overcame technical challenges associated with different operating systems, ensuring a consistent user experience.
In conclusion, we managed to accomplish all of the goals we set for this thesis, our engine successfuly produces a game for all three operating systems we were aiming for.
Creating this game engine was a long process, it took almost a year to bring it to the state it is now in, during this time several reflections came about.
In order to overcome differences for different operating system, a lot of time was put into choosing correct graphical api and libraries that could work on Windows, GNU/Linux and MacOS. This proved crucial when later developing the engine as this issue did not came back and I could focus on creating the engine itself.
Using multiple different libraries and integrating them with our game engine was a challenge, thanks to existing solutions like learnopengl repository which already overcame those difficulties and KDevelop easy approach to external libraries it was possible to implement all of libraries within our game engine.
Lastly, probably the biggest challenge was managing time for this thesis. Finishing it required a lot of determination, setting barriers and working every day to ensure that the thesis is finished on time. Thankfully past experiences helped in guiding through this task that could be compared to colossus.