BooleanSpriteCutterWithTaggedShapes / FragmentManager English Manual Part 2(About Script)

This topc explains about BooleanSpriteCutterWithTaggedShapes Script/ Fragment Manager Script.
Note: Part 1 is Here https://guild.rpgmakerofficial.com/t/topic/1115

BooleanSpriteCutterWithTaggedShapes Overview

BooleanSpriteCutterWithTaggedShapes is a Node2D script that targets Sprite2D nodes (and optionally re-cuttable fragments) in a specified group, uses “mask shape nodes” from another group to cut out intersecting regions, fragments them via Voronoi partitioning + boolean operations, and generates RigidBody2D fragments.
Fragments are categorized as inside (within the mask) and outside (the remainder), and you can configure force, physics, materials, and more separately for each.


Features

  • Batch processing of multiple target sprites via groups (cut multiple at once)
  • Collect mask shapes from another group (sequential processing of multiple masks)
  • Separate settings for inside/outside force (direction/strength/torque)
  • Fragment physics setup modes: Manual / inherit from Sprite / inherit from Shape / inherit from specified node
  • Fragment spawn parent modes: Self / specified node / owner’s parent / owner’s child / Manager
  • Supports re-cutting (re-fragmentation) with separate allow flags for inside/outside
  • Supports edge lines (Line2D) and material inheritance/override

Prerequisites and Requirements

Item Content
Required add-on res://addons/gdDelaunay/Delaunay.gd must exist (it is preloaded)
Targets Sprite2D in target_sprite_group (texture required) / re-cuttable RigidBody2D fragments
Masks Shape nodes in shape_node_group (supported types listed below)
Intersection Cutting occurs only when mask AABB intersects target AABB and polygon intersection exists
Note For the sprite base polygon, only the first element of opaque_to_polygons() is used (materials with multiple separate opaque islands may behave differently from intention)

Setup

  1. Place a Node2D in the scene and attach this script.
  2. Add the Sprite2D you want to break to target_sprite_group (default: SpriteGroup).
  3. Add mask nodes to shape_node_group (default: CutterShapeGroup).
  • Examples: Polygon2D / CollisionPolygon2D / CollisionShape2D (Convex/Concave/Circle/Rectangle)
  1. Configure parameters in the Inspector (minimum: alpha_threshold, simplify_tolerance, voronoi_seed_count).
  2. Call call_cut() at the desired moment.
  • Examples: input, buttons, collision events, animation events, etc.

Generated Node Specification

Generated object Structure Meta / Group Notes
Inside fragments RigidBody2D (children: Polygon2D + CollisionPolygon2D + optional Line2D) META_IS_FRAGMENT=true / META_FRAGMENT_TYPE="inside" / META_FRAGMENT_SOURCE_SPRITE=source Sprite / added to target_sprite_group If unfreeze_delay>0, fragments are temporarily frozen then unfrozen and forces applied after timer
Outside fragments Same as above META_FRAGMENT_TYPE="outside" Outside force/physics/material settings are applied
Source Sprite2D Hidden META_ALREADY_CUT=true Prevents double-cutting the same sprite
Re-cut source (fragment) queue_free() - During re-cutting, the original fragment is replaced

Usage Examples

Goal (use case) Setting Result Notes
Fragment only the area touched by the mask Add a mask shape to shape_node_groupcall_cut() Only intersecting sprites generate fragments Multiple masks are processed sequentially
Throw inside fragments to the right inside_force_direction_mode=FixedVector, inside_force_fixed_vector=(1,0) Inside fragments fly in a constant direction Strength is inside_force_base_strength
Scatter radially from an explosion center *_force_direction_mode=ExplosionFromPoint, set *_explosion_center_node Fragments scatter outward You can override center via call_cut(force_config)
Larger pieces get stronger force/rotation use_area_scaling_for_impulse=true / use_area_scaling_for_torque=true Force and torque scale by area ratio Clamped by area_ratio_min/max
Organize fragments under a specific node fragment_parent_mode=SpecifiedNode (set fragment_parent_node) Fragments are grouped under the specified node You can also select Manager
Re-cut (finish cutting) allow_recutted_inside_fragments=true (and/or outside) Next call_cut() also includes fragments Fragments are added to target_sprite_group
Disable nearby collisions after cutting disable_related_collisions_on_cut=true Disables collisions around the original Generated fragments (META_IS_FRAGMENT) are excluded

Property List

Basics

Property Type / Default Description (behavior/calculation/notes)
target_sprite_group String / "SpriteGroup" Group name to collect cut targets (Sprite2D and allowed fragments)
shape_node_group String / "CutterShapeGroup" Group name to collect mask shape nodes
alpha_threshold float / 0.1 Opaque threshold for BitMap.create_from_image_alpha (alpha >= threshold is opaque)
simplify_tolerance float / 2.0 Simplification tolerance for opaque_to_polygons() (higher is lighter but rougher)
voronoi_seed_count int / 10 Number of Voronoi seeds (more fragments, heavier)
density float / 1.0 Mass coefficient: mass = area_world * density
unfreeze_delay float / 0.0 Delay seconds before unfreezing generated bodies (>0 yields a temporary pause effect)
circle_approx_segments int / 32 Segment count to approximate CircleShape2D as a polygon
debug_log bool / false If true, prints processing logs (normally keep false)

Voronoi Seed Distribution

Property Type / Default Description
voronoi_seed_density_mode enum / Uniform Uniform / TowardMaskCenter / TowardSpriteCenter / TowardNodeCenter
voronoi_seed_density_power float / 2.0 Strength of centering bias (pow(t, power))
voronoi_seed_center_node NodePath / empty Center for TowardNodeCenter (Node2D.global_position)

Force Settings (Inside)

Property Type / Default Description
inside_force_base_strength float / 1000.0 Base impulse strength for inside fragments
inside_force_strength_jitter_ratio float / 0.0 Strength jitter (±ratio; direction fixed)
inside_force_direction_mode enum / FixedVector FixedVector / ExplosionFromPoint
inside_force_fixed_vector Vector2 / (1,0) Direction for FixedVector (normalized internally)
inside_explosion_center_node NodePath / empty Explosion center Node2D for ExplosionFromPoint
inside_torque_impulse float / 0.0 Torque applied to inside fragments

Force Settings (Outside)

Property Type / Default Description
outside_force_base_strength float / 600.0 Base impulse strength for outside fragments
outside_force_strength_jitter_ratio float / 0.0 Strength jitter (±ratio)
outside_force_direction_mode enum / FixedVector FixedVector / ExplosionFromPoint
outside_force_fixed_vector Vector2 / (0,-1) Direction for FixedVector
outside_explosion_center_node NodePath / empty Explosion center
outside_torque_impulse float / 0.0 Torque applied to outside fragments

Size Scaling

Property Type / Default Description
use_area_scaling_for_impulse bool / true Scale impulse by area ratio
use_area_scaling_for_torque bool / true Scale torque by area ratio
area_ratio_min float / 0.2 Minimum clamp for area ratio
area_ratio_max float / 3.0 Maximum clamp for area ratio
impulse_area_exponent float / 0.5 impulse_scale = pow(area_ratio, exponent)
torque_area_exponent float / 1.0 torque_scale = pow(area_ratio, exponent)

Material Settings (Common / Inside / Outside)

Property Type / Default Description
fragment_inherit_material bool / true Inherit the original material (common default)
fragment_use_custom_material bool / false Force-apply a common custom material
fragment_custom_material Material / null Common custom material
inside_fragment_inherit_material bool / true Inside-only: whether to inherit
inside_fragment_use_custom_material bool / false Inside-only: use custom material
inside_fragment_custom_material Material / null Inside-only material
outside_fragment_inherit_material bool / true Outside-only: whether to inherit
outside_fragment_use_custom_material bool / false Outside-only: use custom material
outside_fragment_custom_material Material / null Outside-only material

Edge Line Settings

Property Type / Default Description
draw_edge_line bool / true Draw fragment edges using Line2D
edge_line_width float / 2.0 Line width
edge_line_color_inside Color / white Line color for inside
edge_line_color_outside Color / white Line color for outside

Re-cut Settings

Property Type / Default Description
allow_recutted_inside_fragments bool / false Include inside fragments as targets on the next cut
allow_recutted_outside_fragments bool / false Include outside fragments as targets on the next cut

Disable Original Collisions

Property Type / Default Description
disable_related_collisions_on_cut bool / false Scan and disable collisions around the original sprite (generated fragments excluded)

Fragment Parent (Spawn Destination)

Property Type / Default Description
fragment_parent_mode enum / Self Self / SpecifiedNode / OwnerParent / OwnerChild / Manager
fragment_parent_node NodePath / empty Spawn destination for SpecifiedNode
Note - OwnerChild applies a fallback when re-cutting (owner is a fragment)

Fragment Physics (Inside)

Property Type / Default Description
inside_fragment_physics_mode enum / FromSprite Manual / FromSprite / FromShape / FromSpecified
inside_fragment_physics_reference_node NodePath / empty Reference node for FromSpecified
inside_fragment_gravity_scale_manual float / 1.0 Manual: gravity scale
inside_fragment_collision_layer_manual int(flags) / 1 Manual: Collision Layer
inside_fragment_collision_mask_manual int(flags) / 1 Manual: Collision Mask
inside_fragment_linear_damp_manual float / 0.0 Manual: Linear Damp
inside_fragment_angular_damp_manual float / 0.0 Manual: Angular Damp
inside_fragment_physics_material_manual PhysicsMaterial / null Manual: friction/bounce
inside_fragment_lock_rotation_manual bool / false Manual: lock rotation

Fragment Physics (Outside)

Property Type / Default Description
outside_fragment_physics_mode enum / FromSprite Manual / FromSprite / FromShape / FromSpecified
outside_fragment_physics_reference_node NodePath / empty Reference node for FromSpecified
outside_fragment_gravity_scale_manual float / 1.0 Manual: gravity scale
outside_fragment_collision_layer_manual int(flags) / 1 Manual: Collision Layer
outside_fragment_collision_mask_manual int(flags) / 1 Manual: Collision Mask
outside_fragment_linear_damp_manual float / 0.0 Manual: Linear Damp
outside_fragment_angular_damp_manual float / 0.0 Manual: Angular Damp
outside_fragment_physics_material_manual PhysicsMaterial / null Manual: friction/bounce
outside_fragment_lock_rotation_manual bool / false Manual: lock rotation

Manager Integration

Property Type / Default Description
manager_mode enum / Autoload None / Autoload / SpecifiedNode
manager_autoload_name String / "FragmentManagerSingleton" Autoload name (references /root/<name>)
manager_node NodePath / empty Reference target for SpecifiedNode
Behavior - On fragment generation, calls register_fragment(body) on the resolved Manager (only if the method exists)

Runtime Override (call_cut(force_config))

With the force_config argument to call_cut(), you can override the Inspector force settings only for that call.

Target Key Example value
inside/outside base_strength 1400.0
inside/outside strength_jitter_ratio 0.15
inside/outside direction_mode FORCE_DIR_FIXED_VECTOR or FORCE_DIR_EXPLOSION
inside/outside fixed_vector Vector2(1, 0)
inside/outside explosion_center Vector2(100, 200) (world coordinates)
inside/outside torque_impulse 3.0

FragmentManager Overview

FragmentManager is a Node2D script that manages the RigidBody2D fragments generated by the Cutter. Fragments are registered via register_fragment(), and it can manage count limits, TTL, freeze on settled, and optional off-screen deletion, with separate policies for inside/outside.

Features

  • Separate management policies for inside/outside (limits, TTL, freeze, off-screen deletion)
  • Holds references via WeakRef; references are cleaned up automatically if fragments leave the tree
  • Optionally disables collisions on freeze (set layer/mask to 0)
  • Off-screen checks compute a view rectangle from the viewport Camera2D (skips if unavailable)

Prerequisites and Requirements

  • Assumes Godot 4.x 2D node structure.
  • Managed objects are RigidBody2D passed to register_fragment(body).
  • body must have META_FRAGMENT_TYPE ("inside" / "outside") set by the Cutter.
  • To exclude certain fragments from management, set META_FRAGMENT_NO_MANAGE=true.

Setup

  1. Attach this script to the root node of fragment_manager.tscn.
  2. Register fragment_manager.tscn as an Autoload so it stays under /root.
  3. Ensure the Cutter calls FragmentManager.register_fragment(body) when generating fragments.
  • If the Cutter already implements “call register_fragment on spawn,” ensure the Autoload name and references match.

Generated/Managed Data

  • This node stays as Node2D and internally maintains two lists:
    • _fragments_inside
    • _fragments_outside
  • Registered fragments receive meta data:
    • _boolean_fragment (fragment flag)
    • _fragment_spawn_msec (spawn time in ms)
    • _fragment_last_active_msec (last active time in ms)
  • If inside_fragment_group_name / outside_fragment_group_name are non-empty, fragments are added to those groups at registration.

Usage Examples

Goal (use case) Setting Result Notes
Prevent too many fragments Set inside_max_fragments / outside_max_fragments Old fragments are deleted when exceeding limit No limit if <= 0
Natural disappearance after time *_enable_ttl=true, set *_ttl_seconds Deleted after TTL Spawn time recorded on registration
Stop physics after settling *_enable_freeze_on_settled=true Frozen after sustained low speed Can also disable collisions optionally
Collect fragments off-screen *_delete_when_offscreen=true Deleted after off-screen duration If camera cannot be obtained, check is skipped
Keep specific fragments body.set_meta("_fragment_no_manage", true) Manager ignores that fragment Safest to set immediately after spawn

Property List (FragmentManager)

Property Type / Default Description (behavior/calculation/notes)
inside_fragment_group_name String / "FragmentGroupInside" Group name added on registration for inside fragments. If empty, not added.
inside_max_fragments int / 300 Max inside fragment count. If <= 0, unlimited. Excess is deleted via queue_free() oldest-first.
inside_enable_ttl bool / true Enable TTL deletion for inside fragments.
inside_ttl_seconds float / 8.0 Lifetime in seconds. Deleted when now - spawn_msec >= this.
inside_enable_freeze_on_settled bool / true Enable freeze-on-settled for inside fragments.
inside_settled_linear_speed float / 15.0 Linear speed threshold. Above this is considered “active” and updates last-active time.
inside_settled_angular_speed float / 1.5 Angular speed threshold. Above this is considered “active.”
inside_settled_grace_seconds float / 0.6 If low-speed state lasts this long, freeze is applied.
inside_disable_collision_when_frozen bool / true On freeze, sets collision layer/mask to 0. No unfreeze restoration is performed.
inside_delete_when_offscreen bool / false Enable off-screen deletion for inside fragments.
inside_offscreen_grace_seconds float / 1.0 If off-screen lasts this long, delete. If it returns on-screen, update last-active time.
outside_fragment_group_name String / "FragmentGroupOutside" Group name added on registration for outside fragments. If empty, not added.
outside_max_fragments int / 300 Max outside fragment count. If <= 0, unlimited. Excess deleted oldest-first.
outside_enable_ttl bool / true Enable TTL deletion for outside fragments.
outside_ttl_seconds float / 8.0 Outside lifetime seconds. Deleted when expired.
outside_enable_freeze_on_settled bool / true Enable freeze-on-settled for outside fragments.
outside_settled_linear_speed float / 15.0 Linear speed threshold for outside fragments.
outside_settled_angular_speed float / 1.5 Angular speed threshold for outside fragments.
outside_settled_grace_seconds float / 0.6 Low-speed grace duration for outside fragments.
outside_disable_collision_when_frozen bool / true On freeze, sets collision layer/mask to 0. No restoration.
outside_delete_when_offscreen bool / false Enable off-screen deletion for outside fragments.
outside_offscreen_grace_seconds float / 1.0 Off-screen grace seconds for outside fragments.
debug_log bool / false If true, logs when deleting by limit/TTL/off-screen, etc.

1 Like

It feels like a really good way to enhance the visual expressiveness of the screen.

1 Like