[{"content":"A 2D world generator that runs on the GPU to achieve blazing speed.\n","permalink":"https://connordemeyer.net/posts/gpu-2d-world-generator/","summary":"A 2D world generator that runs on the GPU to achieve blazing speed.","title":"GPU-based 2D World Generator"},{"content":"I have been working on a roguelike centered around naval combat. In this blog post I will detail my progress and talk about some interesting parts of the project.\nWorld Generation I have been working on a world map that the player has to navigate from the left to right. Every hexagonal tile will have a random chance of having either a battle, treasure, or random event similar to other roguelike games.\nThe visuals are still a prototype, but I\u0026rsquo;m very happy how it has turned out so far. The effect is purely shader based using a height map. There is no mesh being generated.\nTo create the effect I used an algorithm that is similar to wave function collapse to generate 2 tree-like connected graphs at each side. Towards the center of the map the rivers are more narrow compared to the edges.\nAfter that I connect both trees at specific locations and I make sure that the new connections make it possible to reach one end of the map from the other.\nFor each tile I draw a circle on a Render Texture depending on the size of the tile and then I draw the connections using lines that smoothly connect the circles.\nAfter all the circles and lines are drawn to a Render Texture I process the texture using the Signed Distance Function texture processing technique described in this paper: https://lnkd.in/gV6vHi_c\nLastly I wrote a custom shader that interprets the values in the signed distance field texture as height to get the direction of the normal at each pixel and use the same height value to choose a color from a color gradient.\n","permalink":"https://connordemeyer.net/posts/naval-combat-roguelike/","summary":"A roguelike centered around naval combat featuring procedural world generation with shader-based visuals, signed distance fields, and wave function collapse-inspired algorithms.","title":"(WIP) Naval Combat Roguelike"},{"content":"Code reflection and type information are essential concepts in programming that play a significant role in various software development processes, particularly in the realm of game development and the creation of editors.\nCode reflection is the ability of a program to examine and manipulate its own structure, data, and behavior during runtime. It provides developers with the means to inspect classes, methods, fields, and other program elements, as well as to interact with them dynamically. This introspective capability allows for powerful runtime operations like object instantiation, method invocation, and dynamic loading of classes.\nIn the context of game development, code reflection and type information offer several benefits, particularly when creating custom editors for game content, levels, assets, and more. Here\u0026rsquo;s how they help:\nDynamic Editors: Game development often involves creating custom editors to facilitate the design and manipulation of game content. Reflection allows these editors to inspect the structure of game objects and assets at runtime, providing a dynamic and user-friendly interface for modifying properties and behaviors without recompiling the entire project. Efficient Workflows: By utilizing type information, game developers can build tools that understand the relationships between different types of game data. This knowledge enables the creation of streamlined workflows for content creation, as editors can present relevant options and information based on the context. Modularity and Extensibility: Reflection and type information enable the development of modular systems where new features, components, or assets can be added without extensive manual integration. Editors can discover and present new content automatically, reducing the need for manual configuration. Debugging and Testing: Reflection assists in creating debugging and testing tools that can analyze the state of game objects and assets during runtime. This aids in identifying issues and optimizing performance. Data-Driven Development: Many modern games rely on data-driven development, where game behavior is defined by external data files. Reflection and type information support this approach by allowing editors to parse and validate these data files against the expected structure. Glassify Glassify is a simple customizable Header-Only Reflection System for C++. It allows the user to easily reflect upon types wherever they are inside of the codebase. The reflection data is generated before the main function is executed. The developer can choose which data gets stored inside of the reflection system by adding code to the config header files.\nFeatures Reflecting Types: Glassify allows for easy reflection of types using a simple Macro: GLAS_TYPE() Member Variables: member variables can also be reflected using the macro GLAS_MEMBER() Functions and Member Functions can be reflected and called at runtime using the macros GLAS_FUNCTION() and GLAS_MEMBER_FUNCTION() Serialization: fields can be automatically converted to binary data or formatted using the serialization system. Instancing: any reflected type can be instantiated on the heap at runtime using the Type ID for that type. Example struct Transform { float x, y, z; float rotation; }; GLAS_TYPE(Transform) GLAS_MEMBER(Transform, x) GLAS_MEMBER(Transform, y) GLAS_MEMBER(Transform, z) GLAS_MEMBER(Transform, rotation) Links GitHub Repository ","permalink":"https://connordemeyer.net/posts/cpp-reflection-system/","summary":"A customizable, header-only runtime reflection system for C++ — inspect types, fields, and functions at runtime with macro-based registration.","title":"Glassify — C++ Reflection System"},{"content":"If you have ever been a developer on a non-trivial application, you will have noticed that every time you want to make changes to the project you have to recompile and restart the program for the changes to be applied. The time lost can vary between mere seconds to multiple minutes, just to recompile a tiny fraction of the program.\nThere are ways to get around this issue. Some programs use a more data centered approach, making it easy to save and load files at runtime to change the program. Most game engines use this to load and save levels. This works great for saving settings or hierarchies of objects.\nScripting languages are also a great way to change how a program works at runtime. Languages like Lua, JavaScript, and Python allow the user to change the functionality of a program without having to recompile the entire program. A visual scripting language is a scripting language but used as a Graphical User Interface (GUI) instead of a text editor like the examples given, making it more accessible to people that aren\u0026rsquo;t programmers.\nUnreal Engine Blueprint Visual Scripting Language Example\nTypes of Scripting Languages There are 3 ways a visual scripting language may execute its code:\nCompiled: The nodes and links are compiled into byte-code that is able to run on a virtual machine created by the developer. The upside to this method is that the developer is able to define a virtual system with its own features that a normal CPU might not have. The downside is that it will not run as fast as compiled machine code on the CPU. This method is used by Unreal Engine.\nTranspiled: The node network is used to generate code from another language that is then compiled using that language\u0026rsquo;s compiler. This method is not as versatile as the virtual machine method and the user has to do his own linking, but the results will be faster if the developer uses a sensible intermediate language. Shader graphs usually use this method to generate GLSL, HLSL code.\nInterpreted: This method does not compile into anything, instead it is similar to a parser. It will execute code while going over the graph step by step. The execution of this method is usually slower than the methods mentioned before as it has to interpret the node graph while executing. It has uses in applications like Houdini, where the graph only has to be executed once it is edited.\nIn my project I went with the Transpiled approach as this method simplifies the compiling process dramatically by offloading the intricate compiling to an existing C++ compiler.\nTransforming into Intermediate Language The Transpiled method requires us to first parse the graph and transform it into another language that can be compiled and executed. In my project I used C++ as the Intermediate Language as it is a very flexible language and is fast to execute when compiled.\nExample Graph for function called \u0026ldquo;Demo\u0026rdquo; that randomly either prints a random integer or draws a circle on the screen\nOutput of parsing graph\nNote that functions and types have an identifier next to them. This identifier is part of a reflection system that contains information about the type or function. We will use that information later on in the linking stage when loading in the compiled machine code.\nEach function also has extern \u0026quot;C\u0026quot; in front of the name, this is to ensure that the name doesn\u0026rsquo;t change or get mangled when using a C++ compiler.\nLinking After the node graph has been compiled into C++ source code using the Transpiled Method and then compiled into binary machine code, it is necessary to also load that data and link any unresolved references that the object file may have.\nWhen loading in that object file we first have to link internal data. Some variables or functions might need access to data that is not stored inside of the code section of the object file. A good example could be string literals. These literals get stored in another header than the binary code for executing code.\nMost unlinked values have to be linked by adding a relative offset to the relocation address that points towards where the value is located. Although some symbols are declared externally, meaning that the symbol that it has to be linked with was defined inside the source file but implemented somewhere else. In that case we have to first find that symbol somewhere else in memory. I do this by using the Function Information stored inside of the reflection system.\nFinal Result ","permalink":"https://connordemeyer.net/posts/visual-scripting-language/","summary":"A node-based visual scripting system that transpiles to C++, compiles to machine code, and links at runtime — enabling near-native performance with hot-reload.","title":"Visual Scripting Language"},{"content":"An Entity Component System (ECS) is a software architecture used primarily for video games where entities are comprised by components of data. This data is stored as closely to each other as possible for easy and fast reading and modification. This architecture heavily benefits from CPU memory caching which improves performance.\nEntity An Entity consists of 2 elements:\nEntityId: either a 4 or 8 byte unsigned integer depending on the system architecture EntityRegistry reference: A Reference to the Entity Registry it is contained in The EntityId is the most important part of the Entity class. When interacting with the Entity Registry it is only necessary to have the EntityId to add/remove/get Components.\nGame Object The Game Object class is a wrapper class for the Entity class. It allows for easy adding/getting/removing of Components and will remove itself from the registry upon destruction.\nComponent A Component is any class or struct that contains data. It does not have to inherit from any base class. It should have its move constructor and operator= intact for it to be able to work.\nMember methods can be added to personalize functionality for various stages of the Components lifetime:\nSerialize(std::ostream\u0026amp;): define custom Serialize logic for when the Component has to be serialized to a stream. Deserialize(std::istream\u0026amp;): define custom logic for initializing Component reading from a stream. Initialize(EntityRegistry*): custom logic for when the Component is added to the registry. bool SortCompare(const Component\u0026amp;, const Component\u0026amp;): custom logic for when Components have to exist in a sorted state as much as possible. Default System Methods: methods that will automatically be called without having to create a system for it. References Because Data is stored in contiguous array, they will sometimes have to move whenever the underlying array has to resize. Because of that, references/pointers to components are passed around by Reference\u0026lt;Component\u0026gt;. It contains a pointer to the class ReferencePointer\u0026lt;Component\u0026gt; that is static in memory and contains the pointer to the Component. Every time the underlying array gets resized, all the ReferencePointer\u0026lt;Component\u0026gt; get their pointers updated. These are similar to std::shared_ptr as they will always point to either a valid component or a nullptr in case the Component has been removed. They will also only be deleted from memory when no reference exists that points to it.\nEntity Registry The EntityRegistry is the class that contains all the Entities, TypeViews, and Systems. It is a controller responsible for managing most resources and is the most important part of the ECS. It contains an Update(float deltaTime) method that should be called with the deltaTime whenever you want to update the Entities, Components and Systems.\nType View The TypeView\u0026lt;Component\u0026gt; class is the container for all the Components in a registry. It is responsible for managing the References and resizing data whenever it needs to.\nType Binding TypeBinding\u0026lt;Components...\u0026gt; are similar to Type Views as they allow quickly accessing multiple Components that are all connected to the same Entity. Type bindings can be initialized with any amount of Components as long as the number is bigger than 1. Example:\nauto typeBinding = TypeBinding\u0026lt;Transform, Physics, Render\u0026gt;{...} will create a TypeBinding that contains references to the Components Transform, Physics, Render. Whenever an entity exists with these components it will be added to the TypeBinding. You may then access the references and call functions on them and/or transfer data between them. It also contains a method to call function on them. For example:\nApplyFunctionOnAll\u0026lt;Transform, Physics, Render\u0026gt;( [](Transform\u0026amp; transform, Physics\u0026amp; physics, Render\u0026amp; render) {...} ); Will call the lambda function on the mentioned Components of an Entity that contains all of them.\nWarning: you may only have one TypeBinding with the specific Components. You may not have TypeBinding\u0026lt;Transform, Render\u0026gt; and TypeBinding\u0026lt;Render, Transform\u0026gt; at the same time. This also applies for Systems.\nSystem A system is a process that modifies or acts on one or multiple components. All Systems inherit from SystemBase, an abstract class that contains the following virtual methods that can be overridden in a custom System:\nExecute(): Should contain the functionality of the system, modifying or using the components. Initialize(): Is called after construction when the TypeView or TypeBinding is set. When constructing a System it requires SystemParameters which contains the following information:\nName of the system Execution time: an integer to specify when it should execute compared to other systems. Systems with lower Execution time will execute before Systems with higher Execution time. Update interval: How long it takes between each Execute call. If 0 it will execute every frame. Systems also have the method GetDeltaTime() which returns the deltaTime variable. This may be different for each system depending on the Update Interval.\nAll Systems should have a constructor taking only const SystemParameters\u0026amp;\nView System System that contains a reference to a TypeView and used to act on a specific Component. You can get the Type View by using the GetTypeView() method.\nBinding System System that contains a reference to a TypeBinding and used to act on multiple Components at the same time. You can get the Type Binding by using the GetTypeBinding() method.\nDynamic Systems Dynamic Systems are either View Systems or Binding Systems that are easy to create as they only need a function taking the Component References as input parameters.\nThere also exist Dynamic Systems DT (deltaTime) taking the same type of functions but with a float parameter at the start.\nSub Systems Sub Systems are systems that act on Components that inherit from other Components. A system will get made calling the same function on the derived class. This way you can still get access to polymorphic function calling.\nDefault Systems These systems are created whenever a specific method exists in the Component. When any of the following methods exists a system will automatically be created to call them:\nPreUpdate(float deltaTime) Update(float deltaTime) LateUpdate(float deltaTime) Render() LateRender() You can also specify the Update interval by creating a static floating point variable inside the class given the corresponding name:\nPreUpdateInterval UpdateInterval LateUpdateInterval RenderInterval LateRenderInterval Example:\nstruct Transform { static constexpr float UpdateInterval{ 0.16f } void Update(float deltaTime); }; Sorting Whenever Components have to exist in a sorted state you can specify a function by the signature of bool SortCompare(const Component\u0026amp;, const Component\u0026amp;). If this function exists the Components will try to stay in a sorted state as much as possible. You can query the sorting state of a TypeView using the function GetDataFlag() and the data flag id using GetDataFlagId(). The data flag Id changes whenever the data becomes dirty again. This way you can check in between the data being dirty if it changed again. The algorithm used for sorting is SmoothSort, which is a sorting algorithm that comes close to O(n) when the data is already mostly sorted.\nSerializing A Registry is able to completely convert itself into a stream of bytes and then convert that stream back into all the original components.\nIf you want to define custom Serialize and Deserialize functionality to Components they should contain methods with the following signature:\nSerialize(std::ostream\u0026amp;) for converting the Component into a stream of data Deserialize(std::istream\u0026amp;) for converting a stream of data into a component When Deserializing, the amount of data it takes from the stream should be the same as the data it puts into the stream when Serializing. Whenever this doesn\u0026rsquo;t apply an exception will be thrown.\nStreams should be used in binary mode\nReflection Inside the TypeInformation/reflection.h contains various functions that will convert Types to std::string_view and uint32_t at compile time. This can be used with std::unordered_maps to create simple type mapping and is used at various times in this framework.\nBecause Serialization requires some form of previous setup before the Deserialization happens, it is necessary to register the existence of Components and Systems using static variables. The TypeInformation/TypeInfoGenerator.h header file contains various helper objects that will generate the necessary data without much trouble. The following can be used:\nRegisterClass\u0026lt;Component\u0026gt; any_name(): Will create some type information and make it possible for views to be added at the Deserialization stage. RegisterChildClass\u0026lt;Base, Inherited\u0026gt; any_name(): Will mark the types as child and parent and will then generate Sub Systems whenever the base class is used in a System. You may also use the Cast() function which replaces the dynamic_cast() that is disabled. RegisterSystem\u0026lt;System\u0026gt; any_name(const SystemParameters\u0026amp;): Will register the System using the System Parameters. It will then be able to add the System to a registry using the name in the System Parameters. RegisterDynamicSystem\u0026lt;Components...\u0026gt; any_name(const SystemParameters\u0026amp;, const std::function\u0026lt;Components...\u0026gt;\u0026amp;): Same as RegisterSystem but as a dynamic system. RegisterDynamicSystem\u0026lt;Components...\u0026gt; any_name(const SystemParameters\u0026amp;, const std::function\u0026lt;float, Components...\u0026gt;\u0026amp;): Same as previous but with deltaTime. Links GitHub Repository ","permalink":"https://connordemeyer.net/posts/entity-component-system/","summary":"A custom data-oriented ECS implementation in C++ with cache-friendly contiguous storage, safe references, built-in serialization, and automatic system generation.","title":"Entity Component System"},{"content":" The Lorentz Factor is a game made in Unreal Engine 4 using C++ and blueprints. This game was originally a blueprint only prototype for the Game Design course at DAE.\nPlay It The Lorentz Factor on itch.io ","permalink":"https://connordemeyer.net/posts/the-lorentz-factor/","summary":"A game prototype in Unreal Engine 4 where the player can slow time in an area while moving at normal speed — inspired by relativistic time dilation.","title":"The Lorentz Factor"},{"content":"Open Demeyer 2D is the second Engine I have tried to make. It is an engine for making 2D games and uses SDL and OpenGL to render the images to the screen, making it possible to compile for most platforms.\nImGui I use ImGui to make the Graphical User Interface of this engine.\n\u0026ldquo;Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).\u0026rdquo;\nYou can read more about ImGui here: https://github.com/ocornut/imgui\nComponents \u0026amp; Scene Graph The game consists of various scenes and every scene consists of game objects who themselves contain components to define their functionality.\nDuring gameplay only one scene gets updated and rendered to the screen. All the other scenes remain inactive in memory but can be switched to at anytime.\nThis allows us to load and unload scenes during gameplay on different threads and can greatly improve loading times.\nFor this engine I decided to only use components to define entities. All Game Objects contain a set of components that define their behaviour. This way we can easily add functionality without using inheritance. This is close to what an Entity Component System does.\nI also added the possibility to add ImGui interfaces that can change functionalities of components while in game.\nGame window The game window shows the current scene before being initialized. You also have the option to play the game, which will instantiate the current scene and starts the update loop making it possible to play the game while in the viewport.\nDuring gameplay you have the option to pause and stop playing, allowing you to quickly return to the editor and change values around.\nYou can also left click to select objects and quickly inspect/change the components.\nIf more than one objects are behind each other you can also right click them to get a list of objects which can be selected.\nEngine Settings I have also implemented a way to save and load engine and game settings in between sessions.\nYou can set a bunch of different settings ranging from the resolution and window size to the title of the screen and more.\nMore settings can easily be added inside of the engine.\nRender Information The Render Information tab gives the user information about the rendering of the engine. It shows the multiple layers that the user can use to render to.\nIt also has the option to display the hitboxes and physics actors of the game.\nSaving and loading (File parsing) I added the ability to save and load the game, scenes or objects using files.\nThis system allows me to stop using the code editor to create the world and makes it easier to acquire the results in the engine without having to change the code and having to recompile every time I want a small change in the game.\nThis file saving system is completely dynamic and I\u0026rsquo;m able to implement a new component in a different project and add it to the engine without having to change or add any code in the engine.\nType information At the start of the game I generate specific type information for each component which allows me to parse files and quickly copy or duplicate values from components and game objects.\nEach component has the ability to override a specific function and define their own serializable fields. These fields will be saved to files and will be loaded in when parsing a game/scene/object file.\nThese are similar to how Unity does the [Serializable] fields.\nBehind the scenes there is a singleton that will save this information and gives other parts of the program access to them.\nFor the loading of files I use the Class Generators to instantiate the components.\nLinks GitHub Repository ","permalink":"https://connordemeyer.net/posts/sdl-opengl-engine/","summary":"A cross-platform 2D game engine built with SDL and OpenGL, featuring a Dear ImGui editor, component-based architecture, and dynamic save/load system.","title":"OpenDemeyer2D — SDL OpenGL Engine"},{"content":"Fruut Wars on itch.io — by Lucy Lesire, Connor De Meyer, lvanmalder, konzui, DylanBoddaert\nFruut Wars is a game created by me and 4 other students.\nFruut Wars is a couch player vs player shooter game where your goal is to eliminate the other players by using fruits as weapons. Each player will be able to pick a character that resembles a fruit or vegetable and use this fruit or vegetable as a weapon.\nDuring the game the players will be able to throw fruits at other players to eliminate them, per elimination a player will be able to gain points. The game will be played in rounds, once there is only one player left in a round, the game will move on to the next round, with a reset map and health.\nDuring the game players will be able to shoot on crates to break them, giving them the option of picking up bonus weapons. Each bonus weapon will have a special ability that can be used a set amount of time. Furthermore, the players will be playing on an interactive map that slowly disappears, making the playing field smaller.\n","permalink":"https://connordemeyer.net/posts/fruut-wars/","summary":"A couch PvP shooter where players use fruits as weapons, built in Unreal Engine as a group project.","title":"Fruut Wars"},{"content":"In the 4th semester of DAE we are given the Graphics Programming 2 course. During this course we are first tasked with adding functionality to the Overlord Engine. Our teachers took out important parts of the engine like animations, text \u0026amp; image rendering, shadow mapping, particles and post processing for us to implement them.\nWorking with the Overlord Engine The Overlord Engine is a 3D game engine used at DAE to teach the Graphics Programming 2 course. It is programmed in C++ and has no visual tools to aid in game development.\nWe learn a lot of techniques that are used in the game industry by implementing various additions to the engine and working with the various frameworks that it comes with.\nPhysX In the Overlord Engine we use the PhysX engine for all physics related components. It can be used on the CPU or GPU and even on smartphones.\nIt is a powerful piece of software developed by NVIDIA and a must have for anyone that wants to have 3D physics for his engine or game.\nFMOD FMOD is the library we use to play and mix sounds. We use it to play sounds in a 3D environment and/or directly to the headphones. It also has the possibility to take velocity of the listener into account and elevate the user experience.\nHLSL Shaders For making the shaders used in the engine we use High-Level Shader Language (HLSL), which is a shading language used for programming shaders for Direct3D.\nUsing HLSL we are able to use the graphics card to its full extent and we are able to use various techniques to bring images to the screen.\nAlthough the engine comes with its own shaders to draw meshes, we had to implement some shaders on our own to become more familiar with HLSL.\nUsing the GPU\u0026rsquo;s geometry shader and pixel shader to quickly draw Sprites to the screen with a bunch of parameters to change the layout of the sprite\nUsing the geometry shader of GPU to add spikes to any surface\nUsing both the geometry shader and the pixel shader to quickly add text to the screen\nAnimations using the GPU We also needed to implement animations on our own. First we made a basic animation that uses the CPU, but turns out that animations are very expensive and take up a lot of data.\nWe then implemented animations for the GPU which transforms all the vertices quickly using its parallel computing capabilities.\nAdding a socket system Unfortunately the engine itself did not come with a way to attach actors to bones. So I had to be creative and try to implement one myself.\nI started running into issues right from the start: Because the Overlord Engine uses its own file system, there is no information available online that could help me get bone information and transformation data out of the file.\nBut after analysing the binary data inside the files and some trial and error I was able to extract the right information and implement a socket system into the Engine.\nHitboxes Because hitboxes can become quite expensive to simulate we have to be quite careful when adding hitboxes to the game.\nEach enemy has a total of 11 hitboxes: 1 big Capsule hitbox that can interact with and block objects in the world. We only use 1 hitbox for interfacing with the world, that way we can get a better performance.\nThe other 10 hitboxes give the enemies a precise hitbox for our bullets to hit. I also set it that these hitboxes cannot interact with each other or the world around them, only bullets from the player/other enemies.\nThese smaller hitboxes are also attached to the sockets that I created for holding the gun. This way we can move them dynamically with the movement of the animation.\nBullet Trail Line Renderer Using the Geometry shader of the GPU and the Adjacent Line input geometry I managed to add a simple trail to the bullets as they travel through the air.\nFinished Project ","permalink":"https://connordemeyer.net/posts/super-hot-remake/","summary":"A remake of SUPERHOT built in the Overlord Engine with custom PhysX integration, GPU skinning, HLSL shaders, and a reverse-engineered socket system.","title":"SUPERHOT Remake"},{"content":"At DAE we were taught about different Artificial Intelligence techniques for video games. We started off with simple steering behaviours that would steer an actor towards a specific direction depending on the situation. We were then taught about pathfinding algorithms which we then applied on a Navigation mesh. After that we were introduced to Decision Making Structures to make complex behaviours. And last of all we were introduced to the basics of Machine Learning.\nSteering Behaviours For the first lesson we had to create multiple different simple steering behaviours which would steer an actor in a certain direction. Some examples are:\nSeek: Move straight towards a target Flee: Move in the opposite direction from where the target is Wander: Move around in a semi random direction Pursuit: Intercept a moving target Circle: Circle a target Hide: Hide behind obstacles to avoid a target Interpose: Go to the middle of two targets Obstacle Avoidance: Move away from close obstacles We would then combine these behaviours using a weight for every specific behaviour. This would blend the steering behaviours together and create more complex actions.\nFlocking Flocking is a specific type of steering behaviour which takes into account all other agents around him to calculate a direction.\nWe were also informed about space partitioning, which would sort agents into squares and would drastically improve performance.\nPathfinding The next step for AI was to calculate an optimal path around objects. We first started off using an algorithm called Dijkstra, which would find the shortest path using a connection graph.\nWe then optimised this algorithm to A*, which is a more complex but faster pathfinding algorithm.\nNavigation Mesh A Navigation mesh is a bunch of connected triangles that go around in accessible places. Using A* and a way to create a connection graph we can upgrade our pathfinding algorithm to a 2D/3D space and increase precision.\nDecision Making One of the most important parts of an AI is its decision making structure. The structure decides which behaviour an actor should do and when to do it. We were taught 3 decision making structures:\nFinite State Machine: contains a bunch of states and connectors between those states Behaviour Tree: always starts with a top decision which chooses the decisions beneath it, and so forth Influence Map: uses a grid which gets populated with good and bad squares depending on what is on it. It then goes towards the most favourable square Exam Assignment For our exam assignment we were tasked to create an AI for a simple zombie game they provided to us. We weren\u0026rsquo;t allowed to see the source code of the actual zombie game and our actor was only able to see entities in front of him inside of a small cone.\nWe had to fill our own behaviour structures and blend steering behaviours while also managing the inventory and dodging/killing zombies.\n","permalink":"https://connordemeyer.net/posts/artificial-intelligence/","summary":"Game AI techniques including steering behaviours, flocking with space partitioning, A* pathfinding, navigation meshes, and decision making structures.","title":"Artificial Intelligence"},{"content":"\nA from-scratch C++ 2D game engine built directly on the Windows API, created as a learning project to understand low-level Windows programming.\nCore Technologies System Technology Windowing/Input Win32 API 2D Rendering Direct2D Text Rendering DirectWrite (DWrite) Audio XAudio2 Image Loading WIC (Windows Imaging Component) Major Systems Windows Message Queue The windows messaging queue allows us to receive and process the input of the player.\nAt the start of the game loop we process all messages that the user may have sent. depending on which message it is we handle it accordingly. (see image above)\nEvery time a person either uses his mouse, moves the window, presses a key, closes the window, etc., a specialized message is sent to the engine. This message contains the id of the message and other extra information depending on the type of message.\nthe id of the message needs to be processed using either a switch case or a hash map, either is fine because sending a message is rare compared to other processes that the engine will do.\nThe extra information that a message can contain depends on the id. when a keyboard button is pressed it will provide the keycode for that specific key, allowing us to process that key using the engine.\nWhen the mouse is moved it will include a 2 dimensional vector which contains the cursor location on the screen.\nThere are a bunch more messages but these are some of the most important if you’re making an Engine.\nDirect2D For this Engine I used Direct2D as a rendering backend. It is an extension of the DirectX API and is included in standard windows.\nIt specializes in Drawing 2D shapes and images onto the screen without having to setup a 2D environment using a 3D backend.\nUsing Direct2D you are able to draw lines, Rectangles, Rounded Rectangles, Ellipses, Circles, Polygons, Bezier curves and Bitmaps (images).\nDirect Write To display text to the screen I used the Direct Write (DWrite) API that is also standard on windows computer.\nIt allows you to generate font data at runtime, which allows you to draw text to the screen in any dimension or style.\nXAudio2 XAudio2 is the latest Audio API from Microsoft that is included in windows.\nIn my engine I used the basic features that the API offers. Playing and looping sounds.\nI was able to produce Sound effect with just a function call and even loop specific parts of the sound file for as many times as the user saw fit.\nComponent System Most Engines use a component system, and for good reason. It allows the programmer to easily add existent pieces of code and simplify the base Objects by offloading many function to specialized components.\nEvery game object has a list of components that can be added and removed at any time. These component are in charge of very basic things and may only have a unique purpose.\nSome examples are: Collision component, Render component, Texture component, Audio component and much more.\nCustom Observer Pattern (\u0026ldquo;Delegate\u0026rdquo;) The observer software design Pattern is an extremely powerful and useful software pattern.\nIt allows the programmer to notify pieces of code that an event occurred without having to know that they exist or what they’re going to do when the event gets called.\nFor example: When the player kills an enemy we various things to happen: The score should go up, the game should get notified that an enemy died, other players need to get that information, etc.\nInstead of having the player class call every function of these different classes, which would make things very messy, we create a Subject to which Observers can connect to and receive data every time the subject wants to relay information.\nUsually this pattern is implemented with inheritance like in Java. I however, decided to take rule 34 of the C++ coding standards to heart:\nPrefer composition over inheritance\nI made a variadic templated class that allows you to make an observer object, which I call a Delegate (inspired by UE4), this object can be placed anywhere. In the example I placed it inside the player class.\nBecause of the Variadic Template I’m able to create an observer that takes any amount and type of parameter for the function calls.\nIn this example you can see how it works in action. Any class or object that can get a reference to the Delegate instance may bind a function to it.\nThat function may later be called whenever the Subject feels necessary.\nThere is however a big issue with this implementation, you can bind member functions that may get invalidated when the instance is deleted.\nThat is why I added the option to also give a predicate that tells the delegate when the function it should call isn’t valid anymore.\nThis Pattern proved so useful that I used it everywhere inside of my code, especially inside of my Input manager.\nInput Manager The input manager is a Singleton that is in charge of processing the users inputs it receives from the windows message queue and translating that to the game.\nAnything is able to bind a function to the input manager and a specified key/button. Whenever that key or button is pressed or activated. The input manager will call the bound function.\nI used the Delegates for this, as it already provides all the logic for binding functions and checking validity of those functions.\nI also added KeyDown , KeyUp and KeyPressed events. The programmer can choose when the event gets fired: the moment the key/button is pressed, when it is is let go, or every frame it is held down.\nThe input manager is also responsible for the mouse location and calling events whenever a mouse button is clicked.\nResource Manager Every engine of course need a way to load Files and translate them into usable resources for the game.\nThe resource manager I created is able to load any image using the WIC image decoder that Microsoft provides. It is also able to load sound and font files so that they may be used in game.\nIt will also detect when a resource is still inside the game using shared and weak pointers. whenever a you try to load a resource that is already loaded inside of the game it will skip the loading process and return a reference to the in game resource.\nCollision System For my Engine I also tried to figure out how to detect when different game objects overlap with each other.\nI created 3 different components:\nA base collision component where the others inherit from A Box Collision Component for objects that want to use a Box collision A Circle Collision Component for objects that want to use a circle collision These components are registered into a Manager that will generate Begin overlap and End overlap events whenever two component start to overlap. It also has the ability to return a list of all components that are currently overlapping with a specific object\nExample Projects Frogger clone — demonstrates the engine\u0026rsquo;s core features Nonogram / Picross Solver This is a Nonogram solver that was made using my 2D engine. It was made for a research topic at DAE. Currently there are only 2 solving algorithms but it is very scalable.\nIf you are interested in reading more about it you can follow the link to the GitHub repository: Nonogram Solver Repository\nLinks GitHub Repository Nonogram Solver Repository ","permalink":"https://connordemeyer.net/posts/2d-win32-game-engine/","summary":"A from-scratch 2D game engine built on the Windows API with Direct2D rendering, XAudio2 sound, and a custom variadic-templated event system.","title":"2D Win32 Game Engine"},{"content":"At DAE we were taught about the different ways to render objects to the screen. We first started off with programming a Software Raytracer that was able to draw geometric objects such as spheres, planes and triangles to the screen. After we were done with the Raytracer we made a software Rasterizer from scratch, teaching us how graphics cards really work. And for the end of the Semester we had to do work with the GPU to make triangles appear to the screen.\nRaytracing Our first assignment was to make a software Raytracer. A Raytracer renderer will shoot a mathematical ray out of the camera for each pixel it has to render. We can then check if the ray collides with any geometrical objects using some math formulas. We can then simulate lighting and shadows by tracing more rays towards the light sources. Each object also had a material/shader that determined how the object would appear on the screen. We implemented some PBR (physical based rendering) shaders to give the objects a realistic look.\nAt the end of this expensive operation we are presented with a realistic looking scene of some spheres and triangles.\nRay tracing meshes We then took this to the next level and tried to render a group of triangles called a mesh. This would affect performance very drastically, so we added an acceleration structure in the form of a AABB (axis aligned bounding box) and used multithreading to speed up the process.\nSoftware Rasterizer Our next assignment was to create a Rasterizer using C++ code. This assignment taught us how GPUs really work as we had to implement the various stages of rasterization. From the Projection stage to the Rasterization stage to the pixel shading stage. We had to implement it all and write a Phong shader to go with it.\nHardware Rasterizer (GPU) We then had to do the same assignment but with the GPU, teaching us the basics of working with DirectX and HLSL to create a Basic Phong Shader.\nBoth the software and hardware Rasterizer really put into perspective how the GPU works and how much is integrated into its hardware.\n","permalink":"https://connordemeyer.net/posts/graphics-programming/","summary":"A software raytracer, software rasterizer, and hardware rasterizer built from scratch in C++ as part of the Graphics Programming course at DAE.","title":"Graphics Programming"},{"content":"For the second semester of the first year we were tasked to remake a 2D game of our choosing. I picked one of my favourite games: \u0026ldquo;The Binding Of Isaac\u0026rdquo;.\nIt didn\u0026rsquo;t matter how we programmed the game, it just had to work and look good. Looking back at the code I wrote for this it really amazes me how far I\u0026rsquo;ve come as a programmer and how much I have improved over such a short amount of time.\nThis project was also featured on the official DAE website along some other students. Click here to go to the page.\n","permalink":"https://connordemeyer.net/posts/the-binding-of-isaac-remake/","summary":"A remake of The Binding of Isaac built during the second semester at DAE, featured on the official DAE website.","title":"The Binding of Isaac Remake"},{"content":"Connor De Meyer C++ Low Level Programmer \u0026amp; Game Programmer\n+81758717359 · connordemeyer@gmail.com · connordemeyer.net · GitHub · LinkedIn\nSkills C++, High performance computing, Low Level programming, Game programming (Engine, gameplay systems, Graphics, AI, animation) Game Design.\nExperience Xai Human Data Team — Team Lead Jun 2025 – Present, Remote from Japan\nOnboarded 400+ new hires In charge of the C++, Gamedev and graphics programmers Close to the HR team to coordinate growth In charge of the hiring pipeline for SWE tutors Conduct interviews for C++, Gamedev and Graphics programming I work closely with people in Palo Alto, Xai HQ Ensure \u0026amp; improve tutor quality Centipede Entertainment — Co-Founder Dec 2023 – Jun 2025, Belgium\nGame Development Website development Game Asset creation CyGames — Internship Feb 2023 – Jun 2023, Japan\nUnreal Engine 4 C++ Motion Matching Framework. Created a library and worked on animation graph. Education Digital Arts and Entertainment — Bachelor in CS and Game Programming Sep 2020 – Jun 2023, Belgium\n3 years of mainly C++ programming and other gamedev related skills (GPU Shaders, Game AI, Game Engines).\nProjects Showcase 2D world generator that runs on the GPU - 2 min Demo Visual Scripting Language that compiles+links to machine code at runtime - 3 min demo C++ Reflection system - Demo video playlist (long) - repository Other projects: connordemeyer.net Downloads Resume ","permalink":"https://connordemeyer.net/resume/","summary":"C++ Low Level Programmer \u0026amp; Game Programmer","title":"Resume"}]