decentraland / decentraland/godot-explorer

Locomotion Iteration #2: Scene Collider Generation & Collision Layers v Unity

Open
#2,853 0 comments 0 reactions 1 assignee Claimed by @manuelmaceira View on GitHub
bug controls feature parity locomotion-pass-2 mobile
Dominant language
Rust
Stars
18
Forks
19
Avg merge
4d 2h
Merged PRs (30d)
43

Description

## **⚠️ Problem:**
Godot marks any scene mesh thinner than 1 cm on any axis as one-way, so thin floors and ramps collide only from above — players fall through geometry that is solid on desktop. The player also collides with a single layer, so scene-placed invisible blockers and several SDK collider categories do not exist for the avatar at all. Drives **Playtime**.

## **🏁 Scope:**
GLTF + primitive collider generation (`scene.rs`, `mesh_collider.rs`) and the player collision mask (`player.tscn`, `project.godot`). Character movement systems are the sibling Iteration 2 issue.

## **📝 Deliverables:**
- [ ] Thin-mesh colliders double-sided — remove the `< 0.01` planar/AABB one-way path (B2)
- [ ] Player collision mask widened from `CL_PHYSICS` alone to the 6 Unity-equivalent layers (B3)
- [ ] Invisible blocker colliders block the avatar
- [ ] Avatar-only collider layer added, routed like Unity's `SDKAvatarHit` (M13)
- [ ] `SDKAvatarTriggerArea` + `SDKEntityTriggerArea` reachable by the player mask
- [ ] Regression: creator-authored one-way colliders still behave one-way
- [ ] #1529, #1203 and #1748 verified as no longer reproducing
- [ ] `decentraland/docs` issue filed if creator-facing collider semantics change; linked here

## Metrics
Playtime. Fall-through incidents per session; no instrumented baseline — measure via the #905 reproduction checklist (B2: approach thin elevated floors from below, Unity blocks and Godot passes through; B3: walk into invisible blocker walls).

## Findings

| | Godot `main` | Unity |
|---|---|---|
| GLTF colliders | trimesh per mesh (`scene.rs:169`) | `MeshCollider`, `BakeMesh` (`ConfigureGltfContainerColliders.cs:93-100`) ✓ |
| Backfaces | only non-planar meshes; planar = AABB thinner than 0.01 (`scene.rs:219,227-229`) | always double-sided |
| Primitive colliders | box / sphere / cylinder / plane shapes | same mapping ✓ |
| Player mask | `CL_PHYSICS` only (`player.tscn:20`) | 6 layers incl. `InvisibleColliders`, `CharacterOnly`, `SDKAvatarTriggerArea` |
| SDK layer routing | 6 functional + 13 reserved/custom layers | avatar-only → `SDKAvatarHit` route (`PhysicsLayers.cs:123-127`) |

Two of the six parity bugs live here. B2 is the direct cause candidate for #1529, #1203 and #1748. The one-way flag is set in our code, not by the solver — the Jolt migration (#2844) will not close it, which is why the audit gates re-evaluating Jolt on this fix landing first.

## Dependency
Blocks the Jolt re-evaluation noted in #2844. Audit §7: re-test thin-geometry tunneling only after B2 lands, otherwise the two changes are unattributable.

## **🔗 References:**
- [#1748](https://github.com/decentraland/godot-explorer/issues/1748) — mobile falls through BBQ grill grates, desktop stands on them; canonical repro for B2
- [#1529](https://github.com/decentraland/godot-explorer/issues/1529) — one-way colliders act two-way (SPIKE, closed); same root cause
- [#1203](https://github.com/decentraland/godot-explorer/issues/1203) — desktop respects mesh normals, mobile blocks both directions; the inverse symptom, same code path
- [`ConfigureGltfContainerColliders.cs`](https://github.com/decentraland/unity-explorer/blob/dev/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Systems/ConfigureGltfContainerColliders.cs) — Unity's collider bake; double-sided unconditionally
- [`PhysicsLayers.cs`](https://github.com/decentraland/unity-explorer/blob/dev/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/Physics/PhysicsLayers.cs) — layer routing + the avatar-only → `SDKAvatarHit` route to replicate
- [#905](https://github.com/decentraland/godot-explorer/issues/905) — parent audit, §3.6

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.