First of all, I want to thank YOU for joining my mailing list! This is my first ever blog post, and it means a lot that you are here at the beginning of this journey. You’ll be a part of monthly deep dives and updates into my development process and progress as I prototype and pursue my game ideas. I hope you enjoy 😁
I’ve been in various stages of development on a few game ideas over the years. If you’ve ever tried your hand at game development, you know how much effort, time, and motivation it takes! So I’d like to always start out with my current plugins, tools, and resources I’m using to maintain my sanity and motivation. If you don’t read this whole post, at least go check out these recommendations!
Godot Plugins:
G.U.I.D.E. - This plugin adds more modular player input capability to Godot. I’ve used this for over a year. Plus, the creator has a YouTube channel for tutorials 🙌
Github Repo: https://github.com/godotneers/G.U.I.D.E
Godotneers YouTube Channel: https://www.youtube.com/@godotneers
PhantomCamera3D - This plugin adds all the fancy camera effects and utilities you could need. I’ve only used it for a week or two, but man does it make a difference!
Website: https://phantom-camera.dev/
Relevant Resources:
Very Very Valet Character Controller walkthrough - This is my original inspiration for this character controller. Great overview of the theory behind it.
YouTube video: https://www.youtube.com/watch?v=qdskE8PJy6Q
Check out Toyful Games: https://www.toyfulgames.com/
Godot RigidBody forces and torques - This video helped me understand how to apply forces to my RigidBody.
YouTube video: https://www.youtube.com/watch?v=XSFkAzXQSWE
I always find that learning from other devs and seeing cool mechanics makes it easier to keep up the momentum. So let’s dive in and keep the motivation going!
What prompted the change
This past month, I began prototyping my newest idea for a cargo loading/unloading game. I envision a gameplay focus on movement and physics-based interaction. I really want the player to feel like their actions directly affect the game world in a satisfying way. Additionally, I know that I want the physics to introduce a little bit of chaos to the gameplay. With this in mind, a standard KinematicBody controller probably won’t provide the immersive interactions I want as easily as a RigidBody controller. So I decided to make the switch.
My basic RigidBody controller theory
My RigidBody character controller has two main parts:
a suspension system, and
a system of torques and forces to move and rotate based on player input.
Suspension: This character controller uses a ShapeCast to provide the suspension. The ShapeCast is projected down and detects collisions with the world. Depending on the penetration depth of the collision, the player’s RigidBody has a springy force applied to it to move to a specified “ride height.” See a visual representation of this idea from Toyful Games below:

From Making A Physics Based Character Controller In Unity (for Very Very Valet) by Toyful Games on YouTube.
Moving and rotation: This was the bulk of my work this month. It took a lot of trial and error, learning about quaternions, and some vector math to pull off. Basically, movement involves rotating movement input into the orientation of the camera and then calculating and applying this as a force. Then for rotation, I continuously determine the quaternion that keeps the player RigidBody upright and facing the correct way. It’s tough to describe, so check out my code snippets below 👇
func _update_upright_quaternion() -> void:
if _move_dir == Vector3.ZERO:
return
_upright_quaternion = Basis.looking_at(_move_dir).get_rotation_quaternion()This function is called to update the _upright_quaternion variable whenever the player is providing a movement direction.
func _apply_upright_torque() -> void:
var current_quaternion: Quaternion = owner.transform.basis.get_rotation_quaternion()
if current_quaternion.dot(_upright_quaternion) < 0.0:
_upright_quaternion = -_upright_quaternion
var quaternion_to_goal: Quaternion = _upright_quaternion * current_quaternion.inverse()
var rotation_axis: Vector3 = quaternion_to_goal.get_axis().normalized()
var rotation_angle: float = quaternion_to_goal.get_angle()
var torque: Vector3 = (rotation_axis * (rotation_angle * 10)) - owner.angular_velocity
owner.apply_torque(torque)This function is called every physics frame. It applies the needed torque based on the current _upright_quaternion variable to keep the RigidBody upright.
func _apply_ground_movement(delta: float) -> void:
_move_dir = look_component.apply_orientation_to(_move_input)
_update_upright_quaternion()
var target_vel: Vector3 = _move_dir * max_ground_speed
var unit_vel: Vector3 = target_vel.normalized()
var direction_change_factor: float = target_vel.dot(unit_vel)
var accel_factor: float = ground_accel * ground_accel_factor_curve.sample(direction_change_factor)
var current_xz_vel: Vector3 = _get_xz_velocity()
current_xz_vel = current_xz_vel.move_toward(target_vel, accel_factor * delta)
var needed_accel: Vector3 = (current_xz_vel - _get_xz_velocity()) / delta
var max_accel: float = max_ground_accel_force * max_ground_accel_force_factor_curve.sample(direction_change_factor)
var actual_accel: Vector3 = needed_accel.limit_length(max_accel)
var move_force: Vector3 = actual_accel * owner.mass
owner.apply_central_force(move_force)This function is also called every physics frame. It gets the current move direction based player input and the camera’s orientation, and updates the _upright_quaternion variable accordingly. Then, using a set of @export variables, it calculates the needed move force to get the RigidBody moving in that direction. Check out this part of Toyful Games solution in Very Very Valet for a more in-depth explanation: https://youtu.be/qdskE8PJy6Q?t=206.
Reflection
The focus of my work this month has revolved around tuning satisfying, yet slightly chaotic, player movement and interactions. I’ve been so pleased with the results and engagement on social media! My most successful post reach 250 likes and 17.4k impressions, which has boosted my motivation so much!
This coming month I hope to finish a playable prototype of my idea to determine viability. If it’s fun, I’ll pursue it fully! If not, then I still have a working RigidBody character controller for more ideas! If you have any ideas, feedback, or questions, please feel free to reply to this email or post a comment online. I would love to hear back from you! If you like this content, sign-up for the mailing list to stay up-to-date with my progress: deadweightdog.com/subscribe. And make sure to share it with anyone you think might enjoy it too. Thanks for reading!


