This is an overview of some projects I worked during my free time.
They range from very small prototypes to bigger projects with lots and lots of code.
Survival Prototype Engine - Sega Saturn
This project is an excuse to code for the Sega Saturn, which is a very complex machine. My idea is to create an engine which is capable of running games in the style of 90's survival horrors like Resident Evil, Alone in the Dark or Silent Hill. In my demos, I'm using RE2 assets because of how hard the game pushed the Playstation hardware back then. I want to achieve at least the same functionality in the Sega Saturn, so I wrote import scripts to extract the original game data to Blender and other popular formats and created new formats tailored for the new engine.
All the fun in this project comes from the fact that the Saturn is a very weird console. It features 2 Hitachi SH2 processors, a SCU-DSP capable of running 6 instructions per cycle in parallel and has only 2MB of RAM (also no FPU, no z-buffer, no UV maps and divisions are really expensive). Programming it also requires building almost everything from scratch. I use and contribute to libyaul and create my own functions for everything else (binary search, sorting, etc).
- Multithreaded renderer, using both SH2 CPUs to process vertices, normals and lighting
- Animation matrix is stored as two component euler angles and expanded in real time
- Lighting is computed as a directional dot product against 8 AABB normals, then face normals are checked against those
- Models are processed in parallel in the DSP (custom ASM program) and the CPUs. The DSP process the list in ascending order whilst the SH2 process in descending order
- Depth sorting happens in visible faces (computed against the near plane) and uses 16-bit radix sorting (quick sorting, merge sorting and bucket sorting were too slow/imprecise)
- Virtual machine for the game code
- Custom animation format featuring skeletal animations
- Collisions using AABB, OBB, spheres, cylinders, triangles and ray casting
- Enemy path finding, boid behavior and logic
- Python and Powershell scripts for importing the original game data and converting to the new engine
- Import of models and animations directly to Blender
- Import of PCM audio and mpeg backgrounds
- Import of room .RDT files with camera information, sprites, masks, collision
- Export models and animations from Blender
- Deferred renderer with a forward pass for transparent objects (G-Buffer with lighting, position, depth, normal, material id and specular intensity):
- Dynamic programable shaders on GLSL (with hot reloading)
- Shadow maps
- Post processing shaders (with many built-in effects like SSAO, Gaussian Blur and color filters)
- GPU sprite / particle support and instancing
- Configurable material system
- Scene Management with a software rasterizer for occlusion culling
- Sound through OpenAL
- Networking via UDP with packet compression, ordering and movement interpolation
- Model and skeletal animation support using the MD5 format (with shared skeletons)
- Integration with Qt (built-in Model Viewer) and Python scripting support (SWIG)
- Resource management (with cached resources), work-stealing and multi-thread support.
- Triangle meshes
- Textures with UV maps
- Cook-Torrance BRDF
- GPUs accelerated kernels using OpenCL (similar to OneAPI from Intel)
- Ray casting acceleration using BVHs/kdtrees/Quadtrees/Octrees/SplitOctree
- Early out with russian roulette
- Denoising with Intel Open Image Denoise
- Mixed frames from CPU and GPU on a progressive display
- Gameplay programmed in C++, everything else in blueprints
- 'Board game' game mode from scratch including netplay
- Character movement with terrain rules
- Dynamic generated characters with different skins/cloth/model attachments
- Custom exporter from Blender to a map format digested by UE4
- Characters modelled and animated on Blender, textured on Gimp
- Custom AI using behavior trees, path finding and minimax
- Real time renderer using OpenGL ES
- Dynamic shadows in real time (shadow maps)
- Cube maps generated and used for reflections on scene change
- Automatically baked AO (could also be bundled with object in another channel)
- Fake BRDF materials with 'metalness', diffuse and specular
- Supported animated objects from a custom format
- Supported all iOS devices with the locked 30 fps
- Car control with correct physics simulation for low speed (no drifting)
- Fake sprite rotation
- Fixed point 16 bit math for precision
- Collision against other scenario parts and other cars
- Map (from Tiled) loaded and painted in real time while driving
- Multithreaded software rasterizer
- Custom exporter from Blender to a header file
Resident Evil is copyrighted and it is a property of Capcom. All assets are converted from the original Playstation disks and are not meant for redistribution.
cgTech1 (Game engine)
My own game engine to learn OpenGL, math and networking. Worked on this on my free time and pushed new features as much as I could, until life got too busy. I was able to make some demos with it.
Toy path tracer
During my masters I started writing a ray tracer which later evolved to a simple path tracer.
Spiderman Dynamic Forces
Spiderman Dynamic Forces (SMDF) was my first contact with game development. It started as a total conversion mod for Quake 3 by a small team in the early 2000's and I joined them initially as an artist and later as a programmer (I was 16 back then). I did almost all the gameplay programming for the mod and also fixed some tools here and there. I was really young and naive but this project pushed me to learn C and C++ better, which worked pretty well :) The project was closed around 2004 when the team got a cease and desist later from Marvel. During the development of the mod we had some game magazines publishing articles about us and got featured on some news sites. It was a pretty cool experience.
Fast forward to 2015, I decided to learn more about Unreal Engine 4. I thought about porting the old ideas I had from SMDF but of course not everything. I converted a map directly and redid Spidey animations on Blender. I ended up with a C++/Blueprint implementation on UE4 for the wallcrawling, double jumping and the swinging mechanics (all with netplay code).
This was my last attempt at building a game by myself. I used Unreal Engine 4 to reduce the amount of work I had to do but in the end it was still too much. I did everything from programming to animation, including the character design and the tools used during the process. Eventually I gave up as this was such a big task that was taking too much of my free time. I was also doing a masters degree during this time so I opted out of this project in lieu of sanity.
In 2014 I was hired as a freelancer to build a 'furniture viewer' for iOS. I was a certified apple developer back then and thought that it would be a cool project to learn more about graphics programming on mobile devices. I did the entire application from scratch to make it as fast as possible, since Unity was really heavy and expensive (back then). The goal was to run this on an iPad 3 and iPhone 4, hence the limitations. The app was never release due to a budget problem but it was a fun experience anyway.
Sega Genesis car demo
I wanted to investigate and know more about car physics and how to work with fixed point math, so I wrote this demo for the Sega Mega Drive/Genesis using SGDK.
At university, one of our assignments was to make a little renderer to display a fixed scene. I had the idea of making instead a car racing game copying enduro on the atari. I did a software renderer, created the cars and the track on blender and used them for the game. I used SDL for the window/OS handling.
I made this little control board as an exercise to learn electronics cad and also to give me a comfortable way to use my SNES 8bitdo controllers on the de10-nano. I designed the board on kicad, developed the code for both arduino's and bought the components on the internet. It works!
Sega Saturn USB cartridge
This was my introduction to soldering SMD components, to build a Sega Saturn USB cartridge (https://antime.kapsi.fi/sega/usbcart/). I did all the soldering and the second cart was the one that worked, the first one almost burned my house down :)