Headshot of Jacob Jones.

Jungle Jim Devlogs

I am passionate about documenting what I have learned and writing about my experiences creating games!

The Base Movement of Jim

March 6th, 2026

Design devlog about the my philosophies and decisions behind the base movement mechanics of Super Jungle Jim.

Thumbnail image for devlog

Creating End of Level Cinematic

January 6th, 2025

In-depth documentation about my process, thoughts, and lessons learned as I created this cinematic. In particular, my developmental planning process shines through here.

Thumbnail image for devlog

The Gameplay Loop of Jungle Jim

November 14th, 2024

Writing about the gameplay loop I've created for the game. I discuss theory for creating a strong core game loop and connect them to examples in Jungle Jim.

Thumbnail image for devlog

First Time Leading a Project

November 12th, 2024

Personal narrative of my experiences leading and managing a team for the first time. I discuss issues I encountered, as well as how I resolved them.

Teaching the Player Without Intrusion - Creating The Tutorial

September 11th, 2024

In-depth documentation about my process creating the tutorial area of the game. I aimed to create an unobtrusive experience that gave players a space to learn at their own discretion.

The Players' Lens - Designing the Camera System

October 13rd, 2024

In-depth documentation about the camera system created for the game. I discuss the numerous features, as well as the design decision behind their implementation.

Headshot of Jacob Jones.

Misc. Devlogs

I am passionate about documenting what I have learned and writing about my experiences creating games! I like to take a retrospective style- accumulating my experiences and writing about them in longer-form devlog posts.

Caislean Paranormal: Player Resources and Enemies

November 11th, 2024

Thumbnail image for devlog

Pizza Panic Post-Mortem: What a Second Iterative Loop Would Entail

May 2nd, 2024

Thumbnail image for devlog

Caislean Paranormal Post-Mortem: My First Failures

May 4th, 2024

Frustum of Truth: Iterations of the Formal Loop

December 6th, 2023

Thumbnail image for devlog

Frustum of Truth: A Look into the Tech

December 6th, 2023

Thumbnail image for devlog

Frustum of Truth: Themes and Messages

December 6th, 2023

Thumbnail image for devlog

Character, Camera, and Controls

May 22nd, 2026

The heart of this game is about overcoming challenges through repetition and effort to achieve great things. The player can live through this experience by controlling the protagonist through the lens of the camera. Character, camera, and control need to work in tandem to achieve a level of cohesion that can deliver the intended experience.Similar to the games central experience, I had to overcome challenges through repetition and effort via iterating on these elements until they were just right for the game.


Magnetic Forces

The core premise of the game was that the player controls a dipole magnet, rotating it around a central pivot to manipulate their velocity and traverse the level. Because a significant portion of the movement is entirely driven by magnetic interaction, perfecting the system became an important part of the character controls.My first implementation was intentionally simple. It applied force along the direction between two magnets’ normal vectors, with the magnitude attenuated by distance. This was enough to validate the core concept, but the system lacked both simulation depth and gameplay intent.

Basic First Implementation

Once the first implementation proved viable, I looked into how magnetic forces behave in the real world. I looked into the Lorentz Force Formula, which describes how electric charges interact with magnetic fields. In reality, magnetic fields emerge from enormous numbers of moving electric charges, but fully simulating that behavior would have been unnecessarily expensive and overly complex for the needs of the game. Instead, I simplified each magnet into a single representative charge while preserving the physical relationships most relevant to gameplay.The most important takeaway from this research was the relationship between force and velocity. In real electromagnetic systems, faster-moving charges experience stronger interactions due to a faster rate of transfer. This concept translated naturally into the game, since players are constantly entering magnetic fields at different speeds and angles. Basically, more relative velocity produces more force.Using these principles as a reference, I rewrote the magnetic force calculations to more closely resemble real electromagnetic behavior. It was certainly more realistic...but that was a bit of a problem. At this point, the formula was not altered in any way to accomodate gameplay. We wanted the game to have a sense of finesse where players could master the controls over time. The reality is that physics is hard to predict and not always fun to control. Players struggled to control their left and right velocities and their movements would feel sluggish when trying to change directions. Other features were added to assist with player control, but I still wanted to adjust the formula to better accomodate gameplay.The final implementation focused on preserving the physical inspiration of the system while shaping it around player readability and responsiveness. I added padding and clamping to create consistency. This was especially important for the distance attenuation. A mathematically accurate inverse-square force created dramatic acceleration near magnet surfaces, which made platforming feel difficult to get a read on during fast gameplay sections. To improve horizontal control, I also incorporated a 2D cross product between the player magnet’s velocity and the target magnet’s normal vector. This allowed the force magnitude to scale based on how perpendicular the player’s movement was relative to the magnetic surface, giving players more deliberate control over lateral movement while inside a magnetic field. Not pictured, I also do an occlusion check between the two magnet surfaces. This occlusion check is between 0 and 1 and is multiplied with the final result.By the end of development, the system had evolved from a simple force simulation into a movement system that was better designed for predictability, responsiveness, and player mastery. Although the final implementation still draws heavily from real-world principles, it has been tweaked to provide a better gameplay experience.

Headshot of Jacob Jones.
Headshot of Jacob Jones.

Final Magnetic Force Implementation


Non-Magnetic Movement

At the core of the game, the player traverses levels using magnetic forces. However, not every surface in the environment is magnetized, which raises an important design question: how should movement work on neutral surfaces?Movement in magnetic fields is heavily based on rotation, so I wanted neutral traversal to follow the same principle. Keeping both systems centered around the concept of rotational control helps create a more cohesive and consistent control scheme throughout the game.This led to concept of using physically based foddian mechanics for neutral surfaces.

Creating a system like this came with a slew of challenges based around physical logistics. Before any of that, I needed a baseline implementation to try out. I created a software cursor and made it so the players negative charge always pointed toward it.

Basic First Implementation

While this first implementation works well for moving the players character around, it was ultimately too naive. I realized that modifying the transform.rotation directly was a mistake, as it caused numerous physics bugs. If the player rotated too quickly while overlapping walls or floors, the physics system would calculate extremely large corrective velocities that created unruly behavior. In cases where this wasn't occurring, there was still a problem. Similar cursor motions could produce very different player velocities, making the controls feel unreliable.

Large Velocities Physics Issue

The solution I used for this problem was to replace the direct rotational changes with a physically based torque system. Instead of modifying transform.rotation to point towards the software cursor, I used custom torque forces on the rigidbody to point towards the software cursor. I also had to implement damping to the torque to prevent oscillation and overshooting.This method has an additional benefit of making the rotation feel significantly more tactile. Previously, players would rotate toward the cursor at the same lagging rate, even if colliders were in the way. With torque-driven rotation, colliders naturally resist movement when rotating. This creates a sense of weight to the player character and adds a sense of depth to the feedback of the controls.

Physically Based Rotation Implementation


Collision Querying

Throughout gameplay, the player is constantly changing between states that affect their controls. On neutral surfaces the player should be able to push themselves off of surfaces by rotating; however, on magnetic surfaces this behavior is not desired. The project has numerous collision queries to provide information for state changes and provide limitations that simplify the controls.In order to detect neutral surfaces, I first use a capsule collider to query for any overlapping surfaces flagged as neutral. Then, I do a raycast between the closest point along the neutral surface and the closest point along the player's collision. This is done to prevent conflicts when moving over the area where neutral surfaces transition into magnetic ones. Whichever end of the player is closest to either surface dictates which state the player is in.

Headshot of Jacob Jones.

The player is a dipole, meaning both ends of the player has a different magnetic charge than the other. Early implementations ran into problems where players laying sideways or attempting to rotate in a magnetic field would see unpredicatable velocities. The reason for this, was that both magnets had a radius of effect that was unrestricted by direction. To create more predicatable movement and allow more intentional control, dead zones were put into place for each magnet's radius of effect. A dot product is checked before calculating any magnetic forces, and if it fails a certain threshold it is disregarded and skipped. Additionally, the dot product is used in affecting the force strength. This allows players to use the edges of their range of influence to get smaller boosts, as well as smoothing over the transition between net zero forces and repel magnetic forces.

Headshot of Jacob Jones.

The neutral player state actually requires additional queries. One of the most difficult issues to solve with the movement was a logistical one. The player moves by rotating, as that is what pushes them against the ground. However, this comes with some problems.If players rotated extremely fast into the ground or walls, the physics system would output extremely large velocities. Slowing down the torque prevents this but also makes the player unable to move much at all. It also prevents the player from being able to react with quick rotations within magnetic fields. The solution involves dynamically changing the player's torque based on results from queries.My solution is simple, but has proved to be fairly effective. Raycasts are performed on the lateral vectors of a magnets direction. If both of these raycasts detect a surface, the players torque is slowed down. When only one or none of these raycasts return a hit, the torque interpolates back to its regular speed.

Headshot of Jacob Jones.

Movement Options

The base movement introduced so far is simple to grasp and hard to master. It is effective for the primary gameplay loop, but it does not provide enough variety to keep platforming feeling fresh on its own. I wanted to add additional aspects to the movement and distribute them as rewards for completing challenges. This way, the game has an additional sense of progression while providing new ways for players to think about levels moving forwards.

I prototyped 5 main concepts for additional movement for the player character.

Welding

Welding allows players to fuse to surfaces, preventing them from falling off or being pushed by magnetic forces. It primarily enables players to move laterally across magnet surfaces through an "inchworm" technique. There is a fair amount of frustration with trying to move laterally on magnets without flying far into the air, and welding resolves this issue by allowing player to move laterally without magnetism applying forces on them.With weld, players can climb up walls! This allows players to view levels in more dimensions which can open the door up for some mentally challenging platforming.

Launching

Launching allows players to exchange their battery power to leap great distances. This lets players have the decision to expend their resources in order to speed through challenges they may struggle with. It also opens the door to creating resource-management challenges within the level.

I was surprised by how many players enjoyed this mechanic. I think it appeals to a power fantasy of sorts for some players, but I have not quite put my finger on what exactly about it provides that. It may be as simple as the fact that the launching ability is very powerful in the context of the game.

Burst Projectiles

Burst Projectiles allow the player to have corrective control of their movements in the air by firing three subsequent shots that propel the character. This allows for smoother traversal through the levels, and makes the controls feel more fair by providing chances for players to correct their mistakes before they are punished. The projectiles are shot by exchanging battery power, so they must be planned accordingly within the players resource management.

Initially I planned to prototype a thrust instead, but then I thought of burst projectiles. The nature of the burst allow for a higher skill ceiling, as players can learn the timing to combine shots to get the exact result they wanted.

Bumpers

Bumpers allow players to jump with both of their ends expanding in a way that pushes the character upwards. This did not make it past the prototype phase, as it was too overpowered and detracted from the primary control scheme of the game revolving around rotations.

Initially, the bumpers were prototyped to mitigate an issue within the base movement preventing players from acheiving reasonable height with rotations. They were no longer needed after I fixed the issue in the base movement itself.

Grapple

Grapple allows for players to tether to nearby grapple points. At the moment of writing, this prototyped feature is not being considered to make it into the final game until it has more purpose and is reworked accordingly. I wanted to lean into the physics-based nature of the controls and provide new ways for players to traverse levels. Unfortunately, the grapple just is not adding anything interesting to the game. It is too slow in its current iteration, and is difficult to not make overpowered in the context of this game.

I would like to reinvestigate the grapple later on, but for now it will remain as a cool footnote.


Camera

The camera is the lens through which the player experiences the game. All game information is presented through its frustum, so it has a great deal of importance.The camera targets the player character, with a bit of lag and look ahead for a smoother look. To improve players' reaction times, the camera zooms out as the characters velocity increases. Volumes were also added to modify camera properties such as zoom or follow targets. These proved to be very useful for putting emphasis on certain elements in a level.We wanted to implement parallax to build depth in our scenes. Initially, I created a parallax script that worked with an orthographic camera. However, we also wanted our camera to be able to zoom in and out. Orthographic cameras do not have a sense of scale to their projection, which made it very difficult to implement parallax through a script when the camera zooms in and out. Because of this, I switched gears and switched our camera setup to use a perspective camera instead.I used Cinemachine to constrain the camera within bounds defined by a collider. Cinemachine is unable to do this smoothly with a perspective camera, so I had to create a dummy orthographic camera to use for the constraint.We also wanted to be able to blend between different follow targets for dynamic cutscenes. I created some utility functions that allowed us to easily add and remove follow targets with weight interpolation.

Signed Distance Field Generation

May 28th, 2026

One of the most ambitious tasks of this project was the creation of a signed distance field generator for use in the render pipeline. The task relied on compute shaders, custom render passes, and dynamic mesh generation.


Purpose

Before I start getting technical, why was this needed in the first place? Well, this game benefits heavily from players being able to read at a glance any magnetic field's range, strength, and attenuation. I had the idea to use emanating lines to communicate this to the player. Their speed, size, and color could be used to show all aspects of the magnetic field that a player would need to know. A huge source of inspiration for the look of the effect was this visualization video for bats echolocation.


Planning the Tech

I knew that with signed distance fields, I could create a shader that imitates the look from the echolocation video. What I didn't know however, was that Unity does not have any built-in signed distance field support. This means I would need to create it myself. I wanted to create a render texture that could be sampled globally by any shader. In order to avoid the cost of having yet another camera added to the scene, I opted for the most efficient route- creating the render texture during a custom render pass injection. A compute shader is used to calculate the signed distance field operations.

Additionally, I needed a way to display these shaders in the game world. Magnetic fields operate in gameplay logic using procedural colliders, but there are no meshes or sprite renderers associated with them. I needed a way to generate a sprite or mesh based on the shape of a collider, while also respecting occlusion of game elements. I ended up creating a procedural mesh generator based on the vertices from the collider, and used this mesh to display shaders that read from the global render texture for my signed distance fields.


Compute Shader

I created a compute shader to generate the signed distance fields. Initially, I used Unity functions on the CPU to generate them. However, this was far too slow. By using a compute shader I could offset the load onto the GPU using multithreading. In order to make this work, I had to write my own signed distance field functions for each Unity collider type. Thankfully, there are plentiful resources online about writing signed distance field formulas for many shape types.

Go into code.


Custom Render Pass Injection

The most optimized way to create the global render texture was to use a custom render pass and to inject that into the render pipeline using Unity 6 Render Graph. Since Render Graph is still new, there was not much documentation on how to do this, but I eventually was able to do it. I actually use it to generate two render textures for different purposes. I create a render texture that uses the results from my signed distance field generator. I also create a render texture mask that is only white where magnetic fields are present and unobstructed by foreground elements. I set my generated magnetic field meshes to be on a certain layer, and used this layermask to create the render texture.

Go into code.


Magnetic Field Procedural Mesh Generation

The magnets in our game are very dynamic in their shapes and in their velocities. Because of this, it was much quicker to procedurally generate their shapes based on their collisions instead of creating custom sprites for every magnetic field that matches their collision.

The generation actually took a while to get functioning correctly. The magnetic field collider's vertices are used to generate the vertices for the mesh, but making them one to one was not easy. I forgot what I did go and read the code and continue writing this after I am reminded about it.

Go into code.

Headshot of Jacob Jones.

Jacob Jones

Game Designer

You can message me through my email using the form below. Or if you rather, you can directly email me at my address.