Bevy ECS skill for 2D sprite animation. Keywords: Bevy, sprite, animation, AnimationPlayer, AnimationClip, 2D.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Expert blueprint for sandbox games (Minecraft, Terraria, Garry's Mod) with physics-based interactions, cellular automata, emergent gameplay, and creative tools. Use when building open-world creation games with voxels, element systems, player-created structures, or procedural worlds. Keywords voxel, sandbox, cellular automata, MultiMesh, chunk management, emergent behavior, creative mode.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
실행 점수 미검증
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
RigidBody nodes for every block; strictly use Static Colliders for the world and reserve physics for dynamic props.MultiMesh buffers every frame; strictly batch changes and only rebuild the buffer when a modification completes (e.g., player stops painting).Nodes for every grid cell; strictly use PackedInt32Arrays or typed Dictionaries to keep RAM overhead minimal.floor(pos/size)) for direct O(1) cell calculation.ArrayMesh that only pushes visible exterior faces to the GPU (Culling/Greedy Meshing).ResourceLoader.load_threaded_request() to prevent frame stutter..tscn files for voxel datasets; strictly use binary .res files for 10x faster parsing.if water and fire); strictly use a Property System where interactions emerge from material attributes (flammability, density).call_deferred() or Mutex locks for safety.queue_free() on discarded branches.MANDATORY / Do NOT Load by path
- 2D falling-sand / CA only: load
cellular_automata_liquid.gd+ property/tool patterns below. Do NOT Loadvoxel_chunk_*.gd,voxel_world.gd, or greedy-mesh paths.- 3D voxel / chunk worlds: load
voxel_world.gd→voxel_chunk_manager.gd→ MANDATORYvoxel_chunk_mesher.gdfor exterior-face meshes. Do NOT Load 2D CA liquid unless you also run a 2D element layer.- Placement / multiplayer validation: load
dynamic_placement_validator.gdbefore trusting client dig/place.- Persistence: load
sandbox_world_serializer.gdfor RLE/binary chunk IO; keepsandbox_patterns.gdfor async load + floating origin.
MultiMeshInstance3D batch updates for medium worlds.ArrayMesh build + deferred set_mesh.Model material properties, not behaviors. Interactions emerge from overlapping properties.
# element_data.gd
class_name ElementData extends Resource
enum Type { SOLID, LIQUID, GAS, POWDER }
@export var id: String = "air"
@export var type: Type = Type.GAS
@export var density: float = 0.0 # For liquid flow direction
@export var flammable: float = 0.0 # 0-1: Chance to ignite
@export var ignition_temp: float = 400.0
@export var conductivity: float = 0.0 # For electricity/heat
@export var hardness: float = 1.0 # Mining time multiplier
# EDGE CASE: What if two elements have same density but different types?
# SOLUTION: Use secondary sort (type enum priority: SOLID > LIQUID > POWDER > GAS)
func should_swap_with(other: ElementData) -> bool:
if density == other.density:
return type > other.type # Enum comparison: SOLID(0) > GAS(3)
return density > other.density
Update order matters. Top-down prevents "teleporting" godot-particles.
# world_grid.gd
var grid: Dictionary = {} # Vector2i -> ElementData
var dirty_cells: Array[Vector2i] = []
func _physics_process(_delta: float) -> void:
# CRITICAL: Sort top-to-bottom to prevent double-moves
dirty_cells.sort_custom(func(a, b): return a.y < b.y)
for pos in dirty_cells:
simulate_cell(pos)
dirty_cells.clear()
func simulate_cell(pos: Vector2i) -> void:
var cell = grid.get(pos)
if not cell: return
match cell.type:
ElementData.Type.LIQUID, ElementData.Type.POWDER:
# Try down, then down-left, then down-right
var targets = [pos + Vector2i.DOWN,
pos + Vector2i(- 1, 1),
pos + Vector2i(1, 1)]
for target in targets:
var neighbor = grid.get(target)
if neighbor and cell.should_swap_with(neighbor):
swap_cells(pos, target)
mark_dirty(target)
return
ElementData.Type.GAS:
# Gases rise (inverse of liquids)
var targets = [pos + Vector2i.UP,
pos + Vector2i(-1, -1),
pos + Vector2i(1, -1)]
# Same swap logic...
# EDGE CASE: What if multiple godot-particles want to move into same cell?
# SOLUTION: Only mark target dirty, don't double-swap. Next frame resolves conflicts.
Decouple input from world modification.
# tool_base.gd
class_name Tool extends Resource
func use(world_pos: Vector2, world: WorldGrid) -> void: pass
# tool_brush.gd
extends Tool
@export var element: ElementData
@export var radius: int = 1
func use(world_pos: Vector2, world: WorldGrid) -> void:
var grid_pos = Vector2i(floor(world_pos.x), floor(world_pos.y))
# Circle brush pattern
for x in range(-radius, radius + 1):
for y in range(-radius, radius + 1):
if x*x + y*y <= radius*radius: # Circle boundary
var target = grid_pos + Vector2i(x, y)
world.set_cell(target, element)
# FALLBACK: If element placement fails (e.g., occupied by indestructible block)?
# Check world.can_place(target) before set_cell(), show visual feedback.
MANDATORY: For exterior-face / greedy-style chunk meshes, read and adapt voxel_chunk_mesher.gd (WorkerThreadPool + SurfaceTool + call_deferred("set_mesh")). Do not inline incomplete mesher stubs in project code.
| World scale | Render path | Load |
|---|---|---|
| Small (<100k blocks) | Single MeshInstance3D + SurfaceTool | Mesher patterns only |
| Medium (100k–1M) | Chunked MultiMeshInstance3D (one mesh, many instances; batch buffer on edit complete) | MANDATORY voxel_chunk_manager.gd |
| Large (>1M) / editable terrain | Chunked ArrayMesh with visible-face / greedy quads + LOD; optional RenderingServer instance RIDs | MANDATORY voxel_chunk_mesher.gd + manager |
Rule: Prefer MultiMesh when every instance shares one mesh and you only need per-instance transforms/colors. Prefer ArrayMesh meshing when adjacent voxels must merge into unique surfaces (greedy faces, UV atlases, per-chunk collision).
# chunk_save_data.gd
class_name ChunkSaveData extends Resource
@export var chunk_coord: Vector2i
@export var rle_data: PackedInt32Array # [type_id, count, type_id, count...]
# EXPERT TECHNIQUE: Run-Length Encoding
static func encode_chunk(grid: Dictionary, chunk_pos: Vector2i, chunk_size: int) -> ChunkSaveData:
var data = ChunkSaveData.new()
data.chunk_coord = chunk_pos
var run_type: int = -1
var run_count: int = 0
for y in range(chunk_size):
for x in range(chunk_size):
var world_pos = chunk_pos * chunk_size + Vector2i(x, y)
var cell = grid.get(world_pos)
var type_id = cell.id if cell else 0 # 0 = air
if type_id == run_type:
run_count += 1
else:
if run_count > 0:
data.rle_data.append(run_type)
data.rle_data.append(run_count)
run_type = type_id
run_count = 1
# Flush final run
if run_count > 0:
data.rle_data.append(run_type)
data.rle_data.append(run_count)
return data
# COMPRESSION RESULT: Empty chunk (16×16 = 256 blocks of air)
# Without RLE: 256 integers = 1024 bytes
# With RLE: [0, 256] = 8 bytes (128x compression!)
# joint_tool.gd
func create_hinge(body_a: RigidBody2D, body_b: RigidBody2D, anchor: Vector2) -> void:
var joint = PinJoint2D.new()
joint.global_position = anchor
joint.node_a = body_a.get_path()
joint.node_b = body_b.get_path()
joint.softness = 0.5 # Allows slight flex
add_child(joint)
# EDGE CASE: What if bodies are deleted while joint exists?
# Joint will auto-break in Godot 4.x, but orphaned Node leaks memory.
# SOLUTION:
body_a.tree_exiting.connect(func(): joint.queue_free())
body_b.tree_exiting.connect(func(): joint.queue_free())
# FALLBACK: Player attaches joint to static geometry?
# Check `body.freeze == false` before creating joint.
MultiMeshInstance3D.multimesh.instance_count: MUST be set before buffer allocation. Cannot dynamically grow — requires recreation.RigidBody2D.sleeping: Bodies auto-sleep after 2 seconds of no movement. Use apply_central_impulse(Vector2.ZERO) to force wake without adding force.GridMap vs MultiMesh: GridMap uses MeshLibrary (great for variety), MultiMesh uses single mesh (great for speed). Combine: GridMap for structures, MultiMesh for terrain.continuous_cd requires convex collision shapes. Use CapsuleShape2D for projectiles, NOT RectangleShape2D.Do not paste placeholder meshers. MANDATORY read voxel_chunk_mesher.gd for threaded visible-face generation. Extend that pattern for full greedy quad merging; for MultiMesh vs ArrayMesh choice see §4 above. Extreme draw paths may push committed arrays via RenderingServer (see Official Documentation → Using servers) after the mesher owns the surface data.
Sandbox chunk lighting is not owned by an incomplete RenderingServer.voxel_gi_allocate_data stub here. For dynamic GI on procedural volumes, follow Using VoxelGI and route implementation detail to godot-3d-lighting. Prefer baked/probe strategies from that skill unless you truly need runtime VoxelGI.
Allow players to share creations via simple strings. Use JSON for readable serialization and DisplayServer for clipboard integration.
class_name BlueprintManager extends Node
## Exports chunk data to the OS clipboard.
static func export_blueprint_to_clipboard(blueprint_data: Dictionary) -> void:
var json_string: String = JSON.stringify(blueprint_data)
DisplayServer.clipboard_set(json_string)
## Imports blueprint from clipboard.
static func import_blueprint_from_clipboard() -> Dictionary:
var json_string: String = DisplayServer.clipboard_get()
var parsed_data = JSON.parse_string(json_string)
return parsed_data if parsed_data is Dictionary else {}
| Topic | Reference / script |
|---|---|
| Elite meshing & blueprint sharing | elite-technical-patterns.md + voxel_chunk_mesher.gd |
| Element / CA grids | Architecture Patterns §1–3 in SKILL.md + cellular_automata_liquid.gd |
| Chunk RLE persistence | Save System § in SKILL.md + sandbox_world_serializer.gd |
Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
var_to_str, binary Resources)..res world data.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Bevy ECS skill for 2D sprite animation. Keywords: Bevy, sprite, animation, AnimationPlayer, AnimationClip, 2D.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Bevy ECS skill for 3D lights. Keywords: Bevy, lighting, directional, point, spot, bevy_light, PBR.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Bevy ECS skill for PBR materials. Keywords: Bevy, StandardMaterial, PBR, material, ExtendedMaterial.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Bevy ECS skill for 3D level assembly. Keywords: Bevy, level, scene, mesh, world, ECS.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Bevy ECS skill for abilities. Keywords: Bevy, ability, cooldown, ECS, gameplay.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Bevy ECS skill for moving a Bevy game from 2D to 3D. Keywords: Bevy, 2D, 3D, adapt, camera, sprite.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.