Compare commits

...

4 Commits

Author SHA1 Message Date
a1d57d6a1a some tuto fixing
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 9m49s
2026-01-06 16:35:17 +01:00
941205af2b small gravity and jump balancing, removed wall jumping coyote times
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 9m34s
2026-01-06 16:08:39 +01:00
6c2ad89687 fixing the manlting into geo
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 9m42s
2026-01-06 12:36:38 +01:00
59494f9e98 updating CI to build for linux as well
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 9m34s
2025-12-25 09:37:51 +01:00
9 changed files with 692 additions and 633 deletions

View File

@@ -54,27 +54,12 @@ jobs:
- name: Import resources and build solution
run: |
godot --headless --editor --build-solutions --quit --import --path $PWD
- name: Build Windows
run: |
mkdir -v -p build/windows
godot --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
zip -r Windows.zip build/windows
- name: Build Windows ARM
run: |
mkdir -v -p build/windowsArm
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
zip -r WindowsArm.zip build/windowsArm
# - name: Linux Build
# run: |
# mkdir -v -p build/linux
# godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
# zip -r Linux.zip build/linux
- name: Mac Build
run: |
mkdir -v -p build/mac
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
zip -r Mac.zip build/mac
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
@@ -84,6 +69,12 @@ jobs:
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: Windows.zip
buildChannel: windows
- name: Build Windows ARM
run: |
mkdir -v -p build/windowsArm
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
zip -r WindowsArm.zip build/windowsArm
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
@@ -93,15 +84,27 @@ jobs:
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: WindowsArm.zip
buildChannel: windows-arm
# - name: Upload to Itch
# uses: KikimoraGames/itch-publish@v0.0.3
# with:
# butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
# itchUsername: ${{ env.ITCHIO_USERNAME }}
# itchGameId: ${{ env.ITCHIO_GAMEID }}
# buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
# gameData: Linux.zip
# buildChannel: linux
- name: Linux Build
run: |
mkdir -v -p build/linux
godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
zip -r Linux.zip build/linux
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
itchUsername: ${{ env.ITCHIO_USERNAME }}
itchGameId: ${{ env.ITCHIO_GAMEID }}
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: Linux.zip
buildChannel: linux
- name: Mac Build
run: |
mkdir -v -p build/mac
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
zip -r Mac.zip build/mac
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -63,22 +63,21 @@ blend_mode = 1
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_poq2x")
WalkSpeed = 7.5
AccelerationAir = 2.0
DecelerationAir = 0.1
Weight = 5.0
MantleTime = 0.2
AccelerationAir = 0.8
DecelerationAir = 0.02
Weight = 4.0
MantleTime = 0.3
MantlePath = ExtResource("2_6lejt")
CoyoteTime = 0.3
SimpleJumpStartVelocity = 8.0
SimpleJumpStartVelocity = 6.0
SimpleJumpHangTimeInFrames = 1
SimpleJumpGravityLesseningFactor = 2.5
DoubleJumpStartVelocity = 15.0
SimpleJumpGravityLesseningFactor = 2.0
DoubleJumpHangTimeInFrames = 3
DoubleJumpGravityLesseningFactor = 1.5
MegaJumpStartVelocity = 30.0
MegaJumpHangTimeInFrames = 12
MegaJumpGravityLesseningFactor = 1.2
WallJumpStartVelocity = 12.0
WallJumpStartVelocity = 8.0
MaxNumberOfEmpoweredActions = 3
SimpleDashStrength = 15.0
PoweredDashStrength = 30.0
@@ -236,6 +235,11 @@ transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0
mesh = SubResource("CylinderMesh_nodcl")
[node name="DashCooldown" type="Timer" parent="."]
wait_time = 0.8
one_shot = true
[node name="AirborneDashCooldown" type="Timer" parent="."]
wait_time = 0.5
one_shot = true
[node name="PowerCooldown" type="Timer" parent="."]
@@ -609,7 +613,7 @@ default_state = NodePath("../CoyoteEnabled")
[node name="OnWallRun" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("28_n7qhm")
to = NodePath("../../OnWall/RunningCoyoteEnabled")
to = NodePath("../../OnWall/Running")
event = &"wall_run"
delay_in_seconds = "0.0"
@@ -672,7 +676,7 @@ script = ExtResource("27_34snm")
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../OnWall/HuggingCoyoteEnabled")
to = NodePath("../../../OnWall/Hugging")
event = &"wall_hug"
delay_in_seconds = "0.0"
@@ -736,7 +740,7 @@ script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Hugging"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
to = NodePath("../../../Jump/DoubleJump")
event = &"jump"
delay_in_seconds = "0.0"
@@ -745,7 +749,7 @@ script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Hanging"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
to = NodePath("../../../Jump/DoubleJump")
event = &"jump"
delay_in_seconds = "0.0"

View File

@@ -58,6 +58,7 @@ public partial class PlayerController : CharacterBody3D
// Timers
private Timer _timeScaleAimInAirTimer;
private Timer _simpleDashCooldownTimer;
private Timer _airborneDashCooldownTimer;
private Timer _powerCooldownTimer;
[Export] public Marker3D TutorialWeaponTarget;
@@ -327,6 +328,7 @@ public partial class PlayerController : CharacterBody3D
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
///////////////////////////
// Initialize components //
@@ -398,6 +400,7 @@ public partial class PlayerController : CharacterBody3D
_aimedDash.StateExited += OnAimedDashFinished;
_simpleDashCooldownTimer.Timeout += DashCooldownTimeout;
_airborneDashCooldownTimer.Timeout += AirborneDashCooldownTimeout;
_onWall.StateEntered += OnWallStarted;
_onWall.StateExited += OnWallStopped;
@@ -469,10 +472,19 @@ public partial class PlayerController : CharacterBody3D
{
_canDash = true;
}
public void AirborneDashCooldownTimeout()
{
_canDashAirborne = true;
}
public bool IsPlayerInputtingForward()
{
return GetMoveInput().Z < -0.5f;
}
public bool IsTryingToMantle()
{
return MantleSystem.IsMantlePossible && GetMoveInput().Z < -0.5f && _isJumpInputPressed;
return MantleSystem.IsMantlePossible && IsPlayerInputtingForward() && _isJumpInputPressed;
}
public void HandleGrounded(float delta)
@@ -485,15 +497,17 @@ public partial class PlayerController : CharacterBody3D
public void HandleAirborne(float delta)
{
MoveInAir(delta);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (IsTryingToMantle()) _playerState.SendEvent("mantle");
if (!WallHugSystem.IsWallHugging())
{
_isWallJumpAvailable = true; // reset wall jump if we left the wall
return;
}
// Going upwards, we stay simply airborne
if (Velocity.AngleTo(Vector3.Up) < Math.PI / 4)
@@ -638,13 +652,15 @@ public partial class PlayerController : CharacterBody3D
return;
}
if (_onWallHuggingCoyoteEnabled.Active || _onWallRunningCoyoteEnabled.Active)
{
if (!_isWallJumpAvailable) return;
}
if (_onWall.Active && !_isWallJumpAvailable && IsFacingWall()) return;
_playerState.SendEvent("jump");
}
public bool IsFacingWall()
{
return _wallHugStartNormal.Dot(GetGlobalForwardFacingVector()) < -0.5f;
}
public void OnInputJumpOngoing()
{
}
@@ -667,7 +683,7 @@ public partial class PlayerController : CharacterBody3D
public void OnDoubleJumpStarted()
{
_canDash = true;
_canDashAirborne = true;
// _canDashAirborne = true;
OnJumpStarted(DoubleJumpStartVelocity);
}
public void OnMegaJumpStarted()
@@ -699,7 +715,14 @@ public partial class PlayerController : CharacterBody3D
public void OnJumpFromWall()
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
if (!IsFacingWall())
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
}
// Remove the ability to dash straight away so you cannot scale up the wall
_canDashAirborne = false;
_airborneDashCooldownTimer.Start();
_isWallJumpAvailable = false;
}
public void OnMegajumpFromWall()
{
@@ -1361,6 +1384,11 @@ public partial class PlayerController : CharacterBody3D
{
WeaponRoot.SetRotation(HeadSystem.Rotation);
}
public Vector3 GetGlobalForwardFacingVector()
{
return Transform.Basis * HeadSystem.Transform.Basis * Vector3.Forward;
}
///////////////////////////
// Processes //////////////

View File

@@ -57,13 +57,15 @@ public partial class MantleSystem: Node3D
IsMantlePossible = false;
if (!isColliding) return;
// Check if collide with wall
// Check if face something wall-like that should be climbable
var collisionNormal = isGrounded ? _groundedWallDetect.GetCollisionNormal(0) : _inAirWallDetect.GetCollisionNormal(0);
if (collisionNormal.Y > 0.9f) return;
if (collisionNormal.Y > 0.7f) return;
var spaceState = GetWorld3D().DirectSpaceState;
MantleCurve = new Curve3D();
MantleCurve.AddPoint(Vector3.Zero);
var hasFirstProfileHit = false;
var hasFirstProfileHit = false;
var previousProfilePoint = GlobalPosition;
foreach (var wallProfileShapecast in _wallProfileShapecasts)
{
// Haven't met the wall yet
@@ -74,22 +76,31 @@ public partial class MantleSystem: Node3D
// Got to the other side of the wall, we stop there
if (!wallProfileShapecast.IsColliding())
{
MantleCurve.AddPoint(ToLocal(globalTargetPosition));
// MantleCurve.AddPoint(ToLocal(globalTargetPosition));
break;
}
var profilePoint = wallProfileShapecast.GetCollisionPoint(0);
var profileNormal = wallProfileShapecast.GetCollisionNormal(0);
var shape = wallProfileShapecast.Shape as SphereShape3D;
var shapeRadius = shape == null ? 0.125f : shape.Radius;
var centerOfShape = profilePoint + profileNormal * shapeRadius;
// Check if we collided parallel to a wall
var isCollisionSameAsTarget = globalTargetPosition.IsEqualApprox(profilePoint);
var isCollisionSameAsTarget = globalTargetPosition.IsEqualApprox(centerOfShape);
var isCollidingWithWall = profileNormal.Y < 0.1f;
if (isCollisionSameAsTarget || isCollidingWithWall) continue;
// Check if the path from the previous point makes us go through a wall
var query = PhysicsRayQueryParameters3D.Create(previousProfilePoint, centerOfShape, wallProfileShapecast.CollisionMask);
var result = spaceState.IntersectRay(query);
if (result.Count > 0) break; // We are going through a wall, we stop there
// We have a valid collision
if (!hasFirstProfileHit) FirstMantleProfilePoint = profilePoint;
if (!hasFirstProfileHit) FirstMantleProfilePoint = centerOfShape;
hasFirstProfileHit = true;
MantleCurve.AddPoint(ToLocal(profilePoint));
previousProfilePoint = centerOfShape;
MantleCurve.AddPoint(ToLocal(centerOfShape));
}
if (MantleCurve.PointCount == 1) return;

View File

@@ -58,47 +58,47 @@ collision_mask = 2
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -0.5)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast2" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -0.75)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast3" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast4" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.25)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast5" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.5)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast6" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.75)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast7" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -2)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2