291 Commits

Author SHA1 Message Date
Tom Boullay 5c8c35cc72 fix: lint and format 2026-05-11 17:32:47 +02:00
Tom Boullay 711c336f1e Merge branch 'develop' into feat/repair-game 2026-05-11 17:31:14 +02:00
math-pixel 12c96b43c1 Merge pull request 'Feat/env-manager' (#1) from feat/env-manager into develop
Reviewed-on: #1
2026-05-11 15:23:31 +00:00
Tom Boullay 2bb2fff310 Update .gitignore 2026-05-11 17:23:00 +02:00
Tom Boullay 052ab34740 fix: merge 2026-05-11 17:01:02 +02:00
Tom Boullay ff21b80d57 fix: a pb with octree 2026-05-11 16:43:02 +02:00
Tom Boullay 8088e67625 fix: a pb with octree 2026-05-11 16:41:11 +02:00
Tom Boullay 6f5137229d update: en dialogue sub 2026-05-11 13:37:12 +02:00
Tom Boullay 6d3a8fde52 update: cinematic references 2026-05-11 13:22:15 +02:00
Tom Boullay 26a9c1c4d4 Update docsTranslations.ts 2026-05-11 13:21:01 +02:00
Tom Boullay f91756bc27 update: document repair movement lock indicator 2026-05-11 13:17:20 +02:00
Tom Boullay e9875206ff update: show repair movement lock indicator 2026-05-11 13:15:16 +02:00
Tom Boullay 841f96f3fd update: doc 2026-05-11 13:14:08 +02:00
Tom Boullay 00b1780b10 update: document repair movement lock 2026-05-11 13:12:37 +02:00
Tom Boullay c81bacc208 update: doc dialogue and cinematic tools 2026-05-11 13:10:26 +02:00
Tom Boullay 49d1a7324c update: lock player movement during repair 2026-05-11 13:09:50 +02:00
Tom Boullay 131fe39311 docs: repair interaction flow 2026-05-11 13:05:46 +02:00
Tom Boullay 3c72298a45 update: assit dialogue and srt creation 2026-05-11 13:05:03 +02:00
Tom Boullay 49e96c7f5a update: improve repair debug mission switching 2026-05-11 13:03:46 +02:00
Tom Boullay e5aeab6534 update: edit cinematic dialogue 2026-05-11 13:01:56 +02:00
Tom Boullay cec4d6ad0d update: reset repair runtime state 2026-05-11 13:01:32 +02:00
Tom Boullay 202ac4628d fix: sequence repair case completion exit 2026-05-11 12:58:37 +02:00
Tom Boullay 6a4d0f7eb1 update: sync dialogue and cinematic 2026-05-11 12:58:12 +02:00
Tom Boullay 40368c22fc add: blocked repair install feedback 2026-05-11 12:56:54 +02:00
Tom Boullay 788e9f0fb3 update: feedback repair model and improve repair case interaction feedback 2026-05-11 12:54:54 +02:00
Tom Boullay 7a439d0879 add: cinematic preview 2026-05-11 12:53:18 +02:00
Tom Boullay 9f5c105c1b update: add dialogue preview 2026-05-11 12:48:59 +02:00
Tom Boullay 72f8acb61c Update RepairCaseModel.tsx 2026-05-11 12:48:38 +02:00
Tom Boullay 3791ab71cd update: add cinecmatic editor 2026-05-11 12:11:58 +02:00
Tom Boullay 1ad4a164ea fix: clarify repair mission locked flow 2026-05-11 12:10:35 +02:00
Tom Boullay cc8ea20536 update: stabilize repair mission stage mounting 2026-05-11 11:51:06 +02:00
Tom Boullay bd14042ca0 update: add dialogue manifest 2026-05-11 11:48:05 +02:00
Tom Boullay 7036b7b0f9 fix: preload repair mission assets 2026-05-11 11:47:20 +02:00
Tom Boullay f4635def91 update: align srt duration 2026-05-11 11:38:19 +02:00
Tom Boullay e16d6e15fa fix repair game suspense boundaries 2026-05-11 11:37:54 +02:00
Tom Boullay f9a6390260 fix: add tracking + add new models 2026-05-11 11:25:17 +02:00
Tom Boullay b521cdd361 update: french srt 2026-05-11 11:22:06 +02:00
Tom Boullay 4218fde63a update: add runtine camera keyframe 2026-05-11 11:13:49 +02:00
Tom Boullay c2ba26ca86 add: loading 2026-05-11 11:11:46 +02:00
Tom Boullay f74a0c5eae update: audio already use 2026-05-11 10:29:46 +02:00
Tom Boullay a93d2dc92c update: audimanager 2026-05-11 10:22:12 +02:00
Tom Boullay 4b7498ae13 update: trigger dialogue en fonction du gameplay 2026-05-11 10:03:07 +02:00
Tom Boullay a34396b958 docs: queue dialogue 2026-05-11 09:43:40 +02:00
Tom Boullay 8cbf696b6e docs: add some docs 2026-05-11 09:18:46 +02:00
Tom Boullay 311c243506 add: dev dialogue manisfest validation panel 2026-05-11 09:09:34 +02:00
math-pixel e8fb859f79 update 2026-05-11 08:56:54 +02:00
math-pixel 17836ec889 update 2026-05-11 08:32:16 +02:00
Tom Boullay 6101bca84f add: dev manifest api validation 2026-05-10 00:54:33 +01:00
Tom Boullay 5889a325ec update: add stereo 2026-05-10 00:50:34 +01:00
Tom Boullay 08f89c9de5 fix: add config vite error srt 2026-05-10 00:49:19 +01:00
Tom Boullay 5ec10f4a35 update: gros commit fix editor srt panel 3 2026-05-10 00:40:26 +01:00
Tom Boullay 71b46b5fea update: gros commit fix editor srt panel 2 2026-05-10 00:37:28 +01:00
Tom Boullay 4a8a1368b2 update: gros commit fix editor srt panl 2026-05-10 00:35:23 +01:00
Tom Boullay c9e5ce3279 update: confort + ui 2026-05-10 00:33:18 +01:00
Tom Boullay f55be58c0b add: audio preview 2026-05-10 00:31:16 +01:00
Tom Boullay 48f2c9ef80 update: generate complete srt template 2026-05-10 00:29:42 +01:00
Tom Boullay 807503fde5 update: fix bug de merde 2026-05-10 00:27:48 +01:00
Tom Boullay 75b77a52bf update: validation/errors srt 2026-05-10 00:25:45 +01:00
Tom Boullay 916b5d304f update: save srt files 2026-05-10 00:23:37 +01:00
Tom Boullay 3d81a9281a add: french subtitles 2026-05-10 00:20:16 +01:00
Tom Boullay 0c8b9070bb add: add str editing panel 2026-05-10 00:13:42 +01:00
Tom Boullay 0fbf6bfa0e add: trigger dialogue with timecode 2026-05-10 00:10:16 +01:00
Tom Boullay 53fdf3cb1e update: play audio + srt sync 2026-05-10 00:07:56 +01:00
Tom Boullay 8ef1da0e9a upatde: load dialogue en fonction du language 2026-05-10 00:04:59 +01:00
Tom Boullay 1c30b73253 add: load dialohue manifest 2026-05-10 00:02:48 +01:00
Tom Boullay f5bc7cb08e add: dialoguejson 2026-05-10 00:00:36 +01:00
Tom Boullay d9525b0aaf add: parser srt files 2026-05-09 23:53:19 +01:00
Tom Boullay 5b43f503ac add: basic subtitle 2026-05-09 23:51:22 +01:00
Tom Boullay 974f1e33fb add: settings menu + menu store 2026-05-09 23:45:05 +01:00
Tom Boullay ce67d07107 add: global cat volumes 2026-05-09 23:37:07 +01:00
Tom Boullay 53add29a48 add: type audio playback cat 2026-05-09 23:30:14 +01:00
Tom Boullay 33524f8409 add: reusable world video prompt billboard 2026-05-09 01:28:06 +01:00
Tom Boullay e0eae67ace fix repair game interaction coordinate spaces 2026-05-09 01:19:16 +01:00
Tom Boullay 254311bddf add: playground in testmap 2026-05-08 03:07:52 +01:00
Tom Boullay 6d9eac291e big clean up 2026-05-08 03:02:26 +01:00
Tom Boullay e4f6ec211c add: configure mission-specific repair variants 2026-05-08 02:41:57 +01:00
Tom Boullay ead3634aab add: animate repair reassembly 2026-05-08 02:40:31 +01:00
Tom Boullay 19a83982a9 add: require broken part deposit before repair 2026-05-08 02:36:14 +01:00
Tom Boullay bebb9ac5a3 add: snap repair parts to case placeholders 2026-05-08 02:33:06 +01:00
Tom Boullay d02ef54bdc add: focus repair case view 2026-05-08 02:22:15 +01:00
Tom Boullay 3f3f623832 fix: track Logger filename casing 2026-05-08 02:20:14 +01:00
Tom Boullay 0256dfa812 add: show broken part prompt during scan 2026-05-08 02:18:00 +01:00
Tom Boullay 5c688fdaf7 add: highlight broken repair parts during scan 2026-05-08 02:16:13 +01:00
Tom Boullay 7a3baa4c0b add: scan fragmented repair parts sequentially 2026-05-08 02:12:58 +01:00
Tom Boullay 95d9bd4f3e add: animation on repair case 2026-05-08 02:10:19 +01:00
Tom Boullay eee69825c6 clean: remove obsolete repair debug code + unused core utilities 2026-05-08 02:07:03 +01:00
Tom Boullay 15c3d1858f add: repair mission completion step 2026-05-08 01:48:40 +01:00
Tom Boullay 7ee842c535 update: validate correct repair replacement part 2026-05-08 01:47:07 +01:00
Tom Boullay d4f215a948 update: require replacement placement before repair completion 2026-05-08 01:45:00 +01:00
Tom Boullay 7bbcf4359e add: repair install completion step 2026-05-08 01:41:29 +01:00
Tom Boullay eed0077dd1 add: repair fragmentation and scan flow 2026-05-08 01:39:23 +01:00
Tom Boullay f5da2f4994 update: enable hand tracking for repair steps (not only when we are close to something) 2026-05-08 01:30:27 +01:00
Tom Boullay ed60114d06 add: repair game inspection sub state 2026-05-08 01:27:32 +01:00
Tom Boullay 861a369776 add: physics in game scene 2026-05-08 01:17:35 +01:00
Tom Boullay 96796bca65 add: repair mission config 2026-05-08 01:14:30 +01:00
Tom Boullay 8fa4b087ba update: add generic repair mission store helpers 2026-05-08 01:09:42 +01:00
Tom Boullay 9371c50110 Merge pull request #7 from La-Fabrik-Durable/feat/main-feature
Feat/main feature
2026-05-08 01:56:18 +02:00
Tom Boullay fb230911a7 Update HandTrackingGlove.tsx 2026-05-08 00:54:42 +01:00
Tom Boullay 457eebc0e3 add hand tracking source debug switch 2026-05-06 23:23:10 +01:00
Tom Boullay 03dfef4aad add browser hand tracking source 2026-05-06 23:23:04 +01:00
Tom Boullay 4bcdbef974 fix hand tracking glove root transform 2026-05-06 23:22:56 +01:00
Tom Boullay 553dc6eb0a fix: flickering hands 2026-05-06 23:16:58 +01:00
Tom Boullay 7ae45d4cfa fix; distance grab objetc 2026-05-02 21:34:23 +02:00
Tom Boullay 27928b00a6 add hand tracking glove bone mapping 2026-05-02 11:38:02 +02:00
Tom Boullay ac7f60060c fix hand tracking glove fallback and loading 2026-05-02 11:35:28 +02:00
Tom Boullay fe662ebe7d fix hand tracking glove rendering 2026-05-02 11:32:00 +02:00
Tom Boullay bdc06f772f update: remove old model elec 2026-05-02 11:02:51 +02:00
Tom Boullay f7a589a11f fix three and rapier warning dependencies 2026-05-02 11:01:50 +02:00
Tom Boullay c71cd35f4d fix electricienne debug model loading 2026-05-02 10:58:00 +02:00
Tom Boullay 0cb5f57182 feat add left hand tracking glove model 2026-05-02 00:14:56 +02:00
Tom Boullay 1d64582383 feat add model loading diagnostics 2026-05-02 00:14:47 +02:00
Tom Boullay 4d7d2efdcc cleaning repo models 2026-05-01 23:54:48 +02:00
Tom Boullay d438c02ad9 update: models made them working 2026-05-01 23:45:58 +02:00
Tom Boullay eef39ab53d update: debug overlay layout controls 2026-05-01 23:39:04 +02:00
Tom Boullay 1a783f1867 Update TestMap.tsx 2026-04-30 16:29:56 +02:00
Tom Boullay bb08054722 connect repair gameplay to zustand progression 2026-04-30 16:25:54 +02:00
Tom Boullay 1625895708 fix: models 2026-04-30 15:48:45 +02:00
Tom Boullay a87ffac63f Merge branch 'develop' into feat/main-feature 2026-04-30 15:48:35 +02:00
Tom Boullay 44a77a0197 Update arbre.bin 2026-04-30 15:09:27 +02:00
Tom Boullay f301a1e318 Merge branch 'design' into feat/main-feature 2026-04-30 15:09:22 +02:00
Tom Boullay 39fbf2333d Merge pull request #11 from La-Fabrik-Durable/feat/zustand
Feat/zustand
2026-04-30 15:07:44 +02:00
Tom Boullay 5f018e6de7 resolve three component type exports 2026-04-30 15:06:26 +02:00
Tom Boullay a14f776e5d address zustand progression review feedback 2026-04-30 14:59:41 +02:00
Tom Boullay 8884edb281 clarify managers and zustand store responsibilities 2026-04-30 14:38:07 +02:00
Tom Boullay b9970c4e03 add zustand game state 2026-04-30 14:29:29 +02:00
Tom Boullay 6a29cfdb0b add : some sounds 2026-04-30 14:25:36 +02:00
Tom Boullay 7c7dbdb588 connect game progression state to world 2026-04-30 14:24:59 +02:00
Tom Boullay 2696289483 add zustand game progression store 2026-04-30 14:04:01 +02:00
Tom Boullay b79f5c9314 chore: align repo health checks and docs 2026-04-30 13:51:39 +02:00
Tom Boullay 5265cdc7e5 add: prettier eslint 2026-04-30 13:36:07 +02:00
Tom Boullay cfb1eaf39a refactor: clean architecture and remove unused code 2026-04-30 13:33:28 +02:00
Tom Boullay b1187b68ae refactor: split hooks types and utils by domain 2026-04-30 11:49:18 +02:00
Tom Boullay 9ac5844182 refactor: organize three components by domain 2026-04-30 11:35:53 +02:00
Tom Boullay 37eded8d7e fix: correct repair case open state rotation 2026-04-30 10:42:47 +02:00
Tom Boullay 92097e5256 feat: add game music loop and mallette sounds 2026-04-30 10:06:00 +02:00
Tom Boullay 01c583ba96 refactor: prepare main feature gameplay object and use GLB sky model 2026-04-30 10:02:00 +02:00
Tom Boullay f66609178b feat: expand main feature model catalog 2026-04-29 23:30:40 +02:00
Tom Boullay 2783b13488 feat: add main feature module selection 2026-04-29 23:30:31 +02:00
Tom Boullay 8b3f24b90b feat: add openable repair case model 2026-04-29 23:30:22 +02:00
Tom Boullay 5173002283 chore: track bin assets with lfs 2026-04-29 17:07:44 +02:00
Tom Boullay fd5294fb54 Merge remote-tracking branch 'origin/feat/main-feature' into feat/main-feature
# Conflicts:
#	src/world/GameMap.tsx
2026-04-29 16:57:58 +02:00
Tom Boullay 95e7e9c0a5 feat: support glb model assets 2026-04-29 16:18:24 +02:00
Tom Boullay 94b8dd0385 Merge branch 'develop' into feat/main-feature 2026-04-29 15:01:17 +02:00
Tom Boullay ad6f1552c6 update: docs 2026-04-29 13:01:10 +02:00
math-pixel d3ba5f6cfb Merge branch 'design' of https://github.com/La-Fabrik-Durable/La-Fabrik into design 2026-04-29 12:16:51 +02:00
math-pixel 05ef9e012a add object 2026-04-29 12:00:11 +02:00
math-pixel aa8b31033f feat: add tree 2026-04-29 11:57:43 +02:00
Tom Boullay 719ddef3ba fix: position perf panel beside debug gui 2026-04-29 11:56:46 +02:00
math-pixel 462b80e1c2 Merge pull request #10 from La-Fabrik-Durable/feat-animation
Feat/animation
2026-04-29 11:50:07 +02:00
Tom Boullay 90bd216efe feat: improve hand grab targeting 2026-04-29 11:40:17 +02:00
math-pixel ba9833d407 fix: pr 2026-04-29 11:35:17 +02:00
math-pixel b736de5f25 Merge branch 'feat-animation' of https://github.com/La-Fabrik-Durable/La-Fabrik into feat-animation 2026-04-29 11:23:57 +02:00
math-pixel d482ae4634 fix: pr issues 2026-04-29 11:23:40 +02:00
Tom Boullay 7958b2c62a fix: decouple hand tracking from crosshair focus 2026-04-29 11:13:11 +02:00
math-pixel d3a3d5eeca Update src/hooks/useCharacterAnimation.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-29 11:07:40 +02:00
math-pixel dca8f5a0d3 update: animation doc 2026-04-29 11:00:32 +02:00
Tom Boullay 8e08c3d5e0 update: upload-gltf add a new model -> createurdepluie
📦 Model
   model.gltf

🎨 Textures (color)
   color_bac_eau.png (compressed)
   color_cable_1.png (compressed)
   color_cable_2.png (compressed)
   color_refroidisseur.png (compressed)
   color_resistance.png (compressed)
   color_shell.png (compressed)
   color_tuyau.png (compressed)

🧭 Textures (normal)
   normal_bac_eau.png (compressed)
   normal_cable_1.png (compressed)
   normal_cable_2.png (compressed)
   normal_refroidisseur.png (compressed)
   normal_resistance.png (compressed)
   normal_shell.png (compressed)
   normal_tuyau.png (compressed)

🧱 Textures (orm)
   orm_bac_eau.png (compressed)
   orm_cable_1.png (compressed)
   orm_cable_2.png (compressed)
   orm_refroidisseur.png (compressed)
   orm_resistance.png (compressed)
   orm_shell.png (compressed)
   orm_tuyau.png (compressed)

🧩 Assets
   createurdepluie2.bin
2026-04-29 11:00:08 +02:00
Tom Boullay 882f3cc71b feat: improve fist grab depth tracking 2026-04-29 10:52:35 +02:00
math-pixel 6c85485622 fix : comflic 2026-04-29 10:51:40 +02:00
Tom Boullay a14ff9d913 feat: grab objects with closed fist raycast 2026-04-29 10:40:48 +02:00
Tom Boullay cc4c11f934 refactor: replace pinch gesture with fist gesture 2026-04-29 10:34:11 +02:00
Tom Boullay 0a0519cead update: upload-gltf add a new model -> gant_r
📦 Model
   model.gltf

🎨 Textures (color)
   color_gant.png (compressed)

🧭 Textures (normal)
   normal_gant.png (compressed)

🧱 Textures (orm)
   orm_gant.png (compressed)

🧩 Assets
   gant_r.bin
2026-04-29 10:03:04 +02:00
Tom Boullay 7d09c29828 update: upload-gltf add a new model -> gant_r_pad
📦 Model
   model.gltf

🎨 Textures (color)
   color_galet.png (compressed)
   color_gant.png (compressed)

🧭 Textures (normal)
   normal_galet.png (compressed)
   normal_gant.png (compressed)

🧱 Textures (orm)
   orm_galet.png (compressed)
   orm_gant.png (compressed)

🧩 Assets
   gant_r_pad.bin
2026-04-29 10:02:21 +02:00
Tom Boullay 28e3ac4c06 fix: guard hand landmark visualization 2026-04-29 09:52:46 +02:00
Tom Boullay cc78420d9c Create model.gltf 2026-04-29 09:05:04 +02:00
Tom Boullay 2747a95847 Merge branch 'design' into feat/main-feature 2026-04-29 09:05:00 +02:00
Tom Boullay d116f26a42 update: upload-gltf add a new model -> talkie
📦 Model
   model.gltf

🎨 Textures (color)
   color_boutonb.png (compressed)
   color_e_cran.png (compressed)
   color_boutona.png (compressed)
   color_cadre.png (compressed)
   color_hautparleur.png (compressed)
   color_touches.png (compressed)
   color_cable2.png (compressed)
   color_talkie.png (compressed)
   color_antenne.png (compressed)
   color_prise.png (compressed)
   color_cable1.png (compressed)

🪶 Textures (roughness)
   roughness_talkie.png (compressed)
   roughness_antenne.png (compressed)
   roughness_touches.png (compressed)
   roughness_prise.png (compressed)
   roughness_hautparleur.png (compressed)
   roughness_cable2.png (compressed)
   roughness_cable1.png (compressed)
   roughness_cadre.png (compressed)
   roughness_boutonb.png (compressed)
   roughness_e_cran.png (compressed)
   roughness_boutona.png (compressed)

🧭 Textures (normal)
   cadre_normal_opengl.png (compressed)
   talkie_normal_opengl.png (compressed)
   hautparleur_normal_opengl.png (compressed)
   hautparleur_normal.png (compressed)
   prise_normal_opengl.png (compressed)
   boutonb_normal_opengl.png (compressed)
   touches_normal.png (compressed)
   antenne_normal.png (compressed)
   boutona_normal_opengl.png (compressed)
   cadre_normal.png (compressed)
   touches_normal_opengl.png (compressed)
   e_cran_normal.png (compressed)
   cable2_normal.png (compressed)
   boutona_normal.png (compressed)
   talkie_normal.png (compressed)
   cable1_normal.png (compressed)
   boutonb_normal.png (compressed)
   prise_normal.png (compressed)
   cable2_normal_opengl.png (compressed)
   antenne_normal_opengl.png (compressed)
   cable1_normal_opengl.png (compressed)
   e_cran_normal_opengl.png (compressed)

🔩 Textures (metalness)
   metalness_cable1.png (compressed)
   metalness_boutonb.png (compressed)
   metalness_touches.png (compressed)
   metalness_e_cran.png (compressed)
   metalness_boutona.png (compressed)
   metalness_talkie.png (compressed)
   metalness_antenne.png (compressed)
   metalness_hautparleur.png (compressed)
   metalness_cadre.png (compressed)
   metalness_cable2.png (compressed)
   metalness_prise.png (compressed)

⛰ Textures (height)
   height_hautparleur.png (compressed)
   height_touches.png (compressed)
   height_antenne.png (compressed)
   height_cadre.png (compressed)
   height_e_cran.png (compressed)
   height_cable2.png (compressed)
   height_boutona.png (compressed)
   height_talkie.png (compressed)
   height_cable1.png (compressed)
   height_boutonb.png (compressed)
   height_prise.png (compressed)

🌑 Textures (ao)
   ao_cable1.png (compressed)
   ao_e_cran.png (compressed)
   ao_boutonb.png (compressed)
   ao_touches.png (compressed)
   ao_antenne.png (compressed)
   ao_talkie.png (compressed)
   ao_boutona.png (compressed)
   ao_cable2.png (compressed)
   ao_prise.png (compressed)
   ao_hautparleur.png (compressed)
   ao_cadre.png (compressed)

🧩 Assets
   model.bin
2026-04-29 08:44:37 +02:00
Tom Boullay 9f746aa7b0 update: upload-gltf add a new model -> refroidisseur
📦 Model
   model.gltf

🎨 Textures (color)
   color_refroidisseur.png (compressed)

🪶 Textures (roughness)
   roughness_refroidisseur.png (compressed)

🧭 Textures (normal)
   refroidisseur_normal.png (compressed)
   refroidisseur_normal_opengl.png (compressed)

🔩 Textures (metalness)
   metalness_refroidisseur.png (compressed)

⛰ Textures (height)
   height_refroidisseur.png (compressed)

🌑 Textures (ao)
   ao_refroidisseur.png (compressed)

🧩 Assets
   model.bin
2026-04-29 08:42:35 +02:00
Tom Boullay 847d6834fd update: upload-gltf add a new model -> immeuble1
📦 Model
   model.gltf

🎨 Textures (color)
   color_buisson.png (compressed)
   color_fenetre.png (compressed)
   color_feuilles.png (compressed)
   color_maison.png (compressed)
   color_panneau.png (compressed)
   color_porte.png (compressed)
   color_tronc.png (compressed)

🧭 Textures (normal)
   normal_buisson.png (compressed)
   normal_fenetre.png (compressed)
   normal_feuilles.png (compressed)
   normal_maison.png (compressed)
   normal_panneau.png (compressed)
   normal_porte.png (compressed)
   normal_tronc.png (compressed)

🧱 Textures (orm)
   orm_buisson.png (compressed)
   orm_fenetre.png (compressed)
   orm_feuilles.png (compressed)
   orm_maison.png (compressed)
   orm_panneau.png (compressed)
   orm_porte.png (compressed)
   orm_tronc.png (compressed)

🧩 Assets
   immeuble1-2.bin
2026-04-28 20:18:56 +02:00
math-pixel bd641328b0 feat: animator 2026-04-28 20:14:37 +02:00
Tom Boullay dbbb67e55a update: upload-gltf add a new model -> maison1
📦 Model
   model.gltf

🎨 Textures (color)
   color_buisson.png (compressed)
   color_contours.png (compressed)
   color_fenetre.png (compressed)
   color_maison.png (compressed)
   color_panneau.png (compressed)
   color_porte.png (compressed)
   color_toit.png (compressed)

🧭 Textures (normal)
   normal_buisson.png (compressed)
   normal_contours.png (compressed)
   normal_fenetre.png (compressed)
   normal_maison.png (compressed)
   normal_panneau.png (compressed)
   normal_porte.png (compressed)
   normal_toit.png (compressed)

🧱 Textures (orm)
   orm_buisson.png (compressed)
   orm_contours.png (compressed)
   orm_fenetre.png (compressed)
   orm_maison.png (compressed)
   orm_panneau.png (compressed)
   orm_porte.png (compressed)
   orm_toit.png (compressed)

🧩 Assets
   maison.bin
2026-04-28 20:07:17 +02:00
Tom Boullay 10dac2e56b update: upload-gltf add a new model -> persoprincipal
📦 Model
   model.gltf

🎨 Textures (color)
   color_defaultmaterial.png (compressed)

🧭 Textures (normal)
   normal_defaultmaterial.png (compressed)

🧱 Textures (orm)
   orm_defaultmaterial.png (compressed)

🧩 Assets
   mc.bin
2026-04-28 20:02:25 +02:00
Tom Boullay aaad1b5884 update: upload-gltf add a new model -> fermier
📦 Model
   model.gltf

🎨 Textures (color)
   color_defaultmaterial.png (compressed)

🧭 Textures (normal)
   normal_defaultmaterial.png (compressed)

🧱 Textures (orm)
   orm_defaultmaterial.png (compressed)

🧩 Assets
   fermier.bin
2026-04-28 19:58:21 +02:00
Tom Boullay bf98f028fe update: upload-gltf add a new model -> gerant
📦 Model
   model.gltf

🎨 Textures (color)
   defaultmaterial_basecolor.png (compressed)
   defaultmaterial_base_color.png (compressed)

🪶 Textures (roughness)
   roughness_defaultmaterial.png (compressed)

🧭 Textures (normal)
   defaultmaterial_normal.png (compressed)
   defaultmaterial_normal_opengl.png (compressed)

🔩 Textures (metalness)
   metalness_defaultmaterial.png (compressed)

⛰ Textures (height)
   height_defaultmaterial.png (compressed)

🧱 Textures (orm)
   orm_defaultmaterial.png (compressed)

🧩 Assets
   gerant.bin
2026-04-28 19:56:34 +02:00
Tom Boullay bff24030ee update: upload-gltf add a new model -> sapin
📦 Model
   model.gltf

🎨 Textures (color)
   color_mat.1.png (compressed)
   color_mat.png (compressed)

🧭 Textures (normal)
   normal_mat.1.png (compressed)
   normal_mat.png (compressed)

🧱 Textures (orm)
   orm_mat.1.png (compressed)
   orm_mat.png (compressed)

🧩 Assets
   sapin.bin
2026-04-28 19:54:38 +02:00
Tom Boullay 6531d9b183 update: upload-gltf add a new model -> eolienne
📦 Model
   model.gltf

🎨 Textures (color)
   color_feuilles1st.png (compressed)
   color_he_lisse.png (compressed)
   color_pied.png (compressed)
   color_tiges1st.png (compressed)
   color_moteur.png (compressed)
   color_feuilles2nd.png (compressed)
   color_tiges2nd.png (compressed)
   color_cul.png (compressed)

🪶 Textures (roughness)
   roughness_tiges2nd.png (compressed)
   roughness_moteur.png (compressed)
   roughness_feuilles2nd.png (compressed)
   roughness_tiges1st.png (compressed)
   roughness_he_lisse.png (compressed)
   roughness_cul.png (compressed)
   roughness_pied.png (compressed)
   roughness_feuilles1st.png (compressed)

🧭 Textures (normal)
   pied_normal.png (compressed)
   feuilles2nd_normal.png (compressed)
   tiges1st_normal.png (compressed)
   tiges1st_normal_opengl.png (compressed)
   cul_normal.png (compressed)
   he_lisse_normal.png (compressed)
   tiges2nd_normal_opengl.png (compressed)
   pied_normal_opengl.png (compressed)
   cul_normal_opengl.png (compressed)
   feuilles2nd_normal_opengl.png (compressed)
   feuilles1st_normal_opengl.png (compressed)
   tiges2nd_normal.png (compressed)
   moteur_normal_opengl.png (compressed)
   feuilles1st_normal.png (compressed)
   moteur_normal.png (compressed)
   he_lisse_normal_opengl.png (compressed)

🔩 Textures (metalness)
   metalness_feuilles2nd.png (compressed)
   metalness_feuilles1st.png (compressed)
   metalness_cul.png (compressed)
   metalness_he_lisse.png (compressed)
   metalness_tiges1st.png (compressed)
   metalness_moteur.png (compressed)
   metalness_tiges2nd.png (compressed)
   metalness_pied.png (compressed)

⛰ Textures (height)
   height_pied.png (compressed)
   height_feuilles2nd.png (compressed)
   height_tiges1st.png (compressed)
   height_cul.png (compressed)
   height_he_lisse.png (compressed)
   height_tiges2nd.png (compressed)
   height_feuilles1st.png (compressed)
   height_moteur.png (compressed)

🪟 Textures (opacity)
   opacity_he_lisse.png (compressed)

🌑 Textures (ao)
   ao_feuilles2nd.png (compressed)
   ao_cul.png (compressed)
   ao_feuilles1st.png (compressed)
   ao_moteur.png (compressed)
   ao_tiges1st.png (compressed)
   ao_he_lisse.png (compressed)
   ao_pied.png (compressed)
   ao_tiges2nd.png (compressed)
2026-04-28 19:19:25 +02:00
Tom Boullay 38fa9c1ff2 update: upload-gltf add a new model -> packderelance
📦 Model
   model.gltf

🎨 Textures (color)
   color_tetemart.png (compressed)
   color_charnie_res.png (compressed)
   color_mousse.png (compressed)
   color_patinf.png (compressed)
   color_lock.png (compressed)
   color_cabledroit.png (compressed)
   color_cablegauche.png (compressed)
   color_puces.png (compressed)
   color_manchemart.png (compressed)
   color_mousse_bas.png (compressed)
   color_patsup.png (compressed)

🪶 Textures (roughness)
   roughness_mousse.png (compressed)
   roughness_charnie_res.png (compressed)
   roughness_cablegauche.png (compressed)
   roughness_patsup.png (compressed)
   roughness_mousse_bas.png (compressed)
   roughness_manchemart.png (compressed)
   roughness_cabledroit.png (compressed)
   roughness_patinf.png (compressed)
   roughness_lock.png (compressed)
   roughness_puces.png (compressed)
   roughness_tetemart.png (compressed)

🧭 Textures (normal)
   patsup_normal.png (compressed)
   mousse_normal_opengl.png (compressed)
   patinf_normal_opengl.png (compressed)
   cablegauche_normal.png (compressed)
   cablegauche_normal_opengl.png (compressed)
   lock_normal.png (compressed)
   patinf_normal.png (compressed)
   patsup_normal_opengl.png (compressed)
   mousse_bas_normal.png (compressed)
   mousse_normal.png (compressed)
   cabledroit_normal_opengl.png (compressed)
   cabledroit_normal.png (compressed)
   manchemart_normal.png (compressed)
   tetemart_normal_opengl.png (compressed)
   tetemart_normal.png (compressed)
   manchemart_normal_opengl.png (compressed)
   puces_normal.png (compressed)
   charnie_res_normal.png (compressed)
   lock_normal_opengl.png (compressed)
   mousse_bas_normal_opengl.png (compressed)
   puces_normal_opengl.png (compressed)
   charnie_res_normal_opengl.png (compressed)

🔩 Textures (metalness)
   metalness_mousse.png (compressed)
   metalness_puces.png (compressed)
   metalness_tetemart.png (compressed)
   metalness_charnie_res.png (compressed)
   metalness_mousse_bas.png (compressed)
   metalness_cabledroit.png (compressed)
   metalness_manchemart.png (compressed)
   metalness_lock.png (compressed)
   metalness_patinf.png (compressed)
   metalness_patsup.png (compressed)
   metalness_cablegauche.png (compressed)

⛰ Textures (height)
   height_patsup.png (compressed)
   height_cablegauche.png (compressed)
   height_lock.png (compressed)
   height_patinf.png (compressed)
   height_mousse_bas.png (compressed)
   height_mousse.png (compressed)
   height_cabledroit.png (compressed)
   height_manchemart.png (compressed)
   height_tetemart.png (compressed)
   height_puces.png (compressed)
   height_charnie_res.png (compressed)

🌑 Textures (ao)
   ao_puces.png (compressed)
   ao_mousse.png (compressed)
   ao_charnie_res.png (compressed)
   ao_mousse_bas.png (compressed)
   ao_cabledroit.png (compressed)
   ao_tetemart.png (compressed)
   ao_manchemart.png (compressed)
   ao_lock.png (compressed)
   ao_patinf.png (compressed)
   ao_patsup.png (compressed)
   ao_cablegauche.png (compressed)
2026-04-28 19:14:52 +02:00
math-pixel e8f621d35f wip 2026-04-28 16:54:00 +02:00
Tom Boullay aa211d16b7 fix: persist debug modes and skip missing map models 2026-04-28 16:35:33 +02:00
Tom Boullay 44c27be640 Merge branch 'develop' into feat/main-feature 2026-04-28 16:27:05 +02:00
Tom Boullay 8a58f75864 update: upload-gltf add a new model -> gants
📦 Model
   model.gltf

🎨 Textures (color)
   color_galet.png (compressed)
   color_gant.png (compressed)

🧭 Textures (normal)
   normal_galet.png (compressed)
   normal_gant.png (compressed)

🧱 Textures (orm)
   orm_galet.png (compressed)
   orm_gant.png (compressed)

🧩 Assets
   gants.bin
2026-04-28 16:07:26 +02:00
Tom Boullay 0c7d5b61ac update: upload-gltf add a new model -> galet
📦 Model
   model.gltf

🎨 Textures (color)
   color_galet.png (compressed)

🧭 Textures (normal)
   normal_galet.png (compressed)

🧱 Textures (orm)
   orm_galet.png (compressed)

🧩 Assets
   galet.bin
2026-04-28 16:02:46 +02:00
Tom Boullay 5c5ba0937e Merge pull request #6 from La-Fabrik-Durable/feat/docs-routing
Feat/docs-routing
2026-04-28 15:04:29 +02:00
Tom Boullay dc7de253de address docs routing review feedback 2026-04-28 15:02:50 +02:00
Tom Boullay 97e0606439 clean docs router declarations 2026-04-28 14:53:28 +02:00
Tom Boullay a11db585de move debug components out of utils 2026-04-28 14:47:26 +02:00
Tom Boullay 6d858cfa7d standardize source naming conventions 2026-04-28 14:46:27 +02:00
Tom Boullay 19bad2c8be fix runtime map loading lifecycle 2026-04-28 14:42:49 +02:00
Tom Boullay e01d6f27ba rename pages 2026-04-28 14:25:29 +02:00
Tom Boullay 64b53a762d clean branch-scoped code quality issues 2026-04-28 14:23:37 +02:00
Tom Boullay 9818e719ce organize data configs by domain 2026-04-28 14:17:21 +02:00
Tom Boullay 2251a81ac1 refactor feature folders by code type 2026-04-28 14:14:15 +02:00
Tom Boullay eebeee9ed8 refactor docs into feature folder 2026-04-28 13:54:41 +02:00
Tom Boullay 9c7c59973e group docs navigation by audience 2026-04-28 13:48:03 +02:00
Tom Boullay dee232ac45 add editor documentation pages 2026-04-28 13:47:56 +02:00
Tom Boullay 2117146de5 fix react three peer dependencies 2026-04-28 13:47:49 +02:00
Tom Boullay 632d4b5c95 update: app and main 2026-04-28 13:32:54 +02:00
Tom Boullay 291e747f7b Merge branch 'develop' into feat/docs-routing 2026-04-28 13:31:40 +02:00
Tom Boullay 48b53746d1 Merge pull request #4 from La-Fabrik-Durable/feat-editor
Feat/editor
2026-04-28 13:22:44 +02:00
Tom Boullay ddde5e33f3 fix editor map reliability 2026-04-28 11:06:09 +02:00
Tom Boullay b5f2b7c990 Update Map.tsx 2026-04-28 10:53:57 +02:00
Tom Boullay bce1a05615 Create Map.tsx 2026-04-28 10:52:05 +02:00
Tom Boullay 81515e3e31 Update debugConfig.ts 2026-04-28 10:48:42 +02:00
math-pixel ed9582562a Merge pull request #9 from La-Fabrik-Durable/feat/deploy-test
Feat/deploy test
2026-04-28 10:45:25 +02:00
math-pixel 2c295fa7ee Merge pull request #8 from La-Fabrik-Durable/feat/deploy-test
Feat/deploy test
2026-04-28 10:44:12 +02:00
Tom Boullay 4a2f9cfb50 Merge branch 'feat-editor' of https://github.com/La-Fabrik-Durable/La-Fabrik into feat-editor 2026-04-28 10:43:08 +02:00
Tom Boullay d70de8c9a4 cleaaning 2026-04-28 10:42:57 +02:00
math-pixel f83df3dd21 Delete test-editor.html 2026-04-28 10:39:58 +02:00
Tom Boullay 5e528a90f9 fix: style 2026-04-28 10:30:31 +02:00
Tom Boullay f3888ed0bf tyle: refresh editor controls with monochrome UI 2026-04-28 10:08:17 +02:00
Tom Boullay b8f6fe59db refactor: move game map into world folder 2026-04-28 09:47:09 +02:00
Tom Boullay d7425ac17d docs: document editor architecture and user features 2026-04-28 09:43:51 +02:00
Tom Boullay f8b2c180cd refactor: move editor page and types to conventional folders 2026-04-28 09:29:18 +02:00
Tom Boullay c6b317448f add: stylesheet 2026-04-28 09:07:56 +02:00
math-pixel bed5010f41 update: deploy file 2026-04-27 20:46:52 +02:00
math-pixel 1b1f2088aa update: deploy file 2026-04-27 20:40:05 +02:00
math-pixel 18d0c2baa5 feat: change version 2026-04-27 20:27:21 +02:00
math-pixel 4aaff26e82 fix :editor 2026-04-27 17:25:56 +02:00
Tom Boullay 31c3e43698 docs: clarify backend virtual environment setup 2026-04-27 17:11:08 +02:00
math-pixel c5b04764ec fix: main model map 2026-04-27 16:38:05 +02:00
Tom Boullay 1e444620c1 fix: address docs routing review 2026-04-27 16:32:23 +02:00
Tom Boullay eeca87dd0e clean: package json 2026-04-27 16:27:57 +02:00
math-pixel fde724f3f0 update models loading in /editor 2026-04-27 16:27:56 +02:00
Tom Boullay d5a295e18f feat: add localized docs pages 2026-04-27 16:27:08 +02:00
math-pixel 14626cd6b1 fix: load all models/ 2026-04-27 16:07:57 +02:00
Tom Boullay 9c602cdc63 feat move debug cube with remote hand tracking 2026-04-27 16:07:54 +02:00
Tom Boullay fa8bc229c3 feat add remote hand tracking backend 2026-04-27 15:49:02 +02:00
Tom Boullay 7139ae559e feat: add docs routing 2026-04-27 15:35:56 +02:00
Tom Boullay 1c9d113050 update: upload-gltf add a new model -> pylone
📦 Model
   model.gltf

🎨 Textures (color)
   pied_base_color.png (compressed)
   panneaux_base_color.png (compressed)
   cable2_base_color.png (compressed)
   chap_base_color.png (compressed)
   puces_base_color.png (compressed)
   lampe_base_color.png (compressed)
   cable1_base_color.png (compressed)

🪶 Textures (roughness)
   lampe_roughness.png (compressed)
   panneaux_roughness.png (compressed)
   cable2_roughness.png (compressed)
   cable1_roughness.png (compressed)
   chap_roughness.png (compressed)
   puces_roughness.png (compressed)
   pied_roughness.png (compressed)

🧭 Textures (normal)
   panneaux_normal.png (compressed)
   pied_normal.png (compressed)
   chap_normal.png (compressed)
   lampe_normal.png (compressed)
   chap_normal_opengl.png (compressed)
   panneaux_normal_opengl.png (compressed)
   lampe_normal_opengl.png (compressed)
   cable2_normal.png (compressed)
   cable1_normal.png (compressed)
   pied_normal_opengl.png (compressed)
   cable2_normal_opengl.png (compressed)
   puces_normal.png (compressed)
   cable1_normal_opengl.png (compressed)
   puces_normal_opengl.png (compressed)

🔩 Textures (metalness)
   lampe_metallic.png (compressed)
   cable1_metallic.png (compressed)
   puces_metallic.png (compressed)
   panneaux_metallic.png (compressed)
   chap_metallic.png (compressed)
   cable2_metallic.png (compressed)
   pied_metallic.png (compressed)

🧩 Assets
   cable1_mixed_ao.png (compressed)
   puces_mixed_ao.png (compressed)
   panneaux_height.png (compressed)
   chap_height.png (compressed)
   lampe_opacity.png (compressed)
   lampe_mixed_ao.png (compressed)
   pied_height.png (compressed)
   lampe_height.png (compressed)
   cable2_height.png (compressed)
   cable1_height.png (compressed)
   panneaux_mixed_ao.png (compressed)
   cable2_mixed_ao.png (compressed)
   puces_height.png (compressed)
   pied_mixed_ao.png (compressed)
   chap_mixed_ao.png (compressed)
2026-04-27 14:35:33 +02:00
math-pixel 70720fbdcf fix: address code review comments
- vite.config.ts: fix __dirname for ESM, add 1MB payload limit + JSON validation
- MapViewer.tsx: remove broken window.isTransforming checks, fix callback order
- EditorPage.tsx: derive undoCount from historyManager in handleTransformEnd
- package.json: support Node 20 or 22 in engines
2026-04-27 14:21:50 +02:00
math-pixel cd7ba7503c fix: lint 2026-04-27 14:19:26 +02:00
math-pixel 2bd0fe5b96 fix: format 2026-04-27 13:57:17 +02:00
math-pixel 037174a409 Merge branch 'develop' into feat-editor 2026-04-27 13:55:13 +02:00
math-pixel 7de5678db1 update: map & update: package json for CI 2026-04-27 13:44:14 +02:00
Tom Boullay b523e98bea Update model.gltf
🔍 Lint / 🪄 Check lint (push) Has been cancelled
🔍 Lint / 🎨 Check format (push) Has been cancelled
🔍 Lint / 🔎 Typecheck (push) Has been cancelled
🔍 Lint / 🏗 Build (push) Has been cancelled
📊 Quality / 🔒 Security Audit (push) Has been cancelled
📊 Quality / 📋 Dependency Freshness (push) Has been cancelled
📊 Quality / 📦 Bundle Size (push) Has been cancelled
2026-04-27 13:43:59 +02:00
Tom Boullay 99d3eb2a2a cleaning: repo + model 2026-04-27 13:36:35 +02:00
Tom Boullay 4a97e265c1 Merge pull request #3 from La-Fabrik-Durable/design
upload: models
2026-04-27 13:31:21 +02:00
Tom Boullay 71d7ccbb4b Merge pull request #2 from La-Fabrik-Durable/feat/implem-map-scene-physique
Feat/implem map scene physique
2026-04-27 11:58:38 +02:00
Tom Boullay cd6831166b fix: docs update debug project tree 2026-04-27 11:57:21 +02:00
Tom Boullay 1b32fe9227 Create .prettierignore 2026-04-27 11:23:29 +02:00
Tom Boullay 7a01d86761 fix: format & lint 2026-04-27 11:20:59 +02:00
Tom Boullay 208b43295c clean 2026-04-27 11:14:43 +02:00
Tom Boullay 0e9d711be5 fix: archi 2026-04-27 10:53:50 +02:00
Tom Boullay 3c7fdbc6f5 update: upload-gltf add a new model -> lafabrik
📦 Model
   model.glb (compressed)
🎨 Textures
   tiges_normal.png
   comptoir_normal_opengl.png
   porte_metallic.png
   tiges_height.png
   comptoir_mixed_ao.png
   tiges_metallic.png
   tiges_normal_opengl.png
   comptoir_roughness.png
   fenetre_0_base_color.png
   bat_roughness.png
   tiges_base_color.png
   comptoir_normal.png
   porte_normal.png
   toit_roughness.png
   comptoir_height.png
   porte_height.png
   porte_mixed_ao.png
   comptoir_metallic.png
   tiges_mixed_ao.png
   porte_normal_opengl.png
   dashboard_metallic.png
   anneaux_metallic.png
   anneaux_base_color.png
   panneau_normal_opengl.png
   toit_mixed_ao.png
   anneaux_roughness.png
   porte_stock_base_color.png
   tuyaux_mixed_ao.png
   fenetre_0_mixed_ao.png
   dashboard_base_color.png
   anneaux_mixed_ao.png
   dashboard_mixed_ao.png
   bat_base_color.png
   tuyaux_height.png
   tuyaux_metallic.png
   verre_fenetre_base_color.png
   bat_height.png
   anneaux_normal.png
   toit_metallic.png
   porte_stock_height.png
   bat_normal.png
   porte_stock_roughness.png
   tuyaux_normal.png
   fenetre_0_metallic.png
   porte_stock_normal.png
   tuyaux_roughness.png
   anneaux_height.png
   comptoir_base_color.png
   panneau_height.png
   panneau_base_color.png
   porte_stock_mixed_ao.png
   panneau_normal.png
   bat_mixed_ao.png
   anneaux_normal_opengl.png
   stock_0_mixed_ao.png
   tuyaux_base_color.png
   fenetre_0_normal_opengl.png
   porte_roughness.png
   porte_base_color.png
   toit_normal_opengl.png
   plan_de_travail_normal.png
   plan_de_travail_roughness.png
   plan_de_travail_height.png
   porte_stock_metallic.png
   toit_base_color.png
   stock_0_metallic.png
   stock_0_normal.png
   verre_fenetre_normal.png
   plan_de_travail_normal_opengl.png
   bat_metallic.png
   stock_0_base_color.png
   stock_0_height.png
   tiges_roughness.png
   fenetre_0_roughness.png
   verre_fenetre_height.png
   panneau_roughness.png
   fenetre_0_normal.png
   plan_de_travail_metallic.png
   dashboard_normal_opengl.png
   tuyaux_normal_opengl.png
   plan_de_travail_base_color.png
   fenetre_0_height.png
   porte_stock_normal_opengl.png
   panneau_mixed_ao.png
   dashboard_height.png
   verre_fenetre_normal_opengl.png
   toit_normal.png
   dashboard_normal.png
   bat_normal_opengl.png
   verre_fenetre_metallic.png
   toit_height.png
   plan_de_travail_mixed_ao.png
   stock_0_roughness.png
   panneau_metallic.png
   dashboard_roughness.png
   stock_0_normal_opengl.png
   verre_fenetre_roughness.png
   verre_fenetre_mixed_ao.png
2026-04-24 16:44:54 +02:00
Tom Boullay 0c43c58dfe update: upload-gltf add a new model -> lafabrik
📦 Model
   model.glb (compressed)
🎨 Textures
   tiges_normal.png
   comptoir_normal_opengl.png
   porte_metallic.png
   tiges_height.png
   comptoir_mixed_ao.png
   tiges_metallic.png
   tiges_normal_opengl.png
   comptoir_roughness.png
   fenetre_0_base_color.png
   bat_roughness.png
   tiges_base_color.png
   comptoir_normal.png
   porte_normal.png
   toit_roughness.png
   comptoir_height.png
   porte_height.png
   porte_mixed_ao.png
   comptoir_metallic.png
   tiges_mixed_ao.png
   porte_normal_opengl.png
   dashboard_metallic.png
   anneaux_metallic.png
   anneaux_base_color.png
   panneau_normal_opengl.png
   toit_mixed_ao.png
   anneaux_roughness.png
   porte_stock_base_color.png
   tuyaux_mixed_ao.png
   fenetre_0_mixed_ao.png
   dashboard_base_color.png
   anneaux_mixed_ao.png
   dashboard_mixed_ao.png
   bat_base_color.png
   tuyaux_height.png
   tuyaux_metallic.png
   verre_fenetre_base_color.png
   bat_height.png
   anneaux_normal.png
   toit_metallic.png
   porte_stock_height.png
   bat_normal.png
   porte_stock_roughness.png
   tuyaux_normal.png
   fenetre_0_metallic.png
   porte_stock_normal.png
   tuyaux_roughness.png
   anneaux_height.png
   comptoir_base_color.png
   panneau_height.png
   panneau_base_color.png
   porte_stock_mixed_ao.png
   panneau_normal.png
   bat_mixed_ao.png
   anneaux_normal_opengl.png
   stock_0_mixed_ao.png
   tuyaux_base_color.png
   fenetre_0_normal_opengl.png
   porte_roughness.png
   porte_base_color.png
   toit_normal_opengl.png
   plan_de_travail_normal.png
   plan_de_travail_roughness.png
   plan_de_travail_height.png
   porte_stock_metallic.png
   toit_base_color.png
   stock_0_metallic.png
   stock_0_normal.png
   verre_fenetre_normal.png
   plan_de_travail_normal_opengl.png
   bat_metallic.png
   stock_0_base_color.png
   stock_0_height.png
   tiges_roughness.png
   fenetre_0_roughness.png
   verre_fenetre_height.png
   panneau_roughness.png
   fenetre_0_normal.png
   plan_de_travail_metallic.png
   dashboard_normal_opengl.png
   tuyaux_normal_opengl.png
   plan_de_travail_base_color.png
   fenetre_0_height.png
   porte_stock_normal_opengl.png
   panneau_mixed_ao.png
   dashboard_height.png
   verre_fenetre_normal_opengl.png
   toit_normal.png
   dashboard_normal.png
   bat_normal_opengl.png
   verre_fenetre_metallic.png
   toit_height.png
   plan_de_travail_mixed_ao.png
   stock_0_roughness.png
   panneau_metallic.png
   dashboard_roughness.png
   stock_0_normal_opengl.png
   verre_fenetre_roughness.png
   verre_fenetre_mixed_ao.png
2026-04-24 16:44:44 +02:00
Tom Boullay 089763713a add: a logger utils 2026-04-24 14:02:16 +02:00
math-pixel 1ca13ca13e feat : save map.json on project 2026-04-23 15:40:10 +02:00
math-pixel ca9abf3f3b feat editor 2026-04-23 15:24:40 +02:00
Tom Boullay a8138a5180 Create package-lock.json 2026-04-19 16:51:10 +02:00
Tom Boullay 0f96b5597b refacto : cleaning the codebasebase again 2026-04-19 16:50:11 +02:00
Tom Boullay 1c48441535 refacto: cleanning the codebase 2026-04-17 16:03:29 +02:00
Tom Boullay 7e72f1e803 update : put every constante in the data folder 2026-04-17 15:42:10 +02:00
Tom Boullay 4b14295749 update : add map model + octree algo 2026-04-17 11:36:03 +02:00
Tom Boullay 5111f2e558 update: add a physic scenne 2026-04-17 10:48:18 +02:00
Tom Boullay 1d4f223c35 refacto: enleve la map 2026-04-16 16:11:20 +02:00
Tom Boullay a3feb96bc3 update: upload-gltf add a new model -> workshop/lafabrik
📦 Model
   model.gltf
🎨 Textures
   roughness (manquant)
   normal (manquant)
   metalness (manquant)
   color (manquant)
   displace (manquant)
2026-04-16 15:43:42 +02:00
Tom Boullay 3d490b7fdd update: upload-gltf add a new model -> general/blocking
📦 Model
   model.gltf
🎨 Textures
   roughness (manquant)
   normal (manquant)
   metalness (manquant)
   color (manquant)
   displace (manquant)
2026-04-16 11:04:48 +02:00
Tom Boullay 269cf81595 fix: archi player 2026-04-16 11:00:08 +02:00
Tom Boullay 71c22386be refactor: tighten project structure and strengthen tooling 2026-04-16 10:45:05 +02:00
Tom Boullay fd8b462e1c fix: lint 2026-04-15 16:42:06 +02:00
Tom Boullay 02283946fa feat: add player camera 2026-04-15 16:40:52 +02:00
Tom Boullay 9e9ac8066c feat: add the map 2026-04-15 16:09:02 +02:00
Tom Boullay aded4ee209 feat: add map blocking and cleanup 2026-04-15 13:36:53 +02:00
Tom Boullay e86d4f2077 Merge branch 'main' into design 2026-04-15 13:32:38 +02:00
Tom Boullay c1ca8ca8e0 cleaning 2026-04-15 13:32:21 +02:00
Tom Boullay 753bdafd2e fix ci 2026-04-15 13:30:04 +02:00
Tom Boullay 18fdd8b2a6 update: add more CI 2026-04-15 11:17:48 +02:00
Tom Boullay 2c771d548b update : docs and skills 2026-04-15 11:06:41 +02:00
Tom Boullay 9eff211958 update: upload-gltf add a new model -> map/blocking
📦 Model
   model.gltf
🎨 Textures
   roughness (manquant)
   normal (manquant)
   metalness (manquant)
   color (manquant)
   displace (manquant)
2026-04-15 09:48:07 +02:00
Tom Boullay 1ce0267d12 update: remove eveything 2026-04-15 09:41:46 +02:00
Tom Boullay f0471a3afe update: upload-gltf update -> general/vase
📦 Model
  ↔️ model.gltf (inchange)
🎨 Textures
   normal.jpg
2026-04-15 09:25:02 +02:00
Tom Boullay 9815a38656 update: upload-gltf update -> general/vase
📦 Model
  ↔️ model.gltf (inchange)
🎨 Textures
  🔄 roughness.jpg
  🔄 metalness.jpg
  🔄 color.jpg
  🔄 displace.jpg
   normal.jpg (supprime)
2026-04-15 09:18:02 +02:00
Tom Boullay 9d63bd6444 Merge branch 'design' of https://github.com/La-Fabrik-Durable/La-Fabrik into design 2026-04-15 09:02:24 +02:00
Tom Boullay 89af15683c update: upload-gltf update -> general/vase
📦 Model
  🔄 model.gltf (compressed)
🎨 Textures
   color.jpg
2026-04-14 16:41:58 +02:00
Tom Boullay 980b16895e update: upload-gltf update -> general/vase
📦 Model
  🔄 model.gltf (compressed)
🎨 Textures
   color.jpg (supprime)
2026-04-14 16:40:55 +02:00
Tom Boullay 0b4d59223f update: upload-gltf add a new model -> general/vase
📦 Model
   model.gltf (compressed)
🎨 Textures
   roughness.jpg
   normal.jpg
   metalness.jpg
   color.jpg
   displace.jpg
2026-04-14 16:23:19 +02:00
Tom Boullay 7d5abfc2af update: upload-gltf update -> general/coffeetest
🎨 Textures
   metalness.jpg
2026-04-14 13:56:37 +02:00
Tom Boullay 4a833c4484 update: upload-gltf replace model -> general/coffeetest
📦 Model
  🔄 model.gltf (compressed)
🎨 Textures
  🔄 roughness.jpg
  🔄 normal.jpg
   metalness (manquant)
  🔄 color.jpg
  🔄 displace.jpg
2026-04-14 13:43:44 +02:00
Tom Boullay c36d3631f2 update: upload-gltf add a new model -> general/coffeetest
📦 Model
   model.gltf (compressed)
🎨 Textures
   roughness.jpg
   normal.jpg
   metalness.jpg
   color.jpg
   displace.jpg
2026-04-14 13:30:53 +02:00
Tom Boullay 5d7ce27285 update: from upload-gltf add a new model -> general/coffeetest
📦 Model
   model.gltf

🎨 Textures
   roughness.jpg
   normal.jpg
   metalness.jpg
   color.jpg
   displace.jpg
2026-04-14 12:24:24 +02:00
Tom Boullay 32d4e07ceb add some folder 2026-04-14 12:22:20 +02:00
Tom Boullay af3262376d update: add agent.md + skills 2026-04-14 09:20:30 +02:00
Tom Boullay 2fcb0ca56f Create ci.yml 2026-04-14 09:02:12 +02:00
Tom Boullay e32be4be53 upatde: add prettier 2026-04-14 08:59:36 +02:00
Tom Boullay 71916b2329 update: add basic structure 2026-04-14 08:39:09 +02:00
Tom Boullay 429ae66703 add : finish readme, git lfs and gitignore 2026-04-13 23:30:33 +02:00
Tom Boullay af2cfe128c Update README.md 2026-04-13 23:17:59 +02:00
Tom Boullay a37e46ac49 Update README.md 2026-04-13 22:59:56 +02:00
Tom Boullay 843d61fd54 add: license + v1 archi 2026-04-13 22:24:20 +02:00
Tom Boullay e622646349 add readme 2026-04-13 16:37:37 +02:00
Tom Boullay 9dc89b438b Initial commit 2026-04-13 16:12:21 +02:00
25 changed files with 8 additions and 1296 deletions
-187
View File
@@ -1,187 +0,0 @@
# Game Flow - La Fabrik
## Étapes du jeu
```
intro → start-intro → naming → bienvenue → star-move → mission2 → searching_problem → preparation → outOfFabrik
```
---
## Détail des étapes
### 1. `intro` (initial)
- État initial au chargement du jeu
- Aucune action, juste une étape de départ
- Transition automatique vers `start-intro`
### 2. `start-intro`
- **Déclenchement** : Auto-transition depuis `intro` quand la scène est chargée
- **Action** : Joue l'audio d'intro (`intro`)
- **Attente** : Attend que l'audio se termine
- **Transition** : Vers `naming` quand l'audio se termine
### 3. `naming`
- **Déclenchement** : Quand l'audio d'intro se termine
- **Action** : Affiche un input pour demander le prénom du joueur
- **Attente** : L'utilisateur entre son prénom et valide
- **Transition** : Vers `bienvenue` quand l'utilisateur valide
### 4. `bienvenue`
- **Déclenchement** : Quand l'utilisateur valide son prénom
- **Actions** :
- Affiche "Bienvenue {prénom} !" à l'écran
- Joue l'audio de bienvenue
- **Attente** : Attend que l'audio se termine
- **Transition** : Vers `star-move` quand l'audio se termine
### 5. `star-move`
- **Déclenchement** : Quand l'audio de bienvenue se termine
- **Action** : Active le mouvement du joueur (`setCanMove(true)`)
- **État** : Le joueur peut maintenant se déplacer librement
- **Zone** : La détection de zone devient active (ZoneDetection)
### 6. `mission2`
- **Déclenchement** : Quand le joueur entre dans la zone `fabrikExit` (position: `[-5, 25, -15]`)
- **Actions** :
- Stocke `activityCity: false` dans le store Zustand
- Joue l'audio `alertCentral`
- **État** : Les objets avec hook `useActivityCity()` détectent le changement et jouent leurs animations
- **Attente** : Le joueur atteint la zone de trigger pour `searching_problem`
### 7. `searching_problem`
- **Déclenchement** : Quand le joueur entre dans la zone `searchingProblemZone` (position: `[-5, 25, -30]`)
- **Actions** :
- Joue l'audio `searchingProblem`
- Affiche l'objet "central" (position: `[1, 15, -45]`)
- **Attente** : Le joueur interagit avec l'objet "central"
### 8. `preparation`
- **Déclenchement** : Quand le joueur interagit avec l'objet "central"
- **Actions** :
- Bloque le mouvement (`setCanMove(false)`)
- Cache l'objet "central"
### 9. `outOfFabrik`
- **Déclenchement** : (non implémenté pour le moment)
- **Action** : Transition vers l'étape finale
---
## Fichiers clés
| Fichier | Rôle |
| --------------------------------------- | --------------------------------------------------------- |
| `src/stores/gameStore.ts` | Store Zustand pour l'état global du jeu |
| `src/stateManager/GameStepManager.ts` | Synchronise avec le store Zustand |
| `src/components/game/GameFlow.tsx` | Gère les transitions automatiques et la lecture audio |
| `src/components/ui/IntroUI.tsx` | Affiche l'input pour le prénom et le message de bienvenue |
| `src/components/zone/ZoneDetection.tsx` | Détecte quand le joueur entre dans une zone |
| `src/components/3d/CentralObject.tsx` | Objet interactif "central" pour la mission 2 |
| `src/data/audioConfig.ts` | Chemins des fichiers audio |
| `src/data/zones.ts` | Configuration des zones de transition |
| `src/hooks/useActivityCity.ts` | Hook pour détecter le changement d'activité de la ville |
---
## Configuration audio
```typescript
// src/data/audioConfig.ts
export const AUDIO_PATHS = {
intro: "/sounds/fa.mp3",
bienvenue: "/sounds/fa.mp3",
alertCentral: "/sounds/fa.mp3",
searchingProblem: "/sounds/fa.mp3",
};
```
---
## Configuration des zones
```typescript
// src/data/zones.ts
export const ZONES: Zone[] = [
{
id: "fabrikExit",
position: [-5, 25, -15],
radius: 10,
height: 20,
targetStep: "mission2",
},
{
id: "searchingProblemZone",
position: [-5, 25, -30],
radius: 10,
height: 20,
targetStep: "searching_problem",
},
];
```
---
## Store Zustand
```typescript
// src/stores/gameStore.ts
interface GameState {
step: GameStep;
activityCity: boolean;
playerName: string;
canMove: boolean;
setStep: (step: GameStep) => void;
setActivityCity: (value: boolean) => void;
setPlayerName: (name: string) => void;
setCanMove: (canMove: boolean) => void;
}
```
---
## Hooks personnalisés
### useActivityCity
Permet aux objets 3D de réagir au changement d'activité de la ville :
```typescript
import { useActivityCity } from "@/hooks/useActivityCity";
function MyAnimatedObject() {
const activityCity = useActivityCity(); // true par défaut, false en mission2
// L'animation se déclenche quand activityCity change à false
// Utiliser useEffect pour réagir au changement
}
```
---
## Debug
En mode debug (`?debug` dans l'URL), on peut voir :
- **Game Step** : L'étape actuelle dans le panneau lil-gui
- **Player Position** : Position X, Y, Z du joueur en temps réel
- **Zone Visualization** : Anneaux visuels au sol pour les zones + cylindres transparents
---
## Notes techniques
- Le mouvement du joueur est bloqué tant que `canMove` est `false`
- Le store Zustand (`useGameStore`) est la source principale de vérité
- `GameStepManager` synchronise automatiquement avec le store Zustand lors des transitions
- Les transitions via les zones utilisent `GameStepManager.transitionTo()` qui met à jour le store
- L'audio utilise un callback `onEnded` pour déclencher les transitions automatiques
-187
View File
@@ -1,187 +0,0 @@
# Game Flow - La Fabrik
## Étapes du jeu
```
intro → start-intro → naming → bienvenue → star-move → mission2 → searching_problem → preparation → outOfFabrik
```
---
## Détail des étapes
### 1. `intro` (initial)
- État initial au chargement du jeu
- Aucune action, juste une étape de départ
- Transition automatique vers `start-intro`
### 2. `start-intro`
- **Déclenchement** : Auto-transition depuis `intro` quand la scène est chargée
- **Action** : Joue l'audio d'intro (`intro`)
- **Attente** : Attend que l'audio se termine
- **Transition** : Vers `naming` quand l'audio se termine
### 3. `naming`
- **Déclenchement** : Quand l'audio d'intro se termine
- **Action** : Affiche un input pour demander le prénom du joueur
- **Attente** : L'utilisateur entre son prénom et valide
- **Transition** : Vers `bienvenue` quand l'utilisateur valide
### 4. `bienvenue`
- **Déclenchement** : Quand l'utilisateur valide son prénom
- **Actions** :
- Affiche "Bienvenue {prénom} !" à l'écran
- Joue l'audio de bienvenue
- **Attente** : Attend que l'audio se termine
- **Transition** : Vers `star-move` quand l'audio se termine
### 5. `star-move`
- **Déclenchement** : Quand l'audio de bienvenue se termine
- **Action** : Active le mouvement du joueur (`setCanMove(true)`)
- **État** : Le joueur peut maintenant se déplacer librement
- **Zone** : La détection de zone devient active (ZoneDetection)
### 6. `mission2`
- **Déclenchement** : Quand le joueur entre dans la zone `fabrikExit` (position: `[-5, 25, -15]`)
- **Actions** :
- Stocke `activityCity: false` dans le store Zustand
- Joue l'audio `alertCentral`
- **État** : Les objets avec hook `useActivityCity()` détectent le changement et jouent leurs animations
- **Attente** : Le joueur atteint la zone de trigger pour `searching_problem`
### 7. `searching_problem`
- **Déclenchement** : Quand le joueur entre dans la zone `searchingProblemZone` (position: `[-5, 25, -30]`)
- **Actions** :
- Joue l'audio `searchingProblem`
- Affiche l'objet "central" (position: `[1, 15, -45]`)
- **Attente** : Le joueur interagit avec l'objet "central"
### 8. `preparation`
- **Déclenchement** : Quand le joueur interagit avec l'objet "central"
- **Actions** :
- Bloque le mouvement (`setCanMove(false)`)
- Cache l'objet "central"
### 9. `outOfFabrik`
- **Déclenchement** : (non implémenté pour le moment)
- **Action** : Transition vers l'étape finale
---
## Fichiers clés
| Fichier | Rôle |
| --------------------------------------- | --------------------------------------------------------- |
| `src/stores/gameStore.ts` | Store Zustand pour l'état global du jeu |
| `src/stateManager/GameStepManager.ts` | Synchronise avec le store Zustand |
| `src/components/game/GameFlow.tsx` | Gère les transitions automatiques et la lecture audio |
| `src/components/ui/IntroUI.tsx` | Affiche l'input pour le prénom et le message de bienvenue |
| `src/components/zone/ZoneDetection.tsx` | Détecte quand le joueur entre dans une zone |
| `src/components/3d/CentralObject.tsx` | Objet interactif "central" pour la mission 2 |
| `src/data/audioConfig.ts` | Chemins des fichiers audio |
| `src/data/zones.ts` | Configuration des zones de transition |
| `src/hooks/useActivityCity.ts` | Hook pour détecter le changement d'activité de la ville |
---
## Configuration audio
```typescript
// src/data/audioConfig.ts
export const AUDIO_PATHS = {
intro: "/sounds/fa.mp3",
bienvenue: "/sounds/fa.mp3",
alertCentral: "/sounds/fa.mp3",
searchingProblem: "/sounds/fa.mp3",
};
```
---
## Configuration des zones
```typescript
// src/data/zones.ts
export const ZONES: Zone[] = [
{
id: "fabrikExit",
position: [-5, 25, -15],
radius: 10,
height: 20,
targetStep: "mission2",
},
{
id: "searchingProblemZone",
position: [-5, 25, -30],
radius: 10,
height: 20,
targetStep: "searching_problem",
},
];
```
---
## Store Zustand
```typescript
// src/stores/gameStore.ts
interface GameState {
step: GameStep;
activityCity: boolean;
playerName: string;
canMove: boolean;
setStep: (step: GameStep) => void;
setActivityCity: (value: boolean) => void;
setPlayerName: (name: string) => void;
setCanMove: (canMove: boolean) => void;
}
```
---
## Hooks personnalisés
### useActivityCity
Permet aux objets 3D de réagir au changement d'activité de la ville :
```typescript
import { useActivityCity } from "@/hooks/useActivityCity";
function MyAnimatedObject() {
const activityCity = useActivityCity(); // true par défaut, false en mission2
// L'animation se déclenche quand activityCity change à false
// Utiliser useEffect pour réagir au changement
}
```
---
## Debug
En mode debug (`?debug` dans l'URL), on peut voir :
- **Game Step** : L'étape actuelle dans le panneau lil-gui
- **Player Position** : Position X, Y, Z du joueur en temps réel
- **Zone Visualization** : Anneaux visuels au sol pour les zones + cylindres transparents
---
## Notes techniques
- Le mouvement du joueur est bloqué tant que `canMove` est `false`
- Le store Zustand (`useGameStore`) est la source principale de vérité
- `GameStepManager` synchronise automatiquement avec le store Zustand lors des transitions
- Les transitions via les zones utilisent `GameStepManager.transitionTo()` qui met à jour le store
- L'audio utilise un callback `onEnded` pour déclencher les transitions automatiques
-79
View File
@@ -1,79 +0,0 @@
# Mission Flow
This document describes the mission intro and mission 2 prototype flow after it was merged into the current architecture.
## Source Of Truth
Mission flow state lives in the global game store:
```txt
src/managers/stores/useGameStore.ts
```
The store owns the `missionFlow` slice:
```ts
missionFlow: {
step: GameStep;
activityCity: boolean;
playerName: string;
canMove: boolean;
dialogMessage: string | null;
}
```
This keeps global gameplay state in Zustand instead of splitting it across a separate mission store or a gameplay manager.
## Managers Boundary
Managers stay responsible for local runtime services:
- `AudioManager` owns audio elements, audio pools, music playback, category volume, and stereo pan.
- `InteractionManager` owns transient focused/nearby/held interaction handles.
Mission progression is not owned by a manager. Components update the store through explicit actions such as `setFlowStep`, `setCanMove`, `showDialog`, and `hideDialog`.
## Runtime Components
- `src/components/game/GameFlow.tsx` reacts to `missionFlow.step` and triggers one-off side effects such as intro audio and movement unlocks.
- `src/components/zone/ZoneDetection.tsx` reads the camera position and moves the flow to a target step when the player enters a configured zone.
- `src/components/three/interaction/CentralObject.tsx` and `VillageoisHelperObject.tsx` expose temporary interactive mission objects.
- `src/pages/page.tsx` mounts mission HTML overlays: `IntroUI`, `BienvenueDisplay`, and `DialogMessage`.
- `src/world/player/PlayerController.tsx` reads `missionFlow.canMove` as an additional movement lock.
## Step Sequence
The prototype currently uses these steps:
```ts
"intro" |
"start-intro" |
"naming" |
"bienvenue" |
"star-move" |
"mission2" |
"searching" |
"helped" |
"manipulation" |
"outOfFabrik";
```
These steps are mission-flow prototype states. They do not replace `mainState` or the repair mission step machine used by `RepairGame`.
## Zone Configuration
Zone triggers live in:
```txt
src/data/zones.ts
```
Each zone has an id, position, radius, height, and `targetStep`. `ZoneDetection` marks a zone as triggered after the first activation so the same zone does not replay its transition every frame.
## Rules
- Keep mission flow state in `useGameStore.missionFlow`.
- Do not reintroduce `GameStepManager` for global state transitions.
- Do not create a second Zustand store for mission flow unless the state becomes independent from game progression.
- Keep side effects such as audio playback in components or service managers, but keep the state transition itself in the store.
- Keep per-frame values such as camera position and zone distance checks out of Zustand.
+1 -7
View File
@@ -59,7 +59,6 @@ Rule of thumb:
The store exposes:
- `mainState`: the active game phase
- `missionFlow`: intro and mission 2 prototype state
- `intro`: intro-specific state
- `bike`: e-bike mission state
- `pylone`: power grid mission state
@@ -67,8 +66,6 @@ The store exposes:
- `outro`: ending state
- actions for direct updates and progression updates
The `missionFlow` slice contains the prototype step, player name, movement lock, city activity flag, and temporary dialog message. It is in the main game store because it is global gameplay state used by UI, world components, and the player controller.
The mission steps currently use this sequence:
```ts
@@ -144,8 +141,6 @@ For repair missions, it mounts the reusable `RepairGame` component with a missio
Mission-specific behavior stays in `src/data/gameplay/repairMissions.ts`: each mission can define its broken nodes, placeholder targets, scan duration, and reassembly duration without adding mission branches to `RepairGame`.
The intro and mission 2 prototype flow is documented separately in `docs/technical/mission-flow.md`. It intentionally uses the same `useGameStore` source of truth instead of a dedicated `GameStepManager` or a second Zustand store.
That means the scene can progressively move toward this pattern:
```tsx
@@ -176,9 +171,8 @@ Current overlays:
- `Crosshair`: player aiming helper
- `InteractPrompt`: interaction prompt
- `RepairMovementLockIndicator`: player-facing indicator shown while repair steps temporarily disable movement
- Mission flow overlays such as `IntroUI`, `BienvenueDisplay`, and `DialogMessage` are mounted by `src/pages/page.tsx` because they are route-level HTML overlays rather than persistent game HUD elements.
`src/pages/page.tsx` should stay thin and mount the canvas, persistent `GameUI`, and route-level overlays.
`src/pages/page.tsx` should stay thin and mount only the canvas and `GameUI`.
## Regression Rules
-80
View File
@@ -1,80 +0,0 @@
import { useEffect, useRef } from "react";
import { AudioManager } from "@/managers/AudioManager";
import { useGameStore } from "@/managers/stores/useGameStore";
import { AUDIO_PATHS } from "@/data/audioConfig";
export function GameFlow(): null {
const step = useGameStore((state) => state.missionFlow.step);
const setStep = useGameStore((state) => state.setFlowStep);
const setActivityCity = useGameStore((state) => state.setActivityCity);
const setCanMove = useGameStore((state) => state.setCanMove);
const hasInitialized = useRef(false);
useEffect(() => {
console.log("[GameFlow] Current step:", step);
if (!hasInitialized.current && step === "intro") {
hasInitialized.current = true;
console.log("[GameFlow] Transition to start-intro");
setStep("start-intro");
}
}, [step, setStep]);
useEffect(() => {
console.log("[GameFlow] useEffect triggered, step:", step);
if (step === "start-intro") {
console.log("[GameFlow] Playing intro audio");
const audio = AudioManager.getInstance();
audio.playSoundWithCallback(AUDIO_PATHS.intro, 0.5, () => {
console.log("[GameFlow] Intro audio ended, transition to naming");
setStep("naming");
});
return () => {};
}
if (step === "bienvenue") {
console.log("[GameFlow] Playing bienvenue audio");
const audio = AudioManager.getInstance();
audio.playSoundWithCallback(AUDIO_PATHS.bienvenue, 0.5, () => {
console.log("[GameFlow] Bienvenue audio ended, enable movement");
setCanMove(true);
setStep("star-move");
});
return () => {};
}
if (step === "mission2") {
console.log("[GameFlow] mission2 - setting activityCity to false");
setActivityCity(false);
const audio = AudioManager.getInstance();
audio.playSound(AUDIO_PATHS.alertCentral, 0.5);
}
if (step === "searching") {
console.log("[GameFlow] Playing searching audio");
const audio = AudioManager.getInstance();
audio.playSoundWithCallback(AUDIO_PATHS.searching, 0.5, () => {
console.log("[GameFlow] searching audio ended");
});
return () => {};
}
if (step === "helped") {
console.log("[GameFlow] Playing helped audio");
const audio = AudioManager.getInstance();
audio.playSound(AUDIO_PATHS.helped, 0.5);
}
if (step === "manipulation") {
console.log("[GameFlow] manipulation - blocking movement");
setCanMove(false);
}
return undefined;
}, [step, setStep, setActivityCity, setCanMove]);
return null;
}
@@ -1,60 +0,0 @@
import { InteractableObject } from "@/components/three/interaction/InteractableObject";
import { useGameStore } from "@/managers/stores/useGameStore";
import { Debug } from "@/utils/debug/Debug";
import type { Vector3Tuple } from "@/types/three/three";
interface CentralObjectProps {
position: Vector3Tuple;
}
export function CentralObject({
position,
}: CentralObjectProps): React.JSX.Element {
const step = useGameStore((state) => state.missionFlow.step);
const setStep = useGameStore((state) => state.setFlowStep);
const setCanMove = useGameStore((state) => state.setCanMove);
const showDialog = useGameStore((state) => state.showDialog);
const debug = Debug.getInstance();
const handlePress = (): void => {
console.log("[CentralObject] handlePress called, current step:", step);
if (step === "helped") {
console.log("[CentralObject] Transitioning to manipulation");
setCanMove(false);
setStep("manipulation");
} else if (step === "searching") {
console.log("[CentralObject] Showing help message");
showDialog(
"Cet objet est trop lourd pour le porter tout seul, trouve de l'aide",
);
} else {
console.log("[CentralObject] Step is not helped or searching, skipping");
}
};
const shouldShow =
step === "helped" || step === "manipulation" || debug.active;
if (!shouldShow) {
return <></>;
}
console.log("[CentralObject] Rendering, step:", step, "position:", position);
return (
<InteractableObject
kind="trigger"
label="central"
position={position}
onPress={handlePress}
>
<group position={position}>
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
</group>
</InteractableObject>
);
}
@@ -1,53 +0,0 @@
import { InteractableObject } from "@/components/three/interaction/InteractableObject";
import { useGameStore } from "@/managers/stores/useGameStore";
import { Debug } from "@/utils/debug/Debug";
import type { Vector3Tuple } from "@/types/three/three";
interface VillageoisHelperObjectProps {
position: Vector3Tuple;
}
export function VillageoisHelperObject({
position,
}: VillageoisHelperObjectProps): React.JSX.Element {
const step = useGameStore((state) => state.missionFlow.step);
const setStep = useGameStore((state) => state.setFlowStep);
const debug = Debug.getInstance();
const handlePress = (): void => {
console.log("[VillageoisHelper] handlePress called, current step:", step);
if (step === "searching") {
console.log("[VillageoisHelper] Transitioning to helped");
setStep("helped");
}
};
const shouldShow = step === "searching" || debug.active;
if (!shouldShow) {
return <></>;
}
console.log(
"[VillageoisHelper] Rendering, step:",
step,
"position:",
position,
);
return (
<InteractableObject
kind="trigger"
label="villageois_helper"
position={position}
onPress={handlePress}
>
<group position={position}>
<mesh>
<sphereGeometry args={[0.5, 16, 16]} />
<meshStandardMaterial color="cyan" />
</mesh>
</group>
</InteractableObject>
);
}
-54
View File
@@ -1,54 +0,0 @@
import { useEffect, useState } from "react";
interface DialogMessageProps {
message: string;
duration?: number;
onClose?: () => void;
}
export function DialogMessage({
message,
duration = 3000,
onClose,
}: DialogMessageProps): React.JSX.Element | null {
const [visible, setVisible] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setVisible(false);
onClose?.();
}, duration);
return () => clearTimeout(timer);
}, [duration, onClose]);
if (!visible) return null;
return (
<div
style={{
position: "fixed",
bottom: "20%",
left: "50%",
transform: "translateX(-50%)",
backgroundColor: "rgba(0, 0, 0, 0.9)",
padding: "1rem 2rem",
borderRadius: "8px",
border: "2px solid #fff",
zIndex: 200,
maxWidth: "80%",
}}
>
<p
style={{
color: "#fff",
margin: 0,
fontSize: "1rem",
textAlign: "center",
}}
>
{message}
</p>
</div>
);
}
-132
View File
@@ -1,132 +0,0 @@
import { useState } from "react";
import { useGameStore } from "@/managers/stores/useGameStore";
export function IntroUI(): React.JSX.Element | null {
const step = useGameStore((state) => state.missionFlow.step);
const setPlayerName = useGameStore((state) => state.setPlayerName);
const setStep = useGameStore((state) => state.setFlowStep);
const [inputValue, setInputValue] = useState("");
if (step !== "naming") return null;
const handleSubmit = (): void => {
if (inputValue.trim() === "") return;
console.log("[IntroUI] Submitting, name:", inputValue.trim());
setPlayerName(inputValue.trim());
console.log("[IntroUI] Calling transitionTo('bienvenue')");
setStep("bienvenue");
console.log("[IntroUI] After transitionTo, step should be:", step);
};
const handleKeyDown = (e: React.KeyboardEvent): void => {
if (e.key === "Enter") {
handleSubmit();
}
};
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(0, 0, 0, 0.7)",
zIndex: 1000,
}}
>
<div
style={{
backgroundColor: "#1a1a1a",
padding: "2rem",
borderRadius: "12px",
display: "flex",
flexDirection: "column",
gap: "1.5rem",
minWidth: "300px",
}}
>
<h2
style={{
color: "#fff",
margin: 0,
fontSize: "1.5rem",
textAlign: "center",
}}
>
Quel est votre prénom ?
</h2>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Votre prénom"
autoFocus
style={{
padding: "0.75rem",
fontSize: "1rem",
borderRadius: "6px",
border: "1px solid #444",
backgroundColor: "#2a2a2a",
color: "#fff",
outline: "none",
}}
/>
<button
onClick={handleSubmit}
disabled={inputValue.trim() === ""}
style={{
padding: "0.75rem",
fontSize: "1rem",
borderRadius: "6px",
border: "none",
backgroundColor: inputValue.trim() ? "#4a9" : "#444",
color: "#fff",
cursor: inputValue.trim() ? "pointer" : "not-allowed",
transition: "background-color 0.2s",
}}
>
Valider
</button>
</div>
</div>
);
}
export function BienvenueDisplay(): React.JSX.Element | null {
const step = useGameStore((state) => state.missionFlow.step);
const playerName = useGameStore((state) => state.missionFlow.playerName);
if (step !== "bienvenue") return null;
return (
<div
style={{
position: "fixed",
top: "20%",
left: "50%",
transform: "translateX(-50%)",
backgroundColor: "rgba(0, 0, 0, 0.8)",
padding: "1rem 2rem",
borderRadius: "8px",
zIndex: 100,
}}
>
<p
style={{
color: "#fff",
margin: 0,
fontSize: "1.25rem",
}}
>
Bienvenue {playerName} !
</p>
</div>
);
}
-163
View File
@@ -1,163 +0,0 @@
import { useEffect, useRef, useState } from "react";
import { useFrame, useThree } from "@react-three/fiber";
import * as THREE from "three";
import { ZONES } from "@/data/zones";
import { useGameStore } from "@/managers/stores/useGameStore";
import { Debug } from "@/utils/debug/Debug";
import type { GameStep } from "@/types/game";
const _playerPos = new THREE.Vector3();
const _zonePos = new THREE.Vector3();
const GAME_STEPS: GameStep[] = [
"intro",
"start-intro",
"naming",
"bienvenue",
"star-move",
"mission2",
"searching",
"helped",
"manipulation",
"outOfFabrik",
];
export function ZoneDetection(): null {
const camera = useThree((state) => state.camera);
const triggeredZones = useRef<Set<string>>(new Set());
const debug = Debug.getInstance();
const step = useGameStore((state) => state.missionFlow.step);
const setStep = useGameStore((state) => state.setFlowStep);
useEffect(() => {
if (!debug.active) return;
const folder = debug.createFolder("Game");
if (!folder) return;
const gameState = { step: step };
const playerPos = { x: 0, y: 0, z: 0 };
folder.add(gameState, "step", GAME_STEPS).name("Game Step").disable();
folder.add(playerPos, "x").name("Player X").listen().disable();
folder.add(playerPos, "y").name("Player Y").listen().disable();
folder.add(playerPos, "z").name("Player Z").listen().disable();
const unsubStore = useGameStore.subscribe((state) => {
gameState.step = state.missionFlow.step;
folder.controllersRecursive().forEach((c) => c.updateDisplay());
});
let frameId: number;
const updatePlayerPos = (): void => {
camera.getWorldPosition(_playerPos);
playerPos.x = Math.round(_playerPos.x * 100) / 100;
playerPos.y = Math.round(_playerPos.y * 100) / 100;
playerPos.z = Math.round(_playerPos.z * 100) / 100;
folder.controllersRecursive().forEach((c) => c.updateDisplay());
frameId = requestAnimationFrame(updatePlayerPos);
};
updatePlayerPos();
return () => {
cancelAnimationFrame(frameId);
debug.destroyFolder("Game");
unsubStore();
};
}, [debug, camera, step]);
useFrame(() => {
camera.getWorldPosition(_playerPos);
for (const zone of ZONES) {
if (triggeredZones.current.has(zone.id)) continue;
_zonePos.set(...zone.position);
const distanceSq = _playerPos.distanceToSquared(_zonePos);
if (distanceSq <= zone.radius * zone.radius) {
setStep(zone.targetStep);
triggeredZones.current.add(zone.id);
break;
}
}
});
return null;
}
interface ZoneVisualProps {
position: [number, number, number];
radius: number;
height: number;
triggered: boolean;
}
function ZoneVisual({
position,
radius,
height,
triggered,
}: ZoneVisualProps): React.JSX.Element {
const color = triggered ? "#00ff00" : "#ff0000";
return (
<group position={position}>
<mesh rotation={[-Math.PI / 2, 0, 0]}>
<ringGeometry args={[radius - 0.3, radius, 32]} />
<meshBasicMaterial color={color} side={THREE.DoubleSide} />
</mesh>
<mesh position={[0, height / 2, 0]}>
<cylinderGeometry args={[radius, radius, height, 32, 1, true]} />
<meshBasicMaterial
color={color}
transparent
opacity={0.15}
side={THREE.DoubleSide}
depthWrite={false}
/>
</mesh>
</group>
);
}
export function ZoneDebugVisuals(): React.JSX.Element | null {
const debug = Debug.getInstance();
const camera = useThree((state) => state.camera);
const [triggeredZones, setTriggeredZones] = useState<Set<string>>(new Set());
useFrame(() => {
camera.getWorldPosition(_playerPos);
for (const zone of ZONES) {
if (triggeredZones.has(zone.id)) continue;
_zonePos.set(...zone.position);
const distanceSq = _playerPos.distanceToSquared(_zonePos);
if (distanceSq <= zone.radius * zone.radius) {
setTriggeredZones((prev) => new Set(prev).add(zone.id));
break;
}
}
});
if (!debug.active) return null;
return (
<>
{ZONES.map((zone) => (
<ZoneVisual
key={zone.id}
position={[zone.position[0], 0.1, zone.position[2]]}
radius={zone.radius}
height={zone.height}
triggered={triggeredZones.has(zone.id)}
/>
))}
</>
);
}
-7
View File
@@ -1,7 +0,0 @@
export const AUDIO_PATHS = {
intro: "/sounds/fa.mp3",
bienvenue: "/sounds/fa.mp3",
alertCentral: "/sounds/fa.mp3",
searching: "/sounds/fa.mp3",
helped: "/sounds/fa.mp3",
} as const;
+4 -10
View File
@@ -50,12 +50,6 @@ export const docGroups: DocGroup[] = [
subtitle: "Progression store",
meta: "06",
},
{
path: "/docs/mission-flow",
title: "Mission Flow",
subtitle: "Intro and mission 2 prototype",
meta: "07",
},
],
},
{
@@ -65,25 +59,25 @@ export const docGroups: DocGroup[] = [
path: "/docs/features",
title: "Features",
subtitle: "Implemented scope",
meta: "08",
meta: "07",
},
{
path: "/docs/main-feature",
title: "Main Feature",
subtitle: "Repair-game prototype",
meta: "09",
meta: "08",
},
{
path: "/docs/editor",
title: "Editor User Guide",
subtitle: "Editing workflow",
meta: "10",
meta: "09",
},
{
path: "/docs/animation",
title: "Animation & 3D Model System",
subtitle: "Components and usage",
meta: "11",
meta: "010",
},
],
},
+1 -79
View File
@@ -328,7 +328,6 @@ Règle simple :
Le store expose :
- \`mainState\` : phase active du jeu
- \`missionFlow\` : état prototype de l'intro et de la mission 2
- \`intro\` : état spécifique à l'intro
- \`bike\` : état de la mission vélo
- \`pylone\` : état de la mission réseau électrique
@@ -336,8 +335,6 @@ Le store expose :
- \`outro\` : état de fin
- des actions de mise à jour directe et des actions de progression
Le slice \`missionFlow\` contient l'étape prototype, le prénom joueur, le lock de déplacement, le flag d'activité de la ville et le message de dialogue temporaire. Il vit dans le store principal parce qu'il s'agit d'un état gameplay global utilisé par l'UI, le world et le controller joueur.
Les étapes de mission utilisent actuellement cette séquence :
\`\`\`ts
@@ -404,8 +401,6 @@ Pour les missions de réparation, il monte le composant réutilisable \`RepairGa
\`RepairGame\` lit l'étape de mission active depuis le store et écrit les transitions via des actions génériques comme \`setMissionStep\` et \`completeMission\`. Les ids de mission, étapes de mission et guards partagés vivent dans \`src/types/gameplay/repairMission.ts\`, ce qui évite à la configuration statique des missions de dépendre du store Zustand. Le flow de réparation de production supporte actuellement les transitions \`waiting -> inspected -> fragmented -> scanning -> repairing -> reassembling -> done -> next mission\`.
Le flow prototype intro et mission 2 est documenté séparément dans \`docs/technical/mission-flow.md\`. Il utilise volontairement la même source de vérité \`useGameStore\`, sans \`GameStepManager\` dédié ni second store Zustand.
La scène peut donc évoluer progressivement vers ce pattern :
\`\`\`tsx
@@ -436,9 +431,8 @@ Overlays actuels :
- \`Crosshair\` : aide de visée joueur
- \`InteractPrompt\` : prompt d'interaction
- \`RepairMovementLockIndicator\` : indicateur joueur affiché quand les étapes repair désactivent temporairement le déplacement
- Les overlays du flow mission comme \`IntroUI\`, \`BienvenueDisplay\` et \`DialogMessage\` sont montés par \`src/pages/page.tsx\`, car ce sont des overlays HTML de route plutôt qu'un HUD de jeu persistant.
\`src/pages/page.tsx\` doit rester fin et monter le canvas, le \`GameUI\` persistant et les overlays de route.
\`src/pages/page.tsx\` doit rester fin et monter seulement le canvas et \`GameUI\`.
## Règles anti-régression
@@ -454,78 +448,6 @@ Overlays actuels :
Déplacer la validation de réparation dans les données de mission lorsque chaque mission aura ses propres nodes de modules cassés, assets de remplacement et événements de complétion.
`;
export const missionFlowFr = `# Flow de mission
Ce document décrit le flow prototype d'intro et de mission 2 après son intégration dans l'architecture actuelle.
## Source de vérité
L'état du flow de mission vit dans le store global du jeu :
\`\`\`txt
src/managers/stores/useGameStore.ts
\`\`\`
Le store possède le slice \`missionFlow\` :
\`\`\`ts
missionFlow: {
step: GameStep;
activityCity: boolean;
playerName: string;
canMove: boolean;
dialogMessage: string | null;
}
\`\`\`
Cela garde l'état gameplay global dans Zustand, au lieu de le répartir entre un store mission séparé ou un manager gameplay.
## Frontière des managers
Les managers restent responsables de services runtime locaux :
- \`AudioManager\` possède les éléments audio, les pools audio, la musique, le volume par catégorie et le pan stéréo.
- \`InteractionManager\` possède les handles d'interaction transitoires, focus, nearby et held.
La progression de mission n'est pas possédée par un manager. Les composants mettent à jour le store via des actions explicites comme \`setFlowStep\`, \`setCanMove\`, \`showDialog\` et \`hideDialog\`.
## Composants runtime
- \`src/components/game/GameFlow.tsx\` réagit à \`missionFlow.step\` et déclenche les effets ponctuels comme l'audio d'intro et le déblocage du mouvement.
- \`src/components/zone/ZoneDetection.tsx\` lit la position caméra et fait passer le flow à une étape cible quand le joueur entre dans une zone configurée.
- \`src/components/three/interaction/CentralObject.tsx\` et \`VillageoisHelperObject.tsx\` exposent les objets interactifs temporaires de mission.
- \`src/pages/page.tsx\` monte les overlays HTML de mission : \`IntroUI\`, \`BienvenueDisplay\` et \`DialogMessage\`.
- \`src/world/player/PlayerController.tsx\` lit \`missionFlow.canMove\` comme lock de déplacement supplémentaire.
## Séquence d'étapes
Le prototype utilise actuellement ces étapes :
\`\`\`ts
"intro" | "start-intro" | "naming" | "bienvenue" | "star-move" | "mission2" | "searching" | "helped" | "manipulation" | "outOfFabrik"
\`\`\`
Ces étapes sont propres au prototype de flow mission. Elles ne remplacent pas \`mainState\` ni la machine d'étapes repair utilisée par \`RepairGame\`.
## Configuration des zones
Les triggers de zones vivent dans :
\`\`\`txt
src/data/zones.ts
\`\`\`
Chaque zone possède un id, une position, un rayon, une hauteur et un \`targetStep\`. \`ZoneDetection\` marque une zone comme déclenchée après sa première activation pour éviter de rejouer la même transition à chaque frame.
## Règles
- Garder l'état du flow mission dans \`useGameStore.missionFlow\`.
- Ne pas réintroduire de \`GameStepManager\` pour les transitions globales.
- Ne pas créer un second store Zustand pour le flow mission sauf si cet état devient réellement indépendant de la progression du jeu.
- Garder les effets de bord comme l'audio dans les composants ou les managers de service, mais garder la transition d'état dans le store.
- Ne pas mettre les valeurs par-frame comme la position caméra ou les distances de zones dans Zustand.
`;
export const featuresFr = `# Fonctionnalités implémentées
Ce document liste les fonctionnalités présentes dans le code actuel.
-19
View File
@@ -1,19 +0,0 @@
import type { Zone } from "@/types/game";
import type { Vector3Tuple } from "@/types/three/three";
export const ZONES: Zone[] = [
{
id: "fabrikExit",
position: [-5, 25, -15] as Vector3Tuple,
radius: 10,
height: 20,
targetStep: "mission2",
},
{
id: "searchingZone",
position: [-5, 25, -30] as Vector3Tuple,
radius: 10,
height: 20,
targetStep: "searching",
},
];
-5
View File
@@ -1,5 +0,0 @@
import { useGameStore } from "@/managers/stores/useGameStore";
export function useActivityCity(): boolean {
return useGameStore((state) => state.missionFlow.activityCity);
}
-27
View File
@@ -1,27 +0,0 @@
import { useState } from "react";
interface DialogState {
message: string;
visible: boolean;
}
export function useDialog(): {
dialog: DialogState;
showDialog: (message: string) => void;
hideDialog: () => void;
} {
const [dialog, setDialog] = useState<DialogState>({
message: "",
visible: false,
});
const showDialog = (message: string): void => {
setDialog({ message, visible: true });
};
const hideDialog = (): void => {
setDialog((prev) => ({ ...prev, visible: false }));
};
return { dialog, showDialog, hideDialog };
}
-12
View File
@@ -114,18 +114,6 @@ export class AudioManager {
return audio;
}
playSoundWithCallback(
path: string,
volume: number,
onEnded: () => void,
options: PlaySoundOptions = {},
): HTMLAudioElement {
const audio = this.playSound(path, volume, options);
audio.addEventListener("ended", onEnded, { once: true });
return audio;
}
playMusic(path: string, volume = 1): void {
this._musicVolume = AudioManager._clampVolume(volume);
-45
View File
@@ -1,5 +1,4 @@
import { create } from "zustand";
import type { GameStep } from "@/types/game";
import {
isRepairMissionId,
type MissionStep,
@@ -20,18 +19,9 @@ interface MissionState {
dialogueAudio: string | null;
}
interface MissionFlowState {
activityCity: boolean;
canMove: boolean;
dialogMessage: string | null;
playerName: string;
step: GameStep;
}
interface GameState {
mainState: MainGameState;
isCinematicPlaying: boolean;
missionFlow: MissionFlowState;
intro: IntroState;
bike: MissionState & {
isRepaired: boolean;
@@ -51,12 +41,7 @@ interface GameState {
interface GameActions {
setMainState: (mainState: MainGameState) => void;
setCinematicPlaying: (isCinematicPlaying: boolean) => void;
hideDialog: () => void;
setActivityCity: (activityCity: boolean) => void;
setCanMove: (canMove: boolean) => void;
setFlowStep: (step: GameStep) => void;
setIntroState: (intro: Partial<IntroState>) => void;
setPlayerName: (playerName: string) => void;
setBikeState: (bike: Partial<GameState["bike"]>) => void;
setPyloneState: (pylone: Partial<GameState["pylone"]>) => void;
setFermeState: (ferme: Partial<GameState["ferme"]>) => void;
@@ -71,7 +56,6 @@ interface GameActions {
advanceGameState: () => void;
rewindGameState: () => void;
resetGame: () => void;
showDialog: (dialogMessage: string) => void;
}
type GameStore = GameState & GameActions;
@@ -241,13 +225,6 @@ function createInitialGameState(): GameState {
return {
mainState: "intro",
isCinematicPlaying: false,
missionFlow: {
activityCity: true,
canMove: false,
dialogMessage: null,
playerName: "",
step: "intro",
},
intro: {
dialogueAudio: null,
hasCompleted: false,
@@ -279,26 +256,8 @@ export const useGameStore = create<GameStore>()((set) => ({
...createInitialGameState(),
setMainState: (mainState) => set({ mainState }),
setCinematicPlaying: (isCinematicPlaying) => set({ isCinematicPlaying }),
hideDialog: () =>
set((state) => ({
missionFlow: { ...state.missionFlow, dialogMessage: null },
})),
setActivityCity: (activityCity) =>
set((state) => ({
missionFlow: { ...state.missionFlow, activityCity },
})),
setCanMove: (canMove) =>
set((state) => ({
missionFlow: { ...state.missionFlow, canMove },
})),
setFlowStep: (step) =>
set((state) => ({ missionFlow: { ...state.missionFlow, step } })),
setIntroState: (intro) =>
set((state) => ({ intro: { ...state.intro, ...intro } })),
setPlayerName: (playerName) =>
set((state) => ({
missionFlow: { ...state.missionFlow, playerName },
})),
setBikeState: (bike) =>
set((state) => ({ bike: { ...state.bike, ...bike } })),
setPyloneState: (pylone) =>
@@ -341,8 +300,4 @@ export const useGameStore = create<GameStore>()((set) => ({
return { outro: { ...state.outro, hasStarted: false } };
}),
resetGame: () => set(createInitialGameState()),
showDialog: (dialogMessage) =>
set((state) => ({
missionFlow: { ...state.missionFlow, dialogMessage },
})),
}));
-14
View File
@@ -1,14 +0,0 @@
import missionFlow from "../../../../docs/technical/mission-flow.md?raw";
import { DocsDocument } from "@/components/docs/DocsDocument";
import { missionFlowFr } from "@/data/docs/docsTranslations";
export function DocsMissionFlowPage(): React.JSX.Element {
return (
<DocsDocument
content={missionFlow}
frContent={missionFlowFr}
meta="07"
title="Mission Flow"
/>
);
}
+1 -30
View File
@@ -1,12 +1,9 @@
import { Suspense, useCallback, useEffect, useState } from "react";
import { Suspense, useCallback, useState } from "react";
import { Canvas } from "@react-three/fiber";
import * as THREE from "three";
import { DebugPerf } from "@/components/debug/DebugPerf";
import { DialogMessage } from "@/components/ui/DialogMessage";
import { GameUI } from "@/components/ui/GameUI";
import { BienvenueDisplay, IntroUI } from "@/components/ui/IntroUI";
import { SceneLoadingOverlay } from "@/components/ui/SceneLoadingOverlay";
import { useGameStore } from "@/managers/stores/useGameStore";
import { HandTrackingProvider } from "@/providers/gameplay/HandTrackingProvider";
import {
INITIAL_SCENE_LOADING_STATE,
@@ -15,26 +12,9 @@ import {
import { World } from "@/world/World";
export function HomePage(): React.JSX.Element {
const dialogMessage = useGameStore(
(state) => state.missionFlow.dialogMessage,
);
const hideDialog = useGameStore((state) => state.hideDialog);
const [sceneLoadingState, setSceneLoadingState] = useState<SceneLoadingState>(
INITIAL_SCENE_LOADING_STATE,
);
useEffect(() => {
if (!dialogMessage) return undefined;
const timeoutId = window.setTimeout(() => {
hideDialog();
}, 3000);
return () => {
window.clearTimeout(timeoutId);
};
}, [dialogMessage, hideDialog]);
const handleSceneLoadingStateChange = useCallback(
(nextState: SceneLoadingState) => {
setSceneLoadingState((currentState) => {
@@ -63,15 +43,6 @@ export function HomePage(): React.JSX.Element {
</Suspense>
</Canvas>
<GameUI />
<IntroUI />
<BienvenueDisplay />
{dialogMessage ? (
<DialogMessage
message={dialogMessage}
duration={3000}
onClose={hideDialog}
/>
) : null}
<SceneLoadingOverlay state={sceneLoadingState} />
</HandTrackingProvider>
);
-2
View File
@@ -14,7 +14,6 @@ import {
DocsHandTrackingRoute,
DocsLayoutRoute,
DocsMainFeatureRoute,
DocsMissionFlowRoute,
DocsReadmeRoute,
DocsTargetArchitectureRoute,
DocsTechnicalEditorRoute,
@@ -50,7 +49,6 @@ const docsChildRoutes = [
{ path: "technical-editor", component: DocsTechnicalEditorRoute },
{ path: "hand-tracking", component: DocsHandTrackingRoute },
{ path: "zustand", component: DocsZustandRoute },
{ path: "mission-flow", component: DocsMissionFlowRoute },
{ path: "features", component: DocsFeaturesRoute },
{ path: "main-feature", component: DocsMainFeatureRoute },
{ path: "editor", component: DocsEditorRoute },
-5
View File
@@ -55,10 +55,6 @@ const LazyDocsZustandPage = lazyNamed(
() => import("@/pages/docs/zustand/page"),
"DocsZustandPage",
);
const LazyDocsMissionFlowPage = lazyNamed(
() => import("@/pages/docs/mission-flow/page"),
"DocsMissionFlowPage",
);
const LazyDocsFeaturesPage = lazyNamed(
() => import("@/pages/docs/features/page"),
"DocsFeaturesPage",
@@ -87,7 +83,6 @@ export const DocsTechnicalEditorRoute = createDocsRoute(
);
export const DocsHandTrackingRoute = createDocsRoute(LazyDocsHandTrackingPage);
export const DocsZustandRoute = createDocsRoute(LazyDocsZustandPage);
export const DocsMissionFlowRoute = createDocsRoute(LazyDocsMissionFlowPage);
export const DocsFeaturesRoute = createDocsRoute(LazyDocsFeaturesPage);
export const DocsMainFeatureRoute = createDocsRoute(LazyDocsMainFeaturePage);
export const DocsEditorRoute = createDocsRoute(LazyDocsEditorPage);
-25
View File
@@ -1,25 +0,0 @@
import type { Vector3Tuple } from "@/types/three/three";
export type GameStep =
| "intro"
| "start-intro"
| "naming"
| "bienvenue"
| "star-move"
| "mission2"
| "searching"
| "helped"
| "manipulation"
| "outOfFabrik";
export interface Zone {
id: string;
position: Vector3Tuple;
radius: number;
height: number;
targetStep: GameStep;
}
export interface GameState {
step: GameStep;
}
-12
View File
@@ -8,16 +8,9 @@ import { useCameraMode } from "@/hooks/debug/useCameraMode";
import { useSceneMode } from "@/hooks/debug/useSceneMode";
import { useHandTrackingSnapshot } from "@/hooks/handTracking/useHandTrackingSnapshot";
import { useWorldSceneLoading } from "@/hooks/world/useWorldSceneLoading";
import { GameFlow } from "@/components/game/GameFlow";
import {
ZoneDebugVisuals,
ZoneDetection,
} from "@/components/zone/ZoneDetection";
import { DebugCameraControls } from "@/components/debug/scene/DebugCameraControls";
import { DebugHelpers } from "@/components/debug/scene/DebugHelpers";
import { HandTrackingGlove } from "@/components/three/handTracking/HandTrackingGlove";
import { CentralObject } from "@/components/three/interaction/CentralObject";
import { VillageoisHelperObject } from "@/components/three/interaction/VillageoisHelperObject";
import { Environment } from "@/world/Environment";
import { GameCinematics } from "@/world/GameCinematics";
import { GameDialogues } from "@/world/GameDialogues";
@@ -72,11 +65,6 @@ export function World({ onLoadingStateChange }: WorldProps): React.JSX.Element {
{cameraMode === "debug" ? <DebugCameraControls /> : null}
{sceneMode === "game" ? (
<>
<GameFlow />
<ZoneDetection />
<ZoneDebugVisuals />
<VillageoisHelperObject position={[1, 12, -55]} />
<CentralObject position={[1, 15, -45]} />
{noMusic ? null : <GameMusic />}
{noCinematics ? null : <GameCinematics />}
{noDialogues ? null : <GameDialogues />}
+1 -2
View File
@@ -94,7 +94,6 @@ export function PlayerController({
const velocity = useRef(new THREE.Vector3());
const onFloor = useRef(false);
const wantsJump = useRef(false);
const canMove = useGameStore((state) => state.missionFlow.canMove);
const capsule = useRef(
new Capsule(
@@ -201,7 +200,7 @@ export function PlayerController({
}, []);
useFrame((_, delta) => {
if (isPlayerInputLocked() || !canMove) {
if (isPlayerInputLocked()) {
keys.current = { ...DEFAULT_KEYS };
velocity.current.set(0, 0, 0);
wantsJump.current = false;