The sample project can be downloaded from the link below.
This project implements a rope and chain system using physics joints (PinJoint2D, GrooveJoint2D).
You can move using the up, down, left, and right arrow keys, jump with the Spacebar, and cut the chain in front of you with the Z key.
Each chain is configured to break based on its angle and stretch.
Project Structure
Directory Structure
steam_achieve/
├── scripts/ # Scripts related to joints, chains, and ropes
│ ├── breakable_joint_monitor_2d.gd
│ ├── chain_path_binder.gd
│ ├── chain_setup_tool.gd
│ ├── chain_part.gd
│ ├── joint_break_params.gd
│ ├── rope_solver.gd
│ ├── rigid_body_pusher.gd
│ ├── area_joint_breaker.gd
│ ├── path_ribbon_mesh_2d.gd
│ ├── boolean_sprite_cutter_with_tagged_shapes.gd
│ └── fragment_manager.gd
├── *.tscn # Scene files
├── *.png # Texture files
└── addons/ # Addons (gdDelaunay, godotsteam)
Explanation of Scene Files
1. testrope_2.tscn (Rope Test Object)
Purpose
An object for testing a chain consisting of 7 RigidBody2Ds connected by GrooveJoint2Ds.
Structure
Testrope2 (Area2DGameObject)
├── Node2D (Root of the chain)
│ ├── RigidBody2D (Head, not fixed)
│ │ ├── CollisionShape2D (RectangleShape2D)
│ │ ├── seg1 (Node2D, position: 0, -10)
│ │ └── seg2 (Node2D, position: 0, 10)
│ ├── RigidBody2D2 (Second link)
│ │ ├── GrooveJoint2D (Connected to previous RigidBody2D)
│ │ │ ├── node_a: ../../RigidBody2D
│ │ │ ├── node_b: ..
│ │ │ ├── position: (0, -16)
│ │ │ ├── bias: 0.2
│ │ │ ├── length: 8.0
│ │ │ └── initial_offset: 2.0
│ │ ├── CollisionShape2D
│ │ ├── seg1
│ │ └── seg2
│ ├── RigidBody2D3 to RigidBody2D7 (Similar structure)
│ └── RigidBody2D7 (End, uses CapsuleShape2D)
├── Path2D (For visualizing the chain)
├── PathRibbonMesh2D (Draws with ribbon mesh)
├── StaticBody2D (Fixes the head)
│ └── GrooveJoint2D (Connected to the head RigidBody2D)
├── StaticBody2D2 (Fixes the tail)
│ └── GrooveJoint2D (Connected to the tail RigidBody2D7)
├── BreakableJointMonitor2D
│ ├── search_root: ..
│ ├── break_angle_degrees: 80.0
│ ├── break_angle_duration_sec: 0.3
│ └── use_break_delay_frames: false
│ └── break_delay_frames: 3
└── ChainPathBinder2D
├── auto_detect_mode: true
├── search_root: ../Node2D
├── output_paths: [../Path2D]
├── joint_monitor: ../BreakableJointMonitor
├── ribbon_mesh: ../PathRibbonMesh2D
└── enable_smooth_handles: true
Joint Structure
- GrooveJoint2D is placed as a child of each RigidBody2D.
- Each joint references the previous RigidBody2D via
node_aand itself (..) vianode_b. - The head and tail are fixed to
StaticBody2DusingGrooveJoint2D. - All joints are uniformly set with
bias=0.2,length=8.0, andinitial_offset=2.0.
Configuration Features
BreakableJointMonitor2Dis set to break if the angle exceeds 80 degrees for 0.3 seconds.ChainPathBinder2Duses auto-detection mode to visualize viaPathRibbonMesh2D.- Each RigidBody2D has damping set with
linear_damp=10.0andangular_damp=10.0.
2. testrope_ball_3.tscn (Chain Test Object with Ball)
Purpose
An object for testing two chains (UnbreakableChain and BreakableChain) and a ball (a breakable sprite).
Structure
Ball (Area2DGameObject)
├── ChainJointSetupTool (Chain auto-setup tool)
│ ├── target_parent: ../UnbreakableChain
│ └── auto_create_seg_nodes: false
├── UnbreakableChain (Node2D)
│ ├── Path2D (RopePathBinder2D script attached)
│ ├── RigidBody2D (Head, fixed with freeze=true)
│ │ ├── CollisionShape2D
│ │ ├── seg1
│ │ └── seg2
│ ├── RigidBody2D2 to RigidBody2D6 (Intermediate links)
│ │ └── GrooveJoint2D (Connected to previous RigidBody2D each)
│ │ ├── bias: 0.9
│ │ ├── length: 8.0
│ │ └── initial_offset: 1.0
│ ├── RigidBody2D7 (Tail, ball)
│ │ ├── mass: 8.0 (Heavier than others which are 3.0)
│ │ ├── CollisionShape2D (CircleShape2D)
│ │ ├── AttackArea2D (Attack hitbox)
│ │ ├── Sprite2D (ball.png)
│ │ ├── Node2D/CollisionShape2D (CutterShapeGroup, for breaking)
│ │ └── GrooveJoint2D
│ ├── ChainPathBinder2D
│ │ ├── auto_detect_mode: true
│ │ ├── search_root: ..
│ │ ├── output_paths: [../Path2D]
│ │ └── joint_monitor: ../BreakableJointMonitor2D
│ ├── BreakableJointMonitor2D
│ │ ├── search_root: ..
│ │ ├── groove_end_epsilon_pixels: 0.0
│ │ ├── joint_params: [JointBreakParams] (Individual settings)
│ │ │ └── joint_path: ../RigidBody2D2/GrooveJoint2D
│ │ │ └── groove_break_angle_degrees: 90.0
│ │ └── use_break_delay_frames: false
│ │ └── break_delay_frames: 10
│ └── PathRibbonMesh2D (chain.png texture)
├── BreakableChain (Node2D)
│ ├── RigidBody2D (Head, freeze=true, collision_layer=0)
│ ├── RigidBody2D2 to RigidBody2D6 (Intermediate links)
│ │ └── GrooveJoint2D
│ ├── RigidBody2D6
│ │ └── GrooveJoint2D2 (Connected to UnbreakableChain/RigidBody2D7)
│ ├── ChainPathBinder2D
│ ├── BreakableJointMonitor2D
│ └── PathRibbonMesh2D (rope.png texture)
└── BooleanSpriteCutterWithTaggedShapes (Sprite breaking system)
├── voronoi_seed_count: 30
└── disable_related_collisions_on_cut: true
Joint Structure
-
UnbreakableChain: 7 RigidBody2Ds connected by GrooveJoint2Ds.
- The head RigidBody2D is fixed with
freeze=true. - The tail RigidBody2D7 has a mass of 8.0, making it heavy.
- The second GrooveJoint2D has individual
JointBreakParamsset to break if the angle exceeds 90 degrees for 0.5 seconds.
- The head RigidBody2D is fixed with
-
BreakableChain: 6 RigidBody2Ds connected by GrooveJoint2Ds.
- The head RigidBody2D has
freeze=trueandcollision_layer=0, disabling collisions. - RigidBody2D6 has two GrooveJoint2Ds; one is within the BreakableChain, and the other connects to UnbreakableChain/RigidBody2D7 (linking the two chains).
- The head RigidBody2D has
Configuration Features
ChainJointSetupToolis placed, but sinceauto_create_seg_nodes=false, seg nodes are placed manually.- The
RopePathBinder2Dscript is attached to Path2D (for UnbreakableChain). - Sprites can be broken using
BooleanSpriteCutterWithTaggedShapes.
3. player.tscn (Player)
Purpose
The player character, featuring the ability to push RigidBody2Ds using RigidBodyPusherNatural.
Structure
Player (GameObject / CharacterBody2D)
├── MoveAndJumpSettings
├── BaseSettings
├── CollisionShape2D (CircleShape2D, radius: 25.02)
├── AnimationPlayer
├── VariableSettings
├── Node2D (RigidBodyPusherNatural)
│ ├── script: rigid_body_pusher.gd
│ ├── min_owner_position_delta_pixels: 1.0
│ ├── min_owner_real_speed: 1.0
│ ├── push_strength: 2000.0
│ ├── min_push_force: 100.0
│ ├── max_force: 2000.0
│ ├── max_impulse: 2000.0
│ ├── mass_influence: 1.0
│ ├── normal_direction_weight: 0.0
│ └── movement_direction_weight: 1.0
├── Connector
└── Sprite2D (mech.png)
Configuration Features
- With
normal_direction_weight=0.0andmovement_direction_weight=1.0, it pushes only in the movement direction. - It pushes strongly with
push_strength=2000.0. - It fully considers mass with
mass_influence=1.0.
4. areabreaker.tscn (Area Breaker Test Object)
Purpose
An object for testing the functionality of breaking all joints within an Area2D range using AreaJointBreaker2D.
Structure
Areabreaker (Area2DGameObject)
├── AreaJointBreaker2D (Node2D)
│ ├── script: area_joint_breaker.gd
│ ├── target_area: Area2D
│ └── rotation: 0.952787
│ └── Area2D
│ └── CollisionShape2D (RectangleShape2D, size: 155x35)
├── BaseSettings
├── CollisionShape2D (disabled)
├── AnimationTree (AnimationPlayer)
│ └── cut animation
│ └── Calls AreaJointBreaker2D.break_joints_in_target_area()
├── PathRibbonMesh2D (For breaking effect)
│ ├── path_nodes: [../Path2D]
│ ├── width: 3.0
│ └── progress_percent, start_percent are controlled by animation
└── Path2D (Path for breaking effect)
Configuration Features
- The
target_areaofAreaJointBreaker2Dis set toArea2D. - It calls
break_joints_in_target_area()via animation. - It visualizes the breaking effect using
PathRibbonMesh2D.
5. game_scene.tscn (Main Game Scene)
Purpose
The main game scene where various objects are placed.
Structure
GameScene
├── SceneLayer
│ ├── DistantView (Parallax2D)
│ ├── MiddleView (Parallax2D)
│ ├── NearView (Parallax2D)
│ ├── WallLayer (Parallax2D)
│ │ ├── Wall (TileMapLayer)
│ │ └── WallDecoration (TileMapLayer)
│ └── BaseLayer (Parallax2D)
│ └── Base (TileMapLayer)
│ ├── Testrope2 (Instance of testrope_2.tscn)
│ │ └── position: (-564, -17)
│ │ └── rotation: 0.0794073
│ ├── StaticBody2D (Floor)
│ ├── Player (Instance of player.tscn)
│ │ └── position: (-612, -80)
│ ├── Ball (Instance of testrope_ball_3.tscn)
│ │ └── position: (121, 38)
│ ├── Platform1, Platform2 (Instances of platform_1.tscn)
│ └── Pillar (Instance of pillar.tscn)
│ └── position: (186, 118)
├── PostEffectLayer (CanvasLayer)
└── UI (CanvasLayer)
Placed Objects
Testrope2: Rope test object (Position: -564, -17)Player: Player (Position: -612, -80)Ball: Chain test object with ball (Position: 121, 38)Platform1,Platform2: PlatformsPillar: Pillar (Belongs toSpriteGroup, breakable)
Details of Joint Usage Locations
1. Joint Structure in testrope_2.tscn
GrooveJoint2D Placement
| Joint | Parent | node_a | node_b | Position | Settings |
|---|---|---|---|---|---|
| StaticBody2D/PinJoint2D3 | StaticBody2D | .. | ../../Node2D/RigidBody2D | (12, 4) | Head fixed |
| RigidBody2D2/PinJoint2D2 | RigidBody2D2 | ../../RigidBody2D | .. | (0, -16) | RigidBody2D → RigidBody2D2 |
| RigidBody2D3/PinJoint2D2 | RigidBody2D3 | ../../RigidBody2D2 | .. | (0, -16) | RigidBody2D2 → RigidBody2D3 |
| RigidBody2D4/PinJoint2D2 | RigidBody2D4 | ../../RigidBody2D3 | .. | (0, -16) | RigidBody2D3 → RigidBody2D4 |
| RigidBody2D5/PinJoint2D2 | RigidBody2D5 | ../../RigidBody2D4 | .. | (0, -16) | RigidBody2D4 → RigidBody2D5 |
| RigidBody2D6/PinJoint2D2 | RigidBody2D6 | ../../RigidBody2D5 | .. | (0, -16) | RigidBody2D5 → RigidBody2D6 |
| RigidBody2D7/PinJoint2D2 | RigidBody2D7 | ../../RigidBody2D6 | .. | (0, -16) | RigidBody2D6 → RigidBody2D7 |
| StaticBody2D2/PinJoint2D2 | StaticBody2D2 | ../../Node2D/RigidBody2D7 | .. | (-13, 6) | Tail fixed |
Common Settings
bias: 0.2(Softer connection with a low value)length: 8.0(Groove length)initial_offset: 2.0(Initial offset)
Monitoring Settings
BreakableJointMonitor2Dbreaks if the angle exceeds 80 degrees for 0.3 seconds.ChainPathBinder2Dgenerates paths in auto-detection mode.
2. Joint Structure in testrope_ball_3.tscn
GrooveJoint2D in UnbreakableChain
| Joint | Parent | node_a | node_b | Settings |
|---|---|---|---|---|
| RigidBody2D2/GrooveJoint2D | RigidBody2D2 | ../../RigidBody2D | .. | bias: 0.9, length: 8.0, initial_offset: 1.0 |
| RigidBody2D3/GrooveJoint2D | RigidBody2D3 | ../../RigidBody2D2 | .. | Same as above |
| RigidBody2D4/GrooveJoint2D | RigidBody2D4 | ../../RigidBody2D3 | .. | Same as above |
| RigidBody2D5/GrooveJoint2D | RigidBody2D5 | ../../RigidBody2D4 | .. | Same as above |
| RigidBody2D6/GrooveJoint2D | RigidBody2D6 | ../../RigidBody2D5 | .. | Same as above |
| RigidBody2D7/GrooveJoint2D | RigidBody2D7 | ../../RigidBody2D6 | .. | Same as above |
GrooveJoint2D in BreakableChain
| Joint | Parent | node_a | node_b | Settings |
|---|---|---|---|---|
| RigidBody2D2/GrooveJoint2D | RigidBody2D2 | ../../RigidBody2D | .. | bias: 0.9, length: 8.0, initial_offset: 1.0 |
| RigidBody2D3/GrooveJoint2D | RigidBody2D3 | ../../RigidBody2D2 | .. | Same as above |
| RigidBody2D4/GrooveJoint2D | RigidBody2D4 | ../../RigidBody2D3 | .. | Same as above |
| RigidBody2D5/GrooveJoint2D | RigidBody2D5 | ../../RigidBody2D4 | .. | Same as above |
| RigidBody2D6/GrooveJoint2D | RigidBody2D6 | ../../RigidBody2D5 | .. | Same as above |
| RigidBody2D6/GrooveJoint2D2 | RigidBody2D6 | .. | ../../../UnbreakableChain/RigidBody2D7 | Same as above (Links the two chains) |
Individual Settings
RigidBody2D2/GrooveJoint2DhasJointBreakParamsset to break if the angle exceeds 90 degrees for 0.5 seconds.
Monitoring Settings
- Both
UnbreakableChainandBreakableChainhaveBreakableJointMonitor2DandChainPathBinder2Dconfigured.
System Interactions
1. Chain Visualization System
testrope_2.tscn
ChainPathBinder2Dautomatically detects RigidBody2Ds underNode2D.- It uses
seg1andseg2of each RigidBody2D as nodes. - It updates the
Curve2DofPath2D. PathRibbonMesh2Ddraws the ribbon mesh using thebelt.pngtexture.
testrope_ball_3.tscn
ChainPathBinder2Dis configured for bothUnbreakableChainandBreakableChain.UnbreakableChainis drawn withchain.png, andBreakableChainwithrope.png.- The
Path2DofUnbreakableChainhas theRopePathBinder2Dscript attached (a different visualization method).
2. Joint Breaking System
testrope_2.tscn
BreakableJointMonitor2Dmonitors all joints.- It breaks if the angle exceeds 80 degrees for 0.3 seconds.
- When broken,
ChainPathBinder2Dautomatically splits the path.
testrope_ball_3.tscn
BreakableJointMonitor2DforUnbreakableChainhas individual settings.- Only
RigidBody2D2/GrooveJoint2Dbreaks if the angle exceeds 90 degrees for 0.5 seconds. - Other joints use global settings (disabled).
3. Player Push System
player.tscn
RigidBodyPusherNaturalruns aftermove_and_slide()ofCharacterBody2D.- It pushes contacted
RigidBody2Dsin the movement direction. - It pushes strongly with
push_strength=2000.0.
4. Area Breaking System
areabreaker.tscn
AreaJointBreaker2Dbreaks all joints within theArea2Drange at once.- It calls
break_joints_in_target_area()via animation. - It visualizes the breaking effect using
PathRibbonMesh2D.
Project Settings
Autoload
FragmentManagerSingleton: Fragment management system (fragment_manager.tscnobject)
Global Groups
CutterShapeGroup: Mask shape group for sprite cutting.SpriteGroup: Sprite cutting target group.
Input Map
right: Move right (Right Arrow Key)left: Move left (Left Arrow Key)jump: Jump (Space)cut: Cut (Z)
Placement of Used Scripts
testrope_2.tscn
BreakableJointMonitor2D(scripts/breakable_joint_monitor_2d.gd)ChainPathBinder2D(scripts/chain_path_binder.gd)PathRibbonMesh2D(scripts/path_ribbon_mesh_2d.gd)ChainPartResource(scripts/chain_part.gd) - As resources, 7 instances
testrope_ball_3.tscn
ChainJointSetupTool(scripts/chain_setup_tool.gd)RopePathBinder2D(scripts/rope_solver.gd) - Attached to Path2DChainPathBinder2D(scripts/chain_path_binder.gd) - 2 instancesBreakableJointMonitor2D(scripts/breakable_joint_monitor_2d.gd) - 2 instancesJointBreakParams(scripts/joint_break_params.gd) - As resources, 1 instancePathRibbonMesh2D(scripts/path_ribbon_mesh_2d.gd) - 2 instancesBooleanSpriteCutterWithTaggedShapes(scripts/boolean_sprite_cutter_with_tagged_shapes.gd)
player.tscn
RigidBodyPusherNatural(scripts/rigid_body_pusher.gd)
areabreaker.tscn
AreaJointBreaker2D(scripts/area_joint_breaker.gd)PathRibbonMesh2D(scripts/path_ribbon_mesh_2d.gd)
Joint Types and Usage Status
GrooveJoint2D
Usage Locations
testrope_2.tscn: Between 7 RigidBody2Ds + 2 StaticBody2Ds for fixing = Total 9testrope_ball_3.tscn:- UnbreakableChain: 6 (RigidBody2D2 to RigidBody2D7)
- BreakableChain: 6 (RigidBody2D2 to RigidBody2D6) + 1 (for connecting to UnbreakableChain) = Total 7
Setting Patterns
-
testrope_2.tscn Pattern
bias: 0.2(Soft)length: 8.0initial_offset: 2.0
-
testrope_ball_3.tscn Pattern
bias: 0.9(Hard)length: 8.0initial_offset: 1.0
PinJoint2D
Usage Locations
- Not used in this project (all are GrooveJoint2Ds).
Chain Structure Patterns
Pattern 1: Single Chain (testrope_2.tscn)
StaticBody2D (Fixed)
└── GrooveJoint2D
└── RigidBody2D1
└── GrooveJoint2D
└── RigidBody2D2
└── GrooveJoint2D
└── ...
└── RigidBody2D7
└── GrooveJoint2D
└── StaticBody2D (Fixed)
Pattern 2: Branching Chain (testrope_ball_3.tscn)
UnbreakableChain:
RigidBody2D1 (freeze)
└── GrooveJoint2D
└── RigidBody2D2
└── GrooveJoint2D
└── ...
└── RigidBody2D7 (Ball)
BreakableChain:
RigidBody2D1 (freeze)
└── GrooveJoint2D
└── RigidBody2D2
└── GrooveJoint2D
└── ...
└── RigidBody2D6
├── GrooveJoint2D (Within BreakableChain)
└── GrooveJoint2D2 (Connected to UnbreakableChain/RigidBody2D7)
Physics Settings
RigidBody2D Settings
testrope_2.tscn
linear_damp: 10.0(Linear damping)angular_damp: 10.0(Angular damping)
testrope_ball_3.tscn
mass: 3.0(Normal link)mass: 8.0(RigidBody2D7, ball part)freeze: true(Head RigidBody2D)continuous_cd: 2(Continuous collision detection)
Visualization System
Usage of PathRibbonMesh2D
testrope_2.tscn
- Texture:
belt.png - Width: 20.0
testrope_ball_3.tscn
- UnbreakableChain:
chain.png, Width: 20.0 - BreakableChain:
rope.png, Width: 20.0
areabreaker.tscn
- Texture:
GradientTexture2D(Gradient) - Width: 3.0 (Changes via animation)
Breaking System
BooleanSpriteCutterWithTaggedShapes
testrope_ball_3.tscn
voronoi_seed_count: 30(Fineness of fragments)disable_related_collisions_on_cut: true(Disables surrounding collisions upon cutting)UnbreakableChain/RigidBody2D7/Node2D/CollisionShape2Dbelongs toCutterShapeGroupand is used as a breaking mask.
Summary
This project implements a joint, chain, and rope system with the following structure:
- testrope_2.tscn object: A 7-link chain connected by GrooveJoint2Ds, breakable via angle monitoring.
- testrope_ball_3.tscn object: Two chains (UnbreakableChain and BreakableChain) linked together, with individual settings allowing only specific parts to break.
- player.tscn object: Pushes RigidBody2Ds using RigidBodyPusherNatural.
- areabreaker.tscn object: Breaks all joints within a range using AreaJointBreaker2D.
All chains are visualized by ChainPathBinder2D and drawn as ribbon meshes by PathRibbonMesh2D.