feat: implement TriggerArea component with Object Pool Manager - #945
Merged
Conversation
- Change verbose INFO logs to DEBUG for TriggerArea CREATE/DELETE - Fix clippy cloned_ref_to_slice_refs warnings using std::slice::from_ref - Add #[allow(clippy::too_many_arguments)] to build_trigger_result - Apply cargo fmt formatting
Contributor
📊 Benchmark Report
Click to expand full benchmark reportDecentraland Godot Explorer - Benchmark ReportGenerated: 2025-12-18_13-35-05 Total Tests: 5 📊 Comparison: vs main branch baseline
Table of Contents
Summary OverviewMemory Metrics
Object Counts
Rendering Metrics
Resource Analysis
Detailed Test ResultsTest 1: 1_Terms_and_ConditionsBenchmark Report: 1_Terms_and_ConditionsTimestamp: 2025-12-18_13-32-15 Memory Metrics
Object Counts
Rendering Metrics
Test 2: 2_LobbyBenchmark Report: 2_LobbyTimestamp: 2025-12-18_13-32-21 Memory Metrics
Object Counts
Rendering Metrics
Test 3: 3_MenuBenchmark Report: 3_MenuTimestamp: 2025-12-18_13-32-28 Memory Metrics
Object Counts
Rendering Metrics
Test 4: 4_Explorer_(72, -10)_Goerli_PlazaBenchmark Report: 4_Explorer_(72, -10)_Goerli_PlazaTimestamp: 2025-12-18_13-32-58 Memory Metrics
Object Counts
Rendering Metrics
Resource Analysis
Test 5: 4_Explorer_(-7, 0)_Genesis_PlazaBenchmark Report: 4_Explorer_(-7, 0)_Genesis_PlazaTimestamp: 2025-12-18_13-34-54 Memory Metrics
Object Counts
Rendering Metrics
Resource Analysis
📋 Logs & Artifacts
🔄 Updated: 2025-12-18 13:35:09 UTC |
This comment was marked as outdated.
This comment was marked as outdated.
kuruk-mm
force-pushed
the
feat/trigger-area
branch
from
December 14, 2025 19:12
e454b4c to
cf60e47
Compare
kuruk-mm
force-pushed
the
feat/trigger-area
branch
from
December 14, 2025 19:23
cf60e47 to
74b2f01
Compare
pool manager potential leak thread as an error
- Add TriggerDetector collision to avatars for trigger area detection - Track avatar entity IDs via metadata (dcl_entity_id, dcl_scene_id) - Implement scene-awareness: only fire events for entities in active scene - Separate physical state (entities_inside) from logical state (entities_entered) - Generate synthetic ENTER/EXIT events when entities change scenes while physically inside trigger areas - Query avatar current scene via metadata to handle remote avatar scene changes
kuruk-mm
force-pushed
the
feat/trigger-area
branch
2 times, most recently
from
December 17, 2025 01:15
7a73e4c to
b7812a7
Compare
- Cache avatar scene info in AvatarTriggerInfo struct to avoid per-frame metadata queries - Batch metadata queries across all trigger areas (query each avatar once, not per-area) - Only query metadata when cache indicates potential state change: - If cache says avatar in scene: query to verify they haven't left - If cache says avatar not in scene: query to check if they joined - Skip query entirely when cache matches expected state
kuruk-mm
force-pushed
the
feat/trigger-area
branch
from
December 17, 2025 01:17
b7812a7 to
cdb0f48
Compare
…isable Replace complex state tracking and per-frame polling with simple physics enable/disable based on player scene. When player leaves a parcel scene: - Generate EXIT for all entities inside trigger areas - Disable physics monitoring (area_set_monitor_callback invalid) When player enters a parcel scene: - Re-enable physics monitoring - PhysicsServer3D auto-fires ENTERs for overlapping bodies Removed (~460 lines): - AvatarTriggerInfo struct with last_known_scene cache - entities_entered HashSet (dual state tracking) - sync_entity_states() function (~190 lines of polling) - get_avatar_current_scene() metadata query function - Scene-awareness checks in process_callback_events() - _on_avatar_scene_changed callback in avatar.gd Added (~186 lines): - check_scene_active() function for enable/disable logic - is_active flag on TriggerAreaInstance - last_player_scene_id field on Scene Result: ~26% code reduction, simpler mental model, no per-frame metadata queries, more responsive scene transitions.
Replace partition() with HashMap<SceneId, Vec<PendingTriggerEvent>> for O(1) per-scene drain instead of O(E_total) scanning all events.
leanmendoza
approved these changes
Dec 18, 2025
| // scene_id=-1 means this is a remote avatar (not a scene NPC) | ||
| // NOTE: This must be called AFTER add_child so that _ready() has been called | ||
| // and the @onready trigger_detector variable is initialized | ||
| new_avatar.call( |
Collaborator
There was a problem hiding this comment.
Question here: as far i understood we won't be setting up triggers for non-primary players nor npc avatar. should we comment this line?
Scene-spawned AvatarShapes (dcl_scene_id >= 0) are now filtered out. Only local player and remote avatars (dcl_scene_id == -1) trigger events.
AvatarShapes now have their trigger_detector node freed in avatar.gd when setup_trigger_detection is called with a scene_id >= 0. This prevents scene NPCs from triggering area events.
- Remove dcl_scene_id from avatar.gd (not needed anymore) - Simplify setup_trigger_detection to only take entity_id - AvatarShapes (skip_process=true) have trigger_detector freed in _ready() - Don't call setup_trigger_detection for AvatarShapes in avatar_shape.rs - Simplify trigger_area.rs to not check dcl_scene_id for avatars
Instead of relying on skip_process, explicitly call remove_trigger_detection() from avatar_shape.rs to free the trigger_detector node for scene NPCs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements TriggerArea (ID: 1060) and TriggerAreaResult (ID: 1061) components to detect when the player and other entities enter/exit defined zones.
Reference: ADR-258 | Protocol PR #306 | Closes #686
What Changed
New Components
New Infrastructure
Why We Implemented It This Way
1. PhysicsServer3D Over Area3D Nodes
Instead of creating
Area3DGodot nodes, we usePhysicsServer3Ddirectly:Reasons:
2. Monitor Callbacks for ENTER/EXIT Detection
We use
area_set_monitor_callbackfor event-driven collision detection:Reasons:
STAY events are generated during
update_trigger_area()for entities that remain inside.3. RID Object Pooling
Physics resources (areas, shapes) are pooled instead of created/destroyed:
Reasons:
4. Centralized PoolManager with Leak Detection
Reasons:
&mut PoolManagerinstead of multiple poolsin_usegrows without bounddebug_summary()andlog_stats()for visibility5. Entity-to-Entity Detection
Detects collisions between trigger areas and:
CL_PLAYERcollision layer (4) on CharacterBody3Ddcl_entity_idmetadata on collidersDecision Summary
Test Plan
How to test: Open
decentraland://open?realm=kuruk.dcl.ethor go tokuruk.dcl.ethrealmcreatedstays stable