39 Commits

Author SHA1 Message Date
tom-boullay 4e6582b543 add: panneaux solaire model
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-21 15:39:01 +02:00
tom-boullay e4ee2d768b feat(debug): add map performance visibility controls 2026-05-21 15:38:23 +02:00
tom-boullay 5e594c51f7 docs(perf): document map rendering bottlenecks 2026-05-21 15:34:56 +02:00
tom-boullay 26ddbebe14 refactor(map): add generated R3F model for ecole 2026-05-21 15:34:49 +02:00
tom-boullay 48c2b4f0cd perf(map): merge instanced map asset geometry 2026-05-21 15:34:39 +02:00
tom-boullay cf08062def refactor(world): restore sky fallback chain
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-21 12:10:31 +02:00
tom-boullay 4f25b33d3b feat(debug): persist and reset debug game state 2026-05-21 12:09:12 +02:00
tom-boullay 072dec03b4 refactor: tighten terrain and sky model resource ownership
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-21 11:55:49 +02:00
tom-boullay 529c60adae update: add new sounds + comrpessed models
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-21 10:52:14 +02:00
Tom Boullay 27951d13fd upatde: json + models
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-15 00:18:03 +02:00
Tom Boullay cdd919c010 update: clean map hierarchy and mesh model names
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-14 17:25:39 +02:00
Tom Boullay cea2856fd0 update: models 2026-05-14 17:17:54 +02:00
Tom Boullay d245d6b460 Update vegetationConfig.ts 2026-05-14 16:13:34 +02:00
Tom Boullay dba7aec6fa fix: dupplicate buisson and ecole 2026-05-14 16:13:32 +02:00
Tom Boullay d376d0ba6b update: add new models 2026-05-14 16:13:16 +02:00
Tom Boullay 242a3dcd37 refactor: remove vegetation instance limit (will be handled by chunks later) 2026-05-14 00:26:42 +02:00
Tom Boullay 225ac828df feat: enable all vegetation types and remove debug logs 2026-05-14 00:23:18 +02:00
Tom Boullay 28f7db172c upatde: add new models
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-14 00:20:20 +02:00
Tom Boullay 2063656f29 chore: update eslint config and CI workflow 2026-05-14 00:18:02 +02:00
Tom Boullay 592cfa405f feat: add graphics settings hook 2026-05-14 00:17:53 +02:00
Tom Boullay 0a32cd1d21 feat: add map node caching for vegetation system 2026-05-14 00:17:44 +02:00
Tom Boullay 4516cf4ec6 feat: configure shadow map settings for better shadow quality 2026-05-14 00:17:33 +02:00
Tom Boullay c6f60d1ca7 update: vegetation models 2026-05-14 00:17:08 +02:00
Tom Boullay aa35e97cbb update: skybox model files 2026-05-14 00:16:58 +02:00
Tom Boullay 57c142c8ef fix: correct texture paths case sensitivity in GLTF models 2026-05-14 00:16:47 +02:00
Tom Boullay 4843bf1d75 fix: correct skybox model path 2026-05-14 00:16:37 +02:00
Tom Boullay d02cf29a1d debug: add logging for scene loading flow 2026-05-14 00:16:28 +02:00
Tom Boullay 3b4c9c2529 feat: add WebGL context loss handler and GPU performance config 2026-05-14 00:16:18 +02:00
Tom Boullay fdf03349cf fix: enable terrain loading for collision octree build 2026-05-14 00:16:09 +02:00
Tom Boullay 439f9c1dad feat: add VegetationSystem with InstancedMesh rendering
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-14 00:16:00 +02:00
Tom Boullay 260bfea716 fix: add disposal on unmount in SkyModel and SimpleModel 2026-05-14 00:15:52 +02:00
Tom Boullay b3a3f3557c fix: add disposal on unmount in TerrainModel 2026-05-14 00:15:41 +02:00
Tom Boullay 621556b38c fix: add disposal on unmount in useClonedObject hook 2026-05-14 00:15:32 +02:00
Tom Boullay 5c55f2c7f4 feat: add disposeObject3D utility for GPU memory cleanup 2026-05-14 00:15:23 +02:00
Tom Boullay bb4bccb175 Update weekly-branch-promotions.yml 2026-05-13 15:26:36 +02:00
Tom Boullay ae835e5008 update: models 2026-05-13 15:00:53 +02:00
Tom Boullay 1d3aa1c9f2 add: world config (wind, graphics, terrain, fog) 2026-05-13 15:00:13 +02:00
Tom Boullay 23cab2da5e update: CI branch promotions schedule 2026-05-13 15:00:05 +02:00
Tom Boullay 44216f9395 update: models 2026-05-13 14:59:57 +02:00
335 changed files with 79000 additions and 35378 deletions
+71 -29
View File
@@ -1,59 +1,58 @@
name: 🔁 Weekly Branch Promotions name: 🔁 Branch Promotions
on: on:
schedule: schedule:
- cron: "0 6 * * 1" - cron: "0 6 * * 1,4" # Lundi et Jeudi à 6h UTC (design → develop)
- cron: "0 6 * * 1" # Lundi à 6h UTC (develop → main)
workflow_dispatch: workflow_dispatch:
inputs:
promotion:
description: "Which promotion to run"
required: true
type: choice
options:
- design-to-develop
- develop-to-main
- both
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
concurrency: concurrency:
group: weekly-branch-promotions group: branch-promotions
cancel-in-progress: false cancel-in-progress: false
jobs: jobs:
open-promotion-pr: design-to-develop:
name: Open ${{ matrix.head }} → ${{ matrix.base }} name: Open design → develop
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: if: |
fail-fast: false (github.event_name == 'schedule') ||
matrix: (github.event_name == 'workflow_dispatch' && (github.event.inputs.promotion == 'design-to-develop' || github.event.inputs.promotion == 'both'))
include:
- head: develop
base: design
title: "chore: merge develop into design"
- head: design
base: main
title: "chore: merge design into main"
steps: steps:
- name: ⬇️ Checkout - name: ⬇️ Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: 🔁 Open promotion PR - name: 🔁 Open promotion PR
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
BASE_BRANCH: ${{ matrix.base }}
HEAD_BRANCH: ${{ matrix.head }}
PR_TITLE: ${{ matrix.title }}
run: | run: |
set -euo pipefail set -euo pipefail
git fetch origin "$BASE_BRANCH" "$HEAD_BRANCH" git fetch origin develop design
if git merge-base --is-ancestor "origin/$HEAD_BRANCH" "origin/$BASE_BRANCH"; then if git merge-base --is-ancestor origin/design origin/develop; then
echo "No promotion needed: $BASE_BRANCH already contains $HEAD_BRANCH." echo "No promotion needed: develop already contains design."
exit 0 exit 0
fi fi
existing_pr="$(gh pr list \ existing_pr="$(gh pr list \
--state open \ --state open \
--base "$BASE_BRANCH" \ --base develop \
--head "$GITHUB_REPOSITORY_OWNER:$HEAD_BRANCH" \ --head "$GITHUB_REPOSITORY_OWNER:design" \
--json number \ --json number \
--jq '.[0].number // empty')" --jq '.[0].number // empty')"
@@ -63,7 +62,50 @@ jobs:
fi fi
gh pr create \ gh pr create \
--base "$BASE_BRANCH" \ --base develop \
--head "$HEAD_BRANCH" \ --head design \
--title "$PR_TITLE" \ --title "chore: merge design into develop" \
--body "Automated weekly promotion PR from \`$HEAD_BRANCH\` to \`$BASE_BRANCH\`." --body "Automated promotion PR from \`design\` to \`develop\`."
develop-to-main:
name: Open develop → main
runs-on: ubuntu-latest
if: |
(github.event_name == 'schedule' && github.event.schedule == '0 6 * * 1') ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.promotion == 'develop-to-main' || github.event.inputs.promotion == 'both'))
steps:
- name: ⬇️ Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 🔁 Open promotion PR
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
git fetch origin main develop
if git merge-base --is-ancestor origin/develop origin/main; then
echo "No promotion needed: main already contains develop."
exit 0
fi
existing_pr="$(gh pr list \
--state open \
--base main \
--head "$GITHUB_REPOSITORY_OWNER:develop" \
--json number \
--jq '.[0].number // empty')"
if [ -n "$existing_pr" ]; then
echo "Promotion PR already open: #$existing_pr."
exit 0
fi
gh pr create \
--base main \
--head develop \
--title "chore: merge develop into main" \
--body "Automated weekly promotion PR from \`develop\` to \`main\`."
+1
View File
@@ -143,6 +143,7 @@ WS ws://localhost:8000/ws
| `docs/technical/hand-tracking.md` | Webcam, backend/browser MediaPipe, glove, and gesture flow | | `docs/technical/hand-tracking.md` | Webcam, backend/browser MediaPipe, glove, and gesture flow |
| `docs/technical/zustand.md` | Game, settings, and subtitle stores | | `docs/technical/zustand.md` | Game, settings, and subtitle stores |
| `docs/technical/three-debugging.md` | DevTools workflow for stepping into Three.js internals | | `docs/technical/three-debugging.md` | DevTools workflow for stepping into Three.js internals |
| `docs/technical/map-performance.md` | Map draw-call bottlenecks and optimization notes |
| `docs/technical/editor.md` | Editor implementation details | | `docs/technical/editor.md` | Editor implementation details |
| `docs/technical/animation.md` | Animated, explodable, and reusable 3D model components | | `docs/technical/animation.md` | Animated, explodable, and reusable 3D model components |
| `docs/user/features.md` | Implemented feature inventory | | `docs/user/features.md` | Implemented feature inventory |
+187
View File
@@ -0,0 +1,187 @@
# Map Performance Notes
This document tracks the current map-rendering performance pass.
## Current Runtime Path
- `public/map.json` is the source of map transforms.
- `src/world/GameMap.tsx` renders regular visual map nodes.
- `src/world/vegetation/VegetationSystem.tsx` already instances dense vegetation.
- `src/world/map-instancing/MapInstancingSystem.tsx` instances selected repeated static map assets.
- `src/world/GameMapCollision.tsx` keeps terrain collision separate for the player octree.
## Draw-Call Bottlenecks Found
The first performance bottleneck was draw calls. Some assets were exported as many small GLTF primitives even when they used only a few materials.
| Model | Instances | Meshes / primitives | Notes |
| ---------------- | --------: | ------------------: | ---------------------------------------------------------------- |
| `generateur` | 3 | 3152 | Worst draw-call offender. Needs asset-side mesh merging. |
| `lafabrik` | 4 | 56 | Moderate draw calls, heavy 2048 texture set. |
| `ecole` | 1 | 107 | One material but many primitives; should be merged. |
| `fermeverticale` | 3 | 1 | Geometry is fine; textures are large for the visible complexity. |
`generateur` was especially expensive because three visible instances could multiply thousands of primitives into thousands of draw calls. Instancing reduces repeated instance cost, but the source asset still needs a cleaner export.
## Runtime Merge Pass
`InstancedMapAsset` now groups source meshes by material and compatible geometry attributes before creating `THREE.InstancedMesh` objects. This reduces the runtime draw groups even when the source GLTF is exported as many small meshes.
Estimated source primitive count versus runtime merged groups:
| Model | Source primitives | Runtime merged groups |
| ------------ | ----------------: | --------------------: |
| `generateur` | 3152 | 8 |
| `ecole` | 107 | 2 |
| `eolienne` | 118 | 8 |
| `lafabrik` | 56 | 14 |
This is a code-side safety net, not a replacement for clean asset exports. Clean GLB exports with merged meshes and fewer textures remain the preferred long-term path.
## Current Triangle Bottleneck
After the runtime merge pass, draw calls can drop dramatically, but FPS can still stay low because the scene now remains triangle-bound. A debug capture after the merge showed roughly:
```txt
138 draw calls
~69.6M triangles
~10 FPS
```
That means the renderer is no longer mostly blocked by draw-call submission. It is mostly drawing too many visible triangles.
Estimated triangle contribution from `map.json` instance counts:
| Model | Instances | Triangles each | Estimated total triangles |
| ------------------- | --------: | -------------: | ------------------------: |
| `buisson` | 646 | 37 500 | ~24.2M |
| `champdesoja` | 1181 | 16 268 | ~19.2M |
| `arbre` | 291 | 38 906 | ~11.3M |
| `champdeble` | 1307 | 6 260 | ~8.2M |
| `champsdetournesol` | 1163 | 3 264 | ~3.8M |
| `sapin` | 93 | 23 972 | ~2.2M |
These vegetation and crop assets account for almost all of the current `~69M` triangle count. By comparison, the previously suspicious static buildings are much smaller in triangle cost:
| Model | Estimated total triangles |
| ---------------- | ------------------------: |
| `generateur` | ~123k |
| `lafabrik` | ~124k |
| `ecole` | ~5k |
| `fermeverticale` | ~1k |
`InstancedMesh` reduces draw calls, but it does not reduce triangle count. If 646 bushes each contain 37 500 triangles, the GPU still has to draw about 24 million bush triangles when those instances are visible.
## Debug Performance Controls
The next useful runtime tool is a debug-only performance folder that can isolate model families. This should be mounted only when `?debug` is enabled.
Proposed controls:
```txt
Performance / Map
- vegetation
- crops
- trees
- buildings
- landmarks
- props
- terrain
- sky
```
Useful per-model toggles:
```txt
buisson
arbre
sapin
champdeble
champdesoja
champsdetournesol
fermeverticale
lafabrik
immeuble1
eolienne
pylone
```
The purpose is diagnostic, not final gameplay behavior. The expected workflow is:
1. Open `/?debug` with R3F perf enabled.
2. Disable one family or model type.
3. Watch `triangles`, `calls`, and FPS.
4. Identify which model groups need LOD, density reduction, or asset re-export.
Recommended implementation files:
```txt
src/managers/stores/useMapPerformanceStore.ts
src/hooks/debug/useMapPerformanceDebug.ts
src/world/vegetation/VegetationSystem.tsx
src/world/map-instancing/MapInstancingSystem.tsx
src/world/GameMap.tsx
```
The store should stay runtime/debug-only. It should not change persisted production map data.
## Triangle-Reduction Follow-Up
Once the expensive model families are isolated, the real triangle fixes are:
1. Lower-poly vegetation and crop exports.
2. LOD variants for trees, bushes, and crop fields.
3. Distance-based culling for vegetation/crop instances.
4. Chunked instancing so Three.js can frustum-cull groups instead of one huge global `InstancedMesh`.
5. Billboard/impostor versions for far vegetation.
Chunked instancing is especially important. A single `InstancedMesh` containing every bush has one global bounding sphere. If that bounding sphere is visible, Three.js may keep the whole batch visible. Splitting instances into grid chunks allows entire offscreen chunks to be skipped.
## Current Code-Side Optimization
Repeated static assets are configured in:
```txt
src/world/map-instancing/mapInstancingConfig.ts
```
Those names are excluded from the regular `GameMap` clone path, then rendered by `MapInstancingSystem` with merged `THREE.InstancedMesh` batches.
This keeps the existing map authoring format while reducing repeated draw calls for selected assets.
## Generated R3F Model Path
Unique static map assets can use explicit R3F components instead of the generic cloned GLTF path. This follows the same intent as `gltfjsx`: expose the model as a React component, then keep control over mesh/material setup in code.
Current generated map-model entry point:
```txt
src/world/map-generated/GeneratedMapNodeInstance.tsx
```
Current generated model component:
```txt
src/components/three/models/generated/EcoleModel.tsx
```
`ecole` is a safe first candidate because it appears once in `map.json`, has one material, and does not participate in player collision or repair gameplay. Its source GLTF has 107 primitives, so the generated component also merges compatible geometry groups before mounting the meshes.
This path should be used selectively. It improves control and can remove clone overhead, but it does not reduce source triangle count by itself.
## Asset-Side Follow-Up
Design/export should prioritize:
1. Produce lower-poly `buisson`, `arbre`, `sapin`, and crop assets.
2. Add LOD or billboard variants for far vegetation.
3. Merge `generateur` meshes from 3152 primitives to a small number of material groups.
4. Reduce `lafabrik` texture count and downscale flat/low-detail maps.
5. Merge `ecole` primitives because it uses a single material.
6. Prefer runtime `.glb` or compressed runtime textures when the pipeline supports it.
## Safety Rules
- Do not instance `terrain` for player collision without validating `Octree.fromGraphNode` support.
- Do not replace repair-game models with optimized map models unless repair node names are preserved.
- Dispose only GPU resources created locally. Do not dispose textures or geometries owned by `useGLTF`'s cache.
+1 -1
View File
@@ -7,7 +7,7 @@ import tseslint from "typescript-eslint";
import { defineConfig, globalIgnores } from "eslint/config"; import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([ export default defineConfig([
globalIgnores(["dist"]), globalIgnores(["dist", "POC-grass"]),
{ {
files: ["**/*.{ts,tsx}"], files: ["**/*.{ts,tsx}"],
extends: [ extends: [
Binary file not shown.
+38279 -32509
View File
File diff suppressed because it is too large Load Diff
+35051
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More