jaakko

sukuvaara

Professional

Junior Software Developer working with C# and ASP.NET in web development at Pinja

Student

Studying game development in a Bachelor of Business Administration degree at JAMK


Highlighted projects

DnDTable

Vocational school final assignment. Includes sprite tile based 2D map editor and a game mode to be used in DnD games.

DnDTable

Year Links
2018-2021 Github

For my vocational degree in computer programming (2018-2021) I had to do a project using technologies taught in the program: C# , WinForms and MSSQL. So I chose to develop a map tool to be used in DnD and other games.

Design

The goal was to have two modes of the tool the level editor tool and the game master tool. With the level editor tool the user could create levels with 2D Tilemaps. After creating the maps for a game night the user would launch the game master tool. In this tool the user could render the maps on a separate screen and keep notes for themselves about the game session for future reference.

Mock up of the level editor

Implementation

State diagram State diagram of the app

The tool opens with a "main menu" from which the level editor and GM tool can be opened

Main menu window

Game master tool

State diagram State diagram of the GM tools

The game master tool consists of two windows that are opened after a game is created. The game window, a full screen window that is placed on the monitor selected in the main menu and should be visible to all players when playing a tabletop game. Then a game master window, from where the gaming session can be managed

Rendered menu in the game mode

GM tools

GM tools in the game mode

In the game master tools levels can be loaded and drawn on to the game window. Additionally the game master can keep notes of the session on the game master window. Both of these options are saved into a MSSQL database from which they can be fetched again when the gaming session in continued.

Tilemap level editor

State diagram State diagram of the level editor

The level editor is divided into two sections. On the left the map itself and on the right the controls.

Map

The editor shown portion of the map and can be navigated with scrollbars horizontally and vertically. The editor consists of the map tiles which can be clicked on to place a tile texture on them or clear it.

Map of tiles in the editor

The tiles are implemeted as images that windows forms draws based on camera location and grid coordinates. The selected tile is calculated when mouse moves over the grid. This is for highlight etc. When mouse is clicked on the grid the selected tile is updated with the new tile information.

Code snippet
foreach (Tile tile in level.Layers[(int)layerSelection.Value].Tiles)
{
    int tileX = tile.X * tileSize - cam.Location().X * tileSize + cam.FovX / 2 * tileSize;
    int tileY = tile.Y * tileSize - cam.Location().Y * tileSize + cam.FovY / 2 * tileSize;

    if (pos.X > tileX && pos.X < tileX + tileSize)
    {
        if (pos.Y > tileY && pos.Y < tileY + tileSize)
        {
            if (tile.X < cam.Location().X + cam.FovX / 2 &
                tile.X > cam.Location().X - cam.FovX / 2 &
                tile.Y < cam.Location().Y + cam.FovY / 2 &
                tile.Y > cam.Location().Y - cam.FovY / 2)
            {
                selectedTile = tile;
            }
        }
    }
}
                                

Controls

In the controls panel there are UI for level file handling, layers, minimap and the tilemaps.

Editor tools
Level files

The user is able to save the level into a file using JSON data format. To accomplish this I created a static FileHandler class that can save a level and load a level. To keep the file size small only tiles with an image are saved and all other are removed as for each saved tile the coordinates are saved with the image details so that the level can be re-constructed.

Code snippet
public static void SaveLevel(Level lvl, string path)
{
    Level level = new Level();
    foreach(TileMap map in lvl.Maps)
    {
        level.AddAMap(map);
    }
    foreach(Layer layer in lvl.Layers)
    {
        Layer newLayer = new Layer();
        foreach(Tile tile in layer.Tiles)
        {
            if (tile.Image != null)
            {
                Tile newTile = tile;
                newTile.PrepareForSaving();
                newLayer.AddTile(newTile);
            }
        }
        level.AddALayer(newLayer);
    }
    JsonSerializer serializer = new JsonSerializer();
    using(StreamWriter wr = new StreamWriter(path))
    {
        using(JsonWriter writer = new JsonTextWriter(wr))
        {
            serializer.Serialize(writer, level);
        }
    }
}
                                
Layers

The user can add layers of tile grids to the level which are then rendered on top of each other. With this the user can create complex sceneries with simple tilemaps.

Minimap

Due to the limited size of the grid that can be shown at a time, the editor draws a minimap of the level for the user to be able to have a clearer image of the whole map. This is done by selecting a tile for an coordinate from the highest layer, that has an image. Then the image is scaled to 1 pixel size and placed on to the minimap.

Code snippet
public static Color GetPixel(Image image)
{
    Bitmap bitmap = new Bitmap(1, 1);

    using (Graphics g = Graphics.FromImage(bitmap))
    {
       g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
       g.DrawImage(image, 0, 0, 1, 1);
    };

    Color color = bitmap.GetPixel(0, 0);
    return color;
}
                                
Tilemaps

Tilemaps are 2D images that consist of drawn tiles of specified width and height. This image can be then parsed into seperate tiles, from which a level can be built from. When adding a tilemap the editor asks for the path of the image and the size of the tiles. After this information is given the image is seperated into tile buttons. When clicking a tile it becomes selected and can then be placed onto the level. These tile buttons are implemented with WinForm buttons.

Long Laugh The King

A game about trying to entertain a king by forming jokes from cards. Developed in 48h for Global Game Jam 2024 in Finnish Game Jam 2024.

Long Laugh the King

Year Theme Team Links
2024 Make me laugh Jaakko Sukuvaara, Lauri Lyytikäinen, Atte Saari, Leo Äijälä, Saarni Holva Itch.io, Github, Global Game Jam

Long Laugh the King is a card game developed for the Finnish Game Jam 2024 in Kajaani. The goal of the game is to form jokes from cards to make the king laugh so that he doesn't get displeased with you. The game was developed with Godot with a team of 5. In the team Me and Lauri were programming, Atte and Leo were doing art and Saarni was responsible for the sounds of the game.

My Role

As programmers me and Lauri decided to try and learn to use Godot during this game jam. Since we didn't know the engine that well at the start we didn't have clear responsibilities. But at the end of the project the biggest systems I had done for the game were the logic for point system and random events. Including how the cards are counted and how the custom effects affect the points received.

Cards

Iso Tammi gameplay image

The idea for the card system was to have three types of cards: Theme, Subject and Punchline, represented by red, blue and green cards respectively. By combining the cards in the right order the player would've created a complete joke. By combining specific cards with each other the joke would be funnier or more offensive to the king.

Challenge

The biggest challenge implementing this system was how to handle the card relationships to each other. By having ~30 cards all with relations to others, the assignment and management of these cards in the time frame of the game jam would've been extremely difficult.

To ease this I implemented a system to read the relationships out of a csv file. This enabled us to use an existing system, like Excel, to assign and manage the relations ships easily.

Iso Tammi gameplay image

Close to the end of the jam we were even able to balance the game by adjusting these relations in the csv file, since it was so trivial.

Random Events

Iso Tammi gameplay image

At the end of the jam I challenged my self to implement random events into the game. The events would include a random character visiting the king's court and affecting how much points each card could give.

I was doubtful I would be able to complete this system in time for the game jam deadline, as none of our systems were implemented to support this. But at the end of the day I managed to squeeze it in!

Iso-Tammi

A freeform forest themed tower defense game. Developed in 48h for Global Game Jam 2023 in Finnish Game Jam 2023.

Iso-Tammi

Year Theme Team Links
2023 Roots Jaakko Sukuvaara, Lauri Lyytikäinen, Atte Saari Itch.io, Github, Global Game Jam
Iso Tammi gameplay image
Defend the tree of life from deforestation! This game is about defending the Finnish tree of life, Iso Tammi, from modern deforestation by using its large network of roots to sprout new trees and make them attack the lumberjacks.

Developed at Finnish Game Jam 2023 Jyväskylä, Iso Tammi is a tower defense game where your task is to defend the large oak from Finnish Mythology. The game was developed in Unity 3D with C# and modeled in Blender. The team was divided into programmers (me and Lauri) and a 3D artist (Atte) with the rest of the roles filled as needed by everyone on the team.

My role

During the jam I worked on the gameplay systems such as enemies, spawning, trees and attacking.

Class diagram Class diagram of my work

Enemy spawning

I implemented the enemy spawning in the GameController object in the scene. With these controls the user could define a list of enemies that the game would spawn, how likely they're to spawn, how often a new wave is created, how many enemies are in a wave and how far away of the trees is the wave created.

Game controller enemy spawning options

Enemy list is a list of structs which are marked serializable so they are able to be changed in the editor. This makes it very easy to add new enemies and balance the game by changing the likely hood of each enemy.

Code snippet
public class gameController : MonoBehaviour
{
    [SerializeField]
    private List<EnemySpawnOption> enemies = new List<EnemySpawnOption>();

    ...

    [System.Serializable]
    private struct EnemySpawnOption
    {
        public GameObject Prefab;
        [Range(0f, 1f)]
        public float Weight;
    }
}
                                

Enemies

Image of an Iso Tammi enemy

Enemies by themselves were the easiest to create. The enemy script only controls the enemy characteristics such as enemy speed and damage. The different types were implemented with Unity prefabs where each enemy got their own characteristics and art

The enemy script implements moving, attacking and getting damage. But most of these actions are called from outside the script. By itself the script only turns the sprite to look at the camera due to sprite implementation in a 3D environment. Moving is called by gameController, which controls and keeps track of all of the enemies in the game. And getting hit is called by the projectile, that hits the enemy.

Trees

Tree types

Image of all the trees in Iso Tammi

The game includes four types of spawnable trees and the Iso Tammi itself. Each tree can attack with projectiles at the enemy, which can be sped up by pressing *space* when the tree is selected, with their unique projectiles.

The tree script is similar to the enemy script that all of the trees use the same script, but with different serialized values. In these values you can specify the projectile used, and attack parameters. Trees are spawned by the game controller when player clicks a spot with a tree card selected. Trees eventually die when they've received enough damage from the enemies.

Tree projectiles

Image of all the projectiles in Iso Tammi

Each tree has its unique projectile of which each has it's own strength

I implemented these projectiles with inheritance, the spruce and pine projectiles being the base class since they didn't have any special effects other than speed and damage. The others had unique behavior e.i. exploding, hanging around and splitting to multiple projectiles on hit. For these special effect I could just override behavior of the base class for example the acorn that explodes on hit.

Code snippet
protected override void onHit(GameObject enemy)
{
    var enemiesInArea = gameController.GetEnemiesInArea(transform.position, splashRadius);
    enemiesInArea.ForEach(e => e.GetComponent().GetHit(splashDamage));
    
    base.onHit(enemy);
}
                                    

Highlighted experience

Military virtual instructor

During my mandatory military service in the Finnish Defense Forces I served as senior virtual instruction support along with other conscripts.

Military virtual instructor

During my mandatory military service in The Finnish Defence Forces I served in the virtual instruction unit in Kainuu Brigade for 9 months. I was the senior of the unit and managed our four person unit under our captain's leadership

Main responsibility of the unit was to help and guide in virtual training of other conscripts in Bohemia Simulation's Virtual BattleSpace 3 (VBS 3) and SAAB's Ground Combat Indoor Trainer (GCIT). The unit was also tasked with the maintenance and upkeep of these simulators and their training scenarios.

Along side our main tasks I developed and maintained the unit's web-based class management software and managed the class rooms.

During the service I worked with a national team of virtual training units in collaboration in the projects of the unit where I managed our unit's projects as well as many cross unit projects.

In the end of the service I trained new conscripts to our unit and I was a co-trainer in nation wide virtual instructor support training organized by Armoured Brigade of Finnish Defence Forces.

Me in finnish milatry uniform
Photo of me during my military service.

Taitajat -competition

I competed in Taitajat 2021 competition in Web development and won 1st place.

Taitajat -competition

Taitajat competitions are heald yearly in Finland by Skill Finland where the participants compete in various vocational skills.

In 2021 I competed in Web development under Gradia vocational school where I achieved 1st place.

The web development tasks in the final were to design and develop a computer management website for Opinsys. Over two days, first we had to develop the front-end with our chosen technologies. I used only jQuery on top of plain HTML, CSS and JavaScript. On the second day we had to develop a backend for the website where I chose to use PHP.

The comleted websites were judged on desing, technical implementation, accordance with web standards and other features of the site.
The website that I made can be found preserved here: Website

See also my employer's blog post about it at the time: Blog post
Taitaja 2021 web development standings (In Finnish only) can be seen at the official website: Standings

I also competed in the cancelled (due to CoVid-19) Taitaja 2020 Web development finals as well as in the Taitaja 2019 Data Processing semi-finals

Cover photo: Tomi Mäki, Työmaa / Skills Finalnd

Me during the competition wearing a mask behind two computer monitors
Photo of me during the competition. Photo: Ari-Pekka Ojala Koulutuskeskus JEDU / Skills Finland

Global/Finnish Game Jam

All the way from 2015 I've participated in many Finnish Game Jam events during the Global Game Jam. During the jam I developed a game in 48h with a team.

Global/Finnish Game Jam

Since 2015 I've participated in Global Game Jam through the Finnish Game Jam organization. During the game jam the goal is to create a video game in 48 hours.

I've worked as an 2D artist, level designer and programmer in the game jams. Most games that I've participated in were made using the Unity3D engine.

My game jams
2024 - Long Laugh the King
Role: Programmer
2023 - Iso Tammi
Role: Programmer
2019 - HomeSweetConnection
Role: UI/UX Programmer
2018 - Bad Pipes
Role: Programmer
2017 - Gravity Shmup
Role: 2D Artist
2016 - Escape from Tuonela
Role: Level designer
2015 - Spring is coming
Role: 2D Artist
Global Game Jam logo