Dernière activité 1786915903

What features should we make to deliver a productivity tool for multipc multimonitor work. Copy and paste works, this is a time saving application. Let's save time for anyone who uses this app. List features and other tasks to complete this project and save it all in SUMMARY.md

ZZ's Avatar ZZ a révisé ce gist 1786915903. Aller à la révision

1 file changed, 45 insertions

z2-AiderDesk-Shell.md(fichier créé)

@@ -0,0 +1,45 @@
1 + ```
2 + ┌─────────────────────────────────────────────────────────────────────┐
3 + │ SHELL LAYER (one active per platform) │
4 + │ │
5 + │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
6 + │ │ TabBar │ │ Sidebar │ │ Appbar │ │ Menubar │ │ Tray │ │
7 + │ │ (current)│ │ (NavBar) │ │ (Dock) │ │ (macOS) │ │ Win/Linux│ │
8 + │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
9 + │ │ │ │ │ │ │
10 + │ └────────────┴────────────┴────────────┴────────────┘ │
11 + │ │ │
12 + │ ┌─────────▼──────────┐ │
13 + │ │ ShellEngine │ ← window mgmt, resize, │
14 + │ │ (extracted from │ drag, mode, DPI │
15 + │ │ MainEngine) │ │
16 + │ └─────────┬──────────┘ │
17 + │ │ │
18 + ├──────────────────────────────┼──────────────────────────────────────┤
19 + │ CORE LAYER │ │
20 + │ ┌─────────▼──────────┐ │
21 + │ │ AppEngine │ ← module registry, │
22 + │ │ (extracted from │ power routing, │
23 + │ │ MainEngine) │ session, network │
24 + │ └─────────┬──────────┘ │
25 + │ │ │
26 + │ ┌────────────────────┼────────────────────┐ │
27 + │ │ │ │ │
28 + │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │
29 + │ │AIEngine │ │AudioEng │ │ ... │ │
30 + │ │+AIUI │ │+AudioUI │ │$app pairs│ │
31 + │ └─────────┘ └─────────┘ └─────────┘ │
32 + │ │
33 + ├─────────────────────────────────────────────────────────────────────┤
34 + │ PLATFORM LAYER (conditional compilation) │
35 + │ │
36 + │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
37 + │ │ Web │ │ iOS │ │ Android │ │ Desktop │ │
38 + │ │ (WASM) │ │ (IPA) │ │ (APK) │ │(Win/Lnx)│ │
39 + │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
40 + │ No tray No tray No tray Full tray │
41 + │ No resize Native Native Custom resize │
42 + │ No drag window window Custom drag │
43 + │ File API File API File API Full FS │
44 + └─────────────────────────────────────────────────────────────────────┘
45 + ```

ZZ's Avatar ZZ a révisé ce gist 1786866330. Aller à la révision

Aucun changement

ZZ's Avatar ZZ a révisé ce gist 1786866300. Aller à la révision

Aucun changement

ZZ's Avatar ZZ a révisé ce gist 1786860290. Aller à la révision

1 file changed, 23 deletions

z1-Features.md

@@ -1,26 +1,3 @@
1 - Feature inventory (stable, in-progress, missing)
2 - 5-phase roadmap (stabilization → multi-PC power features → multi-monitor & AI → packaging → platform expansion)
3 - Non-functional requirements
4 - Success metrics
5 - Immediate next steps
6 - Verified content is consistent with README.md, SUMMARY.md, and AITASKS.md.
7 -
8 - 31687
9 - 94
10 - Task Ready for Review
11 -
12 -
13 - Agent
14 -
15 - Power Tools
16 -
17 - Manual
18 -
19 - Guided
20 -
21 - Auto
22 -
23 -
24 1 # EnvoyOS — Feature Roadmap
25 2
26 3 EnvoyOS is a multi-PC, multi-monitor productivity dashboard built in Godot 4.6. It combines clipboard sync, AI assistance, timers, inventory, web tab sessions, media controls, theme building, and a modular tab/engine architecture into a single desktop app.

ZZ's Avatar ZZ a révisé ce gist 1786860248. Aller à la révision

1 file changed, 221 insertions

z1-Features.md(fichier créé)

@@ -0,0 +1,221 @@
1 + Feature inventory (stable, in-progress, missing)
2 + 5-phase roadmap (stabilization → multi-PC power features → multi-monitor & AI → packaging → platform expansion)
3 + Non-functional requirements
4 + Success metrics
5 + Immediate next steps
6 + Verified content is consistent with README.md, SUMMARY.md, and AITASKS.md.
7 +
8 + 31687
9 + 94
10 + Task Ready for Review
11 +
12 +
13 + Agent
14 +
15 + Power Tools
16 +
17 + Manual
18 +
19 + Guided
20 +
21 + Auto
22 +
23 +
24 + # EnvoyOS — Feature Roadmap
25 +
26 + EnvoyOS is a multi-PC, multi-monitor productivity dashboard built in Godot 4.6. It combines clipboard sync, AI assistance, timers, inventory, web tab sessions, media controls, theme building, and a modular tab/engine architecture into a single desktop app.
27 +
28 + The roadmap below prioritizes:
29 +
30 + 1. Stabilizing the existing core product.
31 + 2. Completing the highest-value multi-PC productivity features.
32 + 3. Expanding AI and developer workflows.
33 + 4. Building a polished, cross-platform desktop suite.
34 +
35 + ---
36 +
37 + ## 1. Feature Inventory
38 +
39 + ### 1.1 Implemented / Stable
40 +
41 + | Feature | Module(s) | Notes |
42 + |---------|-----------|-------|
43 + | Cross-PC clipboard sync | `clipboard_engine.gd` | ENet + AES-256, client/server, auto-reconnect |
44 + | AI chat | `ai_engine.gd`, `ai_ui.gd` | Ollama HTTP streaming, multi-turn context |
45 + | Markdown editor | `editor_engine.gd`, `editor_ui.gd` | Autosave, debounce, theme-aware typography |
46 + | Timer panel | `time_engine.gd`, `time_ui.gd` | Up to 12 timers, background tick, config persistence |
47 + | Inventory tracking | `inventory_engine.gd`, `inventory_ui.gd` | Slot-based UI, expiration tracking |
48 + | Tab management | `tab_engine.gd`, `tab_ui.gd` | Custom tab bar, session persistence |
49 + | Theme builder | `ui_engine.gd`, `ui_ui.gd` | bg/font/accent/shade/transparency, light/dark adaptivity |
50 + | Video / display settings | `video_engine.gd`, `video_ui.gd` | FPS, DPI, window mode, position, size |
51 + | OS grid layout | `grid_engine.gd`, `grid_ui.gd` | Configurable rows × columns dashboard |
52 + | User AFK detection | `user_active_engine.gd` | Cross-platform idle time |
53 + | System tray | `systemtray.gd` | Minimize-to-tray, app-level tray integration |
54 + | Ship game | `ship_engine.gd`, `ship_ui.gd` | 2D physics mini-game, object pooling |
55 + | Web tab session viewer | `web_engine.gd`, `web_ui.gd` | Loads Tab Session Manager JSON, tree view |
56 + | VoIP scaffolding | `voip_engine.gd`, `voip_ui.gd` | UDP, VAD, jitter buffer; still in progress |
57 + | Audio settings | `audio_engine.gd`, `audio_ui.gd` | Master volume, mute, mic level |
58 +
59 + ### 1.2 Partial / In Progress
60 +
61 + | Feature | Module(s) | Missing |
62 + |---------|-----------|---------|
63 + | System monitor | `system_engine.gd`, `system_ui.gd` | Empty; needs CPU/RAM/disk/GPU stats and dashboard UI |
64 + | AI code assistant | `ai_code_engine.gd`, `ai_code_ui.gd` | Empty; needs code-gen, review, explain, diff view |
65 + | Music / media player | `music_engine.gd`, `music_ui.gd` | `extends Node` only; needs playback queue, seeking, shuffle |
66 + | VoIP | `voip_engine.gd`, `voip_ui.gd` | Needs input validation, UI polish, reliability tests |
67 + | OS grid layout | `grid_engine.gd`, `grid_ui.gd` | Broken references to clipboard engine state |
68 +
69 + ### 1.3 Stubs / Missing
70 +
71 + | Feature | Notes |
72 + |---------|-------|
73 + | Command palette | No `Ctrl+K` action search |
74 + | Global hotkeys | No OS-level hotkey registration |
75 + | Monitor layout memory | No per-monitor window position/size persistence |
76 + | Floating overlays | No always-on-top widgets |
77 + | P2P file transfer | No chunked ENet file streaming UI |
78 + | Shared workspace / Kanban | No cross-PC synced task board |
79 + | Notification mirroring | No cross-PC toasts |
80 + | Clipboard history ring buffer | No searchable past clipboard picker |
81 + | Snippet library | No saved snippets with sync |
82 + | Screen recording / capture | No per-monitor GPU capture |
83 + | Voice commands | No local voice-to-action pipeline |
84 + | In-app updater | No auto-update mechanism |
85 + | Unit tests / CI | No GUT test suite or automated checks |
86 +
87 + ---
88 +
89 + ## 2. Roadmap
90 +
91 + ### Phase 1 — Stabilize & Finish Core Gaps (Weeks 1–3)
92 +
93 + Goal: make every existing tab useful and remove obvious technical debt.
94 +
95 + | # | Feature / Task | Description |
96 + |---|----------------|-------------|
97 + | 1.1 | System monitor | Implement `system_engine.gd` (CPU %, RAM, disk, GPU, network) and `system_ui.gd` dashboard with live gauges. |
98 + | 1.2 | Music player | Build `music_engine.gd` playback queue, seeking, shuffle/repeat; wire `music_ui.gd`. |
99 + | 1.3 | AI code tab | Implement `ai_code_engine.gd` for explain/refactor/generate and `ai_code_ui.gd` with side-by-side editor + diff view. |
100 + | 1.4 | Fix grid engine refs | Replace `is_connected_to_network` / `is_reconnecting` with valid clipboard engine properties. |
101 + | 1.5 | Input validation | Validate VoIP port, timer/inventory `hh:mm:ss` fields, and all numeric inputs. |
102 + | 1.6 | Merge duplicate engines | Consolidate `tab_engine.gd` and `top_engine.gd` into one base class. |
103 + | 1.7 | Testing foundation | Add GUT unit tests for theme serializer, tab engine, timer, inventory, clipboard crypto. |
104 + | 1.8 | CI pipeline | GitHub Actions: `godot --headless --check-only` + GUT on push. |
105 + | 1.9 | Bug bash | Systematic pass over known technical debt list. |
106 +
107 + **Exit criteria:** No empty tabs, no broken references, CI green, basic test coverage.
108 +
109 + ### Phase 2 — Multi-PC Power Features (Weeks 4–7)
110 +
111 + Goal: make EnvoyOS the primary productivity bridge between the user’s PCs.
112 +
113 + | # | Feature | Description |
114 + |---|---------|-------------|
115 + | 2.1 | Clipboard history ring buffer | Last 100 text/image items with timestamp, source PC, app name. Searchable picker. |
116 + | 2.2 | Snippet library | Save frequently used snippets/templates, sync to all peers, one-click paste. |
117 + | 2.3 | Cross-PC clipboard search | Type keyword → RPC search across all peers’ history. |
118 + | 2.4 | P2P file transfer | Drag-and-drop file onto network tab → AES-256 → chunked ENet stream → progress bar. |
119 + | 2.5 | Shared workspace folder | Synced directory with chunked transfer; edit on one PC, open on another. |
120 + | 2.6 | Shared Kanban board | To-Do / In-Progress / Done, RPC-synced in real time; cards with title, tags, due date, assigned PC. |
121 + | 2.7 | Notification mirroring | Broadcast system/app notifications to all peers; timer expiry → alert all PCs. |
122 + | 2.8 | Command palette | `Ctrl+K` fuzzy-search actions: tabs, theme, timers, connections, mute, etc. |
123 + | 2.9 | Global OS-level hotkeys | Clipboard history, screenshot, quick paste, show/hide app. |
124 + | 2.10 | Offline queue | Queue clipboard/file/task changes while disconnected; auto-sync on reconnect. |
125 +
126 + **Exit criteria:** User can copy/paste, transfer files, and track tasks across PCs without leaving EnvoyOS.
127 +
128 + ### Phase 3 — Multi-Monitor & AI (Weeks 8–11)
129 +
130 + Goal: exploit multi-monitor setups and deepen AI assistance.
131 +
132 + | # | Feature | Description |
133 + |---|---------|-------------|
134 + | 3.1 | Monitor layout memory | Detect monitors, save per-monitor window positions/sizes, restore on launch. |
135 + | 3.2 | Floating overlays | Always-on-top widgets: timer countdown, clipboard dock, AFK glow, assigned to monitors. |
136 + | 3.3 | Window tiling / snapping | `Ctrl+1..4` quadrant, `Ctrl+Shift+Left/Right` half, named layouts. |
137 + | 3.4 | Per-monitor contrast | Different shade/brightness per monitor; auto time-of-day adjustment. |
138 + | 3.5 | AI code review | Explain selected code, refactor with diff, generate from prompt, review PR diff. |
139 + | 3.6 | AI meeting notes | Stream mic audio → local Whisper/Ollama → bullet summary → sync to peers. |
140 + | 3.7 | Cross-PC input mirroring | Type on PC-A → keystrokes stream to PC-B; relative mouse deltas; per-peer toggle. |
141 + | 3.8 | AI suggestion engine | Context-aware “Smart Suggestions” on clipboard/tab/editor. |
142 + | 3.9 | Screenshot + AI annotate | Capture region → send to local model → written description. |
143 +
144 + **Exit criteria:** Multi-monitor setup feels native; AI handles coding and documentation tasks with low friction.
145 +
146 + ### Phase 4 — Polish, Packaging & Release (Weeks 12–14)
147 +
148 + Goal: ship a polished, discoverable, cross-platform product.
149 +
150 + | # | Feature | Description |
151 + |---|---------|-------------|
152 + | 4.1 | Auto-start with OS | Windows registry, Linux `.desktop`, macOS `LaunchAgent`. |
153 + | 4.2 | System tray menu | Show, Mute, Disconnect, Open Timer, Open Kanban, Exit. |
154 + | 4.3 | Backup / restore | Export/import all `user://` settings as `.zip`. |
155 + | 4.4 | Accessibility pass | High-contrast mode, font scaling, screen-reader labels. |
156 + | 4.5 | Session replay | Record short UI interaction replay for bug reports. |
157 + | 4.6 | User documentation | Full user manual, keyboard shortcut reference, per-OS setup guide. |
158 + | 4.7 | Export / packaging | Release builds for Windows / Linux / macOS; in-app updater (optional). |
159 + | 4.8 | Localization scaffold | String externalization for future i18n. |
160 + | 4.9 | Error reporting | Opt-in crash/telemetry with minimal PII. |
161 +
162 + **Exit criteria:** Stable release builds, onboarding experience, accessible UI.
163 +
164 + ### Phase 5 — Differentiators & Platform Expansion (Ongoing)
165 +
166 + Goal: make EnvoyOS a complete second OS layer for power users.
167 +
168 + | # | Feature | Description |
169 + |---|---------|-------------|
170 + | 5.1 | Screen recording per monitor | GPU capture, “record this monitor” toggle, export to file. |
171 + | 5.2 | Voice commands | “Hey, paste the last email” → VAD → snippet match → paste. |
172 + | 5.3 | Pomodoro focus mode | 25/5 preset; auto-pauses AI streaming and sync during focus. |
173 + | 5.4 | Dark-light auto-switch | Theme tied to system clock or ambient light. |
174 + | 5.5 | Peer presence bar | Avatar strip showing online PCs via `multiplayer.get_peers()`. |
175 + | 5.6 | Shared timer countdown | Timer on PC-A visible live on PC-B; sync `end_timestamp`. |
176 + | 5.7 | Calendar view | Timers/inventory deadlines on mini monthly calendar. |
177 + | 5.8 | CSV export | Timer/inventory state to CSV. |
178 + | 5.9 | Low-stock alerts | Inventory item below threshold → red flag on all PCs. |
179 + | 5.10 | Browser extension | Sync tabs/bookmarks/clipboard from browser to EnvoyOS. |
180 + | 5.11 | Mobile companion | System-tray / applet / browser-extension views; remote status. |
181 + | 5.12 | Plugin / extension system | Load custom GDScript panels into the tab grid. |
182 + | 5.13 | App manifest / RBAC | JSON manifest for per-panel permissions, resource limits, data classification. |
183 + | 5.14 | Power management UI | Per-tab/applet status, bandwidth throttle, CPU/GPU allocation. |
184 +
185 + ---
186 +
187 + ## 3. Non-Functional Requirements
188 +
189 + | Area | Requirement |
190 + |------|-------------|
191 + | Performance | Inactive engines must not consume CPU; active tabs < 10 ms frame budget on mid-range hardware. |
192 + | Reliability | Network sync must survive peer disconnects and auto-reconnect without data loss. |
193 + | Security | All network payloads encrypted (AES-256); no secrets in logs; configurable trust model. |
194 + | Accessibility | WCAG-conscious contrast, full keyboard navigation, font scaling, screen-reader labels. |
195 + | Portability | Windows, Linux, macOS desktop; optional WebAssembly build for applet view. |
196 + | Testability | Unit tests for engines, integration tests for network sync, smoke tests for UI tabs. |
197 + | Observability | Structured logs, error reporting, session replay for debugging. |
198 + | Packaging | Signed release binaries per platform; in-app updater (optional). |
199 +
200 + ---
201 +
202 + ## 4. Success Metrics
203 +
204 + | Metric | Target |
205 + |--------|--------|
206 + | Core stability | Zero empty tabs; no broken references; CI green |
207 + | Cross-PC utility | User can copy, transfer, and track work across ≥ 2 PCs without external tools |
208 + | AI value | ≥ 3 AI-powered workflows (chat, code review, meeting notes) usable daily |
209 + | Multi-monitor | ≥ 3 per-monitor layout features working out of the box |
210 + | Release readiness | Signed builds for 3 platforms; documented onboarding; < 5 min setup time |
211 + | Extensibility | Third-party panels can be loaded via manifest / plugin API |
212 +
213 + ---
214 +
215 + ## 5. Immediate Next Steps
216 +
217 + 1. Complete Phase 1 items (system monitor, music player, AI code tab, grid refs, tests, CI).
218 + 2. Pick one Phase 2 multi-PC feature to prototype (clipboard history or P2P file transfer).
219 + 3. Define the JSON manifest schema for panels / RBAC (informs Phase 5 but can be designed now).
220 + 4. Establish a release cadence and changelog process.
221 +

ZZ's Avatar ZZ a révisé ce gist 1786857431. Aller à la révision

1 file changed, 0 insertions, 0 deletions

Godot-Convention.md renommé en z-Godot-Convention.md

Fichier renommé sans modifications

ZZ's Avatar ZZ a révisé ce gist 1786857415. Aller à la révision

1 file changed, 849 insertions

Godot-Convention.md(fichier créé)

@@ -0,0 +1,849 @@
1 + # Godot 4.7 — Project Conventions & API Reference
2 +
3 + A reference document for the EnvoyOS project targeting Godot 4.7. Derived from the official [Godot 4.7 documentation](https://github.com/godotengine/godot-docs/tree/4.7) structure and the project's `AIFIX.md` corrections.
4 +
5 + ---
6 +
7 + ## Table of Contents
8 +
9 + 1. [GDScript Syntax & Type Hints](#1-gdscript-syntax--type-hints)
10 + 2. [Node Lifecycle](#2-node-lifecycle)
11 + 3. [Signals](#3-signals)
12 + 4. [Input Handling](#4-input-handling)
13 + 5. [Controls & UI](#5-controls--ui)
14 + 6. [Window Management](#6-window-management)
15 + 7. [Audio](#7-audio)
16 + 8. [Networking (Multiplayer)](#8-networking-multiplayer)
17 + 9. [File I/O](#9-file-io)
18 + 10. [Resources & Loading](#10-resources--loading)
19 + 11. [Performance](#11-performance)
20 + 12. [Style Conventions](#12-style-conventions)
21 + 13. [Common Pitfalls & Corrections](#13-common-pitfalls--corrections)
22 +
23 + ---
24 +
25 + ## 1. GDScript Syntax & Type Hints
26 +
27 + ### Typed Arrays
28 +
29 + ```gdscript
30 + # WRONG (Godot 3 style, inferred empty array)
31 + var rocks := []
32 +
33 + # CORRECT (Godot 4.7 explicit type)
34 + var rocks: Array[Label] = []
35 + var items: Array[Dictionary] = []
36 + var names: Array[String] = []
37 + var scales: Array[float] = []
38 + ```
39 +
40 + ### Variable Declarations
41 +
42 + ```gdscript
43 + # Prefer explicit types over := inference when the type is unambiguous
44 + var file: FileAccess = FileAccess.open(path, FileAccess.READ)
45 + var parsed: Variant = JSON.parse_string(json_str)
46 +
47 + # Use := only when the right-hand side type is clear
48 + var btn := Button.new()
49 + var style := StyleBoxFlat.new()
50 + ```
51 +
52 + ### Color Construction
53 +
54 + ```gdscript
55 + # WRONG
56 + col.color = Color.rand()
57 +
58 + # CORRECT
59 + col.color = Color(randf(), randf(), randf())
60 + ```
61 +
62 + ### Global Functions (Not Methods)
63 +
64 + ```gdscript
65 + # WRONG (clampf is a global function, not a method on float)
66 + _transparency_multiplier = value.clampf(0.0, 1.0)
67 +
68 + # CORRECT
69 + _transparency_multiplier = clampf(value, 0.0, 1.0)
70 + # OR
71 + _transparency_multiplier = clamp(value, 0.0, 1.0)
72 + ```
73 +
74 + ### Vector Operations
75 +
76 + ```gdscript
77 + # WRONG (ceiled() does not exist on Vector2)
78 + var target := vec.ceiled()
79 +
80 + # CORRECT
81 + var target := Vector2i(vec.ceil())
82 + ```
83 +
84 + ### Async/Await
85 +
86 + ```gdscript
87 + # WRONG (yield was removed in Godot 4)
88 + yield(get_tree().process_frame, "process_frame")
89 +
90 + # CORRECT
91 + await get_tree().process_frame
92 + ```
93 +
94 + ### Process Delta Time
95 +
96 + ```gdscript
97 + # WRONG (throws error)
98 + var speed = Node.get_process_delta_time()
99 +
100 + # CORRECT
101 + var speed = get_process_delta_time()
102 + ```
103 +
104 + ### Constants & Enums
105 +
106 + ```gdscript
107 + const MAX_ITEMS := 12
108 + const CONFIG_PATH := "user://inventory_config.cfg"
109 +
110 + enum PowerState {
111 + OFF = 0,
112 + LOW = 1,
113 + NETWORK = 2,
114 + HIGH = 3,
115 + }
116 + ```
117 +
118 + ---
119 +
120 + ## 2. Node Lifecycle
121 +
122 + ### Key Notifications (Godot 4.7)
123 +
124 + ```gdscript
125 + func _notification(what: int) -> void:
126 + match what:
127 + NOTIFICATION_WM_CLOSE_REQUEST:
128 + # Window close (replaces NOTIFICATION_WM_QUIT_REQUEST)
129 + pass
130 + NOTIFICATION_APPLICATION_PAUSED, NOTIFICATION_APPLICATION_FOCUS_OUT:
131 + # App backgrounded / lost focus
132 + pass
133 + NOTIFICATION_APPLICATION_RESUMED, NOTIFICATION_APPLICATION_FOCUS_IN:
134 + # App foregrounded / regained focus
135 + pass
136 + ```
137 +
138 + ### Process Mode (Replaces Old Pause Mode)
139 +
140 + ```gdscript
141 + # WRONG
142 + timer.pause_mode = Timer.PAUSE_MODE_PROCESS
143 +
144 + # CORRECT
145 + timer.process_mode = Node.PROCESS_MODE_ALWAYS
146 + ```
147 +
148 + ### Dialogs and Timers
149 +
150 + ```gdscript
151 + # When a ConfirmationDialog is shown via popup_centered(),
152 + # the SceneTree pauses. Timers inside will stop unless:
153 + dialog.process_mode = Node.PROCESS_MODE_ALWAYS
154 + ```
155 +
156 + ### Node Creation and Freeing
157 +
158 + ```gdscript
159 + # To clear a container's children (VBoxContainer has no .clear() in Godot 4)
160 + # WRONG
161 + kitchen_sink_box.clear()
162 +
163 + # CORRECT
164 + for child in container.get_children():
165 + child.queue_free()
166 + ```
167 +
168 + ### Safe Instance Checks
169 +
170 + ```gdscript
171 + # After any await or deferred call, verify the object still exists
172 + if is_instance_valid(node) and node.is_inside_tree():
173 + node.do_something()
174 + ```
175 +
176 + ---
177 +
178 + ## 3. Signals
179 +
180 + ### Declaration
181 +
182 + ```gdscript
183 + signal item_updated(index: int)
184 + signal stats_updated(latency_ms: float, jitter: float, packet_loss: float)
185 + ```
186 +
187 + ### Connecting (with type-safe lambdas)
188 +
189 + ```gdscript
190 + btn.pressed.connect(_on_button_pressed.bind(index))
191 + slider.value_changed.connect(func(val: float): _on_slider(val))
192 + ```
193 +
194 + ### Disconnecting
195 +
196 + ```gdscript
197 + if signal_name in node.get_signal_connection_list(sig):
198 + node.disconnect(sig, callable)
199 + ```
200 +
201 + ### RPC (Multiplayer)
202 +
203 + ```gdscript
204 + @rpc("any_peer", "unreliable_ordered")
205 + func receive_secure_clipboard(encrypted_data: PackedByteArray) -> void:
206 + pass
207 +
208 + # Call from any peer:
209 + rpc("receive_secure_clipboard", data)
210 + ```
211 +
212 + ---
213 +
214 + ## 4. Input Handling
215 +
216 + ### Key Codes (Godot 4.7)
217 +
218 + ```gdscript
219 + if event is InputEventKey and event.keycode == KEY_TAB and Input.is_key_pressed(KEY_CTRL):
220 + pass
221 + ```
222 +
223 + ### Touchscreen
224 +
225 + ```gdscript
226 + # WRONG
227 + Input.is_touchscreen_available()
228 +
229 + # CORRECT
230 + DisplayServer.is_touchscreen_available()
231 + ```
232 +
233 + ### WebRTC Feature Check
234 +
235 + ```gdscript
236 + # WRONG
237 + Engine.has_feature("web_view")
238 +
239 + # CORRECT
240 + OS.has_feature("web") or ClassDB.class_exists("WebRTCPeerConnection")
241 + ```
242 +
243 + ### Mouse Position (Global vs Local)
244 +
245 + ```gdscript
246 + # For window-level calculations (resize, drag), use GLOBAL screen coords:
247 + var global_mouse: Vector2 = DisplayServer.mouse_get_position()
248 +
249 + # For UI-local calculations:
250 + var local_mouse: Vector2 = get_viewport().get_mouse_position()
251 + ```
252 +
253 + ---
254 +
255 + ## 5. Controls & UI
256 +
257 + ### StyleBoxFlat (Per-Corner, Per-Side)
258 +
259 + ```gdscript
260 + # WRONG (Godot 3 properties do not exist in 4.7)
261 + style.border_width_all = 2
262 + style.corner_radius_all = 16
263 +
264 + # CORRECT (individual properties)
265 + style.border_width_left = 2
266 + style.border_width_right = 2
267 + style.border_width_top = 2
268 + style.border_width_bottom = 2
269 + style.corner_radius_top_left = 16
270 + style.corner_radius_top_right = 16
271 + style.corner_radius_bottom_left = 16
272 + style.corner_radius_bottom_right = 16
273 + ```
274 +
275 + ### StyleBox Copying
276 +
277 + ```gdscript
278 + # WRONG
279 + var hover_style = StyleBoxFlat.new(style)
280 +
281 + # CORRECT
282 + var hover_style = style.duplicate()
283 + ```
284 +
285 + ### TextEdit Wrapping
286 +
287 + ```gdscript
288 + # WRONG
289 + system_input.fit_content_width = true
290 +
291 + # CORRECT
292 + system_input.wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY
293 + ```
294 +
295 + ### Tree Items
296 +
297 + ```gdscript
298 + # WRONG (type inference fails)
299 + var child := control.create_item(root)
300 +
301 + # CORRECT
302 + var child: TreeItem = control.create_item(root)
303 + ```
304 +
305 + ### Abstract Classes
306 +
307 + ```gdscript
308 + # WRONG (Slider is abstract, cannot be constructed)
309 + Slider.new()
310 +
311 + # CORRECT
312 + VSlider.new()
313 + HSlider.new()
314 + ```
315 +
316 + ### TabBar Close Buttons
317 +
318 + ```gdscript
319 + # WRONG (property does not exist)
320 + tab_bar.tabs_closeable = true
321 +
322 + # CORRECT
323 + tab_bar.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS
324 + tab_bar.tab_close_pressed.connect(_on_tab_close_pressed)
325 + ```
326 +
327 + ### Hiding TabContainer's Built-in Tab Bar
328 +
329 + ```gdscript
330 + tab_container.tabs_visible = false
331 + ```
332 +
333 + ### ConfirmationDialog
334 +
335 + ```gdscript
336 + # Godot 4.7: use get_cancel_button() (not get_cancel())
337 + dialog.get_cancel_button().text = "Cancel"
338 + ```
339 +
340 + ---
341 +
342 + ## 6. Window Management
343 +
344 + ### V-Sync
345 +
346 + ```gdscript
347 + # WRONG
348 + DisplayServer.vsync = DisplayServer.VSYNC_ENABLED
349 +
350 + # CORRECT
351 + DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)
352 + ```
353 +
354 + ### DPI / Content Scaling
355 +
356 + ```gdscript
357 + # WRONG (size_scale does not exist)
358 + get_window().size_scale = 2.0
359 +
360 + # CORRECT
361 + get_window().content_scale_factor = 2.0
362 + # OR for base resolution:
363 + get_window().content_scale_size = Vector2i(1920, 1080)
364 + ```
365 +
366 + ### Window Size (Integer Required)
367 +
368 + ```gdscript
369 + # Adjust physical window size inversely proportional to scale
370 + var target_size := Vector2i((LOGICAL_BASE_SIZE / scale).ceil())
371 + window.size = target_size
372 + ```
373 +
374 + ### Deferred Window Size (Avoid Startup Race)
375 +
376 + ```gdscript
377 + window.content_scale_factor = scale
378 + var target_size := Vector2i((LOGICAL_BASE_SIZE / scale).ceil())
379 + window.set_deferred("size", target_size)
380 + ```
381 +
382 + ### Borderless Window
383 +
384 + ```gdscript
385 + get_window().borderless = true
386 + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
387 + ```
388 +
389 + ### Resize Flag (Windows DWM)
390 +
391 + ```gdscript
392 + # WRONG (RESIZE flag does not exist as a set-to-true operation)
393 + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE, true)
394 +
395 + # CORRECT (pass false to RESIZE_DISABLED to ENABLE resizing)
396 + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, false)
397 + ```
398 +
399 + ### Borderless Resize (Global Mouse)
400 +
401 + ```gdscript
402 + # Must use global screen coordinates for borderless resize
403 + var global_mouse := DisplayServer.mouse_get_position()
404 + var window_top_left := get_window().position
405 + var target_width: int = int(max(global_mouse.x - window_top_left.x, 800))
406 + var target_height: int = int(max(global_mouse.y - window_top_left.y, 500))
407 + get_window().size = Vector2i(target_width, target_height)
408 + ```
409 +
410 + ### Cursor Shapes
411 +
412 + ```gdscript
413 + DisplayServer.cursor_set_shape(DisplayServer.CURSOR_DRAG)
414 + DisplayServer.cursor_set_shape(DisplayServer.CURSOR_HSIZE)
415 + DisplayServer.cursor_set_shape(DisplayServer.CURSOR_ARROW)
416 + ```
417 +
418 + ### Always on Top
419 +
420 + ```gdscript
421 + get_window().always_on_top = true
422 + ```
423 +
424 + ### Window Position
425 +
426 + ```gdscript
427 + DisplayServer.window_set_position(Vector2i(x, y))
428 + # OR
429 + get_window().position = Vector2i(x, y)
430 + ```
431 +
432 + ---
433 +
434 + ## 7. Audio
435 +
436 + ### Bus Management
437 +
438 + ```gdscript
439 + AudioServer.add_bus()
440 + AudioServer.set_bus_volume_db(index, db)
441 + AudioServer.set_bus_mute(index, true)
442 + AudioServer.get_bus_count()
443 + AudioServer.get_bus_name(index)
444 + ```
445 +
446 + ### Audio Effects
447 +
448 + ```gdscript
449 + var capture := AudioEffectCapture.new()
450 + AudioServer.add_bus_effect(bus_index, capture)
451 + AudioServer.set_bus_effect_enabled(bus_index, effect_index, true)
452 + ```
453 +
454 + ### Microphone Input
455 +
456 + ```gdscript
457 + var mic_stream := AudioStreamMicrophone.new()
458 + player.stream = mic_stream
459 + player.bus = AudioServer.get_bus_name(bus_index)
460 + player.autoplay = true
461 + ```
462 +
463 + ### PCM Playback
464 +
465 + ```gdscript
466 + var wav := AudioStreamWAV.new()
467 + wav.format = AudioStreamWAV.FORMAT_16_BITS
468 + wav.mix_rate = 48000
469 + wav.stereo = true
470 + wav.set_data(PackedFloat32Array)
471 + player.stream = wav
472 + player.play()
473 + ```
474 +
475 + ### Input Device List
476 +
477 + ```gdscript
478 + if AudioServer.has_method("get_input_device_list"):
479 + var devices: Array[String] = AudioServer.call("get_input_device_list")
480 + ```
481 +
482 + ---
483 +
484 + ## 8. Networking (Multiplayer)
485 +
486 + ### ENet Multiplayer
487 +
488 + ```gdscript
489 + var peer := ENetMultiplayerPeer.new()
490 + var err: int = peer.create_server(port)
491 + # OR
492 + var err: int = peer.create_client("192.168.1.10", 8443)
493 +
494 + multiplayer.multiplayer_peer = peer
495 + ```
496 +
497 + ### Signals
498 +
499 + ```gdscript
500 + multiplayer.connected_to_server.connect(_on_connected)
501 + multiplayer.connection_failed.connect(_on_failed)
502 + multiplayer.server_disconnected.connect(_on_disconnected)
503 + multiplayer.peer_connected.connect(_on_peer_joined)
504 + multiplayer.peer_disconnected.connect(_on_peer_left)
505 + multiplayer.get_peers() # Array[int]
506 + multiplayer.get_unique_id() # int
507 + ```
508 +
509 + ### UDP (VoIP)
510 +
511 + ```gdscript
512 + var pkt_peer := PacketPeerUDP.new()
513 + pkt_peer.connect_to_host(ip, port)
514 + pkt_peer.put_data(PackedByteArray)
515 + pkt_peer.get_available_packet_count()
516 + pkt_peer.get_packet() # PackedByteArray
517 + pkt_peer.close()
518 + ```
519 +
520 + ### Local Addresses
521 +
522 + ```gdscript
523 + # WRONG
524 + IP.get_network_interfaces() # as static call
525 +
526 + # CORRECT (on the singleton instance)
527 + var addresses: Array = IP.get_local_addresses()
528 + var interfaces: Array = IP.get_network_interfaces()
529 + ```
530 +
531 + ### Crypto (AES-256)
532 +
533 + ```gdscript
534 + var aes := AESContext.new()
535 + var hash_ctx := HashingContext.new()
536 + hash_ctx.start(HashingContext.HASH_SHA256)
537 + hash_ctx.update(key_bytes)
538 + var key: PackedByteArray = hash_ctx.finish()
539 +
540 + aes.start(AESContext.MODE_ECB_ENCRYPT, key)
541 + var encrypted: PackedByteArray = aes.update(data)
542 + aes.finish()
543 + ```
544 +
545 + ---
546 +
547 + ## 9. File I/O
548 +
549 + ### ConfigFile
550 +
551 + ```gdscript
552 + var config := ConfigFile.new()
553 + config.load("user://settings.cfg")
554 + var val = config.get_value("section", "key", default)
555 + config.set_value("section", "key", value)
556 + config.save("user://settings.cfg")
557 + ```
558 +
559 + ### FileAccess
560 +
561 + ```gdscript
562 + # Plain
563 + var file := FileAccess.open(path, FileAccess.READ)
564 + var text := file.get_as_text()
565 + file.close()
566 +
567 + # Compressed (FastLZ)
568 + var file := FileAccess.open_compressed(path, FileAccess.WRITE, FileAccess.COMPRESSION_FASTLZ)
569 + file.store_string(json_str)
570 + file.close()
571 +
572 + # Check existence
573 + FileAccess.file_exists("user://data.json")
574 + ```
575 +
576 + ### CSV
577 +
578 + ```gdscript
579 + file.store_csv_line(["col1", "col2", "col3"])
580 + var row: PackedStringArray = file.get_csv_line()
581 + ```
582 +
583 + ### JSON
584 +
585 + ```gdscript
586 + var parsed: Variant = JSON.parse_string(json_text)
587 + var json_str: String = JSON.stringify(data, "\t")
588 + ```
589 +
590 + ---
591 +
592 + ## 10. Resources & Loading
593 +
594 + ### Loading Scripts
595 +
596 + ```gdscript
597 + # Static (compile-time)
598 + const MyScript = preload("res://scripts/my_script.gd")
599 +
600 + # Dynamic (runtime)
601 + var script: GDScript = load("res://scripts/dynamic.gd")
602 + var instance: Node = script.new()
603 + ```
604 +
605 + ### Loading Fonts
606 +
607 + ```gdscript
608 + var custom_font: Font = load("res://font/text_with_emojis.tres")
609 + ```
610 +
611 + ### Class Registration
612 +
613 + ```gdscript
614 + class_name MyEngine
615 + extends Node
616 + ```
617 +
618 + > **Note:** If two scripts reference each other (circular dependency),
619 + > relax the type hint to the base class to break the loop:
620 + > ```gdscript
621 + > # Instead of:
622 + > var tab_bar: MainTabBar
623 + > # Use:
624 + > var tab_bar: TabBar
625 + > ```
626 +
627 + ---
628 +
629 + ## 11. Performance
630 +
631 + ### FPS
632 +
633 + ```gdscript
634 + Engine.get_frames_per_second()
635 + Engine.max_fps = 60
636 + ```
637 +
638 + ### Draw Calls
639 +
640 + ```gdscript
641 + Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME)
642 + ```
643 +
644 + ### Low Processor Usage
645 +
646 + ```gdscript
647 + OS.low_processor_usage_mode = true
648 + ```
649 +
650 + ### Object Pooling
651 +
652 + ```gdscript
653 + # Pre-allocate nodes, toggle visibility instead of create/free
654 + var pool: Array[Label] = []
655 + for i in POOL_SIZE:
656 + var node := Label.new()
657 + node.visible = false
658 + add_child(node)
659 + pool.append(node)
660 + ```
661 +
662 + ### Avoid Per-Frame Allocations
663 +
664 + ```gdscript
665 + # Reuse cache arrays
666 + var _cache: Array[Node] = []
667 +
668 + func update():
669 + _cache.clear()
670 + for item in items:
671 + if item.valid:
672 + _cache.append(item)
673 + # Swap with working array
674 + var temp = items
675 + items = _cache
676 + _cache = temp
677 + ```
678 +
679 + ### Debounce Timers
680 +
681 + ```gdscript
682 + var _save_timer := Timer.new()
683 + _save_timer.wait_time = 1.0
684 + _save_timer.one_shot = true
685 + add_child(_save_timer)
686 +
687 + # In event handler:
688 + _save_timer.stop()
689 + _save_timer.start()
690 + ```
691 +
692 + ---
693 +
694 + ## 12. Style Conventions
695 +
696 + ### File Naming
697 +
698 + | Pattern | Purpose |
699 + |---------|---------|
700 + | `*_engine.gd` | Logic / data / network layer |
701 + | `*_ui.gd` | Presentation / node construction |
702 + | `*_helper.gd` | Static utility functions |
703 +
704 + ### Engine Pattern
705 +
706 + ```gdscript
707 + extends Node
708 + class_name MyEngine
709 +
710 + signal data_changed(value: Variant)
711 +
712 + const CONFIG_PATH := "user://my_settings.cfg"
713 +
714 + var _state: Dictionary = {}
715 +
716 + func _ready() -> void:
717 + _load()
718 +
719 + func _exit_tree() -> void:
720 + _save()
721 +
722 + func _process(delta: float) -> void:
723 + # Per-frame logic
724 +
725 + # Public API
726 + func get_value(key: String) -> Variant: ...
727 + func set_value(key: String, val: Variant) -> void: ...
728 +
729 + # Private helpers
730 + func _load() -> void: ...
731 + func _save() -> void: ...
732 + ```
733 +
734 + ### UI Pattern
735 +
736 + ```gdscript
737 + extends RefCounted
738 + class_name MyUI
739 +
740 + static func setup_ui(page_container: Node, engine: Node) -> void:
741 + # Guard against double-setup
742 + if page_container.has_node("MyWrapper"):
743 + return
744 +
745 + # Locate content area
746 + var layout_vbox = page_container.get_child(0)
747 + var main_content = layout_vbox.get_child(0)
748 +
749 + # Clear previous
750 + for child in main_content.get_children():
751 + child.queue_free()
752 +
753 + # Build UI...
754 + ```
755 +
756 + ### Print Statements
757 +
758 + ```gdscript
759 + print("[EngineName] Message: ", detail)
760 + push_warning("[EngineName] Non-fatal issue")
761 + push_error("[EngineName] Fatal issue: ", err)
762 + ```
763 +
764 + ---
765 +
766 + ## 13. Common Pitfalls & Corrections
767 +
768 + | # | Wrong | Correct | Reason |
769 + |---|-------|---------|--------|
770 + | 1 | `var items := []` | `var items: Array[Label] = []` | Typed arrays required |
771 + | 2 | `DisplayServer.vsync = true` | `DisplayServer.window_set_vsync_mode(...)` | API changed in 4.x |
772 + | 3 | `Input.is_touchscreen_available()` | `DisplayServer.is_touchscreen_available()` | Moved to DisplayServer |
773 + | 4 | `Color.rand()` | `Color(randf(), randf(), randf())` | No static rand() |
774 + | 5 | `yield(...)` | `await ...` | yield removed in Godot 4 |
775 + | 6 | `container.clear()` | `for c in container.get_children(): c.queue_free()` | No clear() on Container |
776 + | 7 | `style.border_width_all = 2` | Per-side `border_width_left/right/top/bottom` | No _all shortcut |
777 + | 8 | `style.corner_radius_all = 16` | Per-corner `corner_radius_top_left/...` | No _all shortcut |
778 + | 9 | `StyleBoxFlat.new(style)` | `style.duplicate()` | No copy constructor |
779 + | 10 | `fit_content_width = true` | `wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY` | Property renamed |
780 + | 11 | `Slider.new()` | `VSlider.new()` / `HSlider.new()` | Slider is abstract |
781 + | 12 | `tab_bar.tabs_closeable = true` | `tab_bar.tab_close_display_policy = ...` | Property renamed |
782 + | 13 | `get_window().size_scale = 2.0` | `get_window().content_scale_factor = 2.0` | Property renamed |
783 + | 14 | `DisplayServer.window_set_flag(RESIZE, true)` | `DisplayServer.window_set_flag(RESIZE_DISABLED, false)` | Flag semantics inverted |
784 + | 15 | `dialog.get_cancel()` | `dialog.get_cancel_button()` | Method renamed in 4.6+ |
785 + | 16 | `Node.get_process_delta_time()` | `get_process_delta_time()` | Instance method, not static |
786 + | 17 | `vec.ceiled()` | `Vector2i(vec.ceil())` | Wrong method name |
787 + | 18 | `IP.get_network_interfaces()` (static) | `IP.get_network_interfaces()` (on singleton) | Must be instance call |
788 + | 19 | `NOTIFICATION_WM_QUIT_REQUEST` | `NOTIFICATION_WM_CLOSE_REQUEST` | Renamed in Godot 4 |
789 + | 20 | `timer.pause_mode = PAUSE_MODE_PROCESS` | `timer.process_mode = PROCESS_MODE_ALWAYS` | Renamed in Godot 4 |
790 + | 21 | `Engine.has_feature("web_view")` | `OS.has_feature("web")` | Correct singleton + feature |
791 + | 22 | `var child := control.create_item(root)` | `var child: TreeItem = control.create_item(root)` | Type inference fails |
792 + | 23 | `Engine.get_process_time()` | Does not exist | Use `Time.get_ticks_msec()` |
793 + | 24 | `NOTIFICATION_FOCUS_OUT` | `NOTIFICATION_APPLICATION_FOCUS_OUT` | Correct constant name |
794 +
795 + ---
796 +
797 + ## Quick Reference: Godot 4.7 Class Hierarchy (UI)
798 +
799 + ```
800 + CanvasItem
801 + ├── Control
802 + │ ├── Container
803 + │ │ ├── VBoxContainer
804 + │ │ ├── HBoxContainer
805 + │ │ ├── GridContainer
806 + │ │ ├── MarginContainer
807 + │ │ ├── PanelContainer
808 + │ │ ├── ScrollContainer
809 + │ │ ├── TabContainer
810 + │ │ ├── HSplitContainer / VSplitContainer
811 + │ │ └── CenterContainer
812 + │ ├── Label
813 + │ ├── Button
814 + │ ├── CheckBox
815 + │ ├── OptionButton
816 + │ ├── LineEdit
817 + │ ├── TextEdit
818 + │ ├── RichTextLabel
819 + │ ├── HSlider / VSlider
820 + │ ├── ProgressBar
821 + │ ├── SpinBox
822 + │ ├── ColorPickerButton
823 + │ ├── Tree
824 + │ ├── TabBar
825 + │ ├── PopupMenu
826 + │ └── ConfirmationDialog (extends Window)
827 + ├── Node2D
828 + ├── AudioStreamPlayer
829 + └── Node (base)
830 + ```
831 +
832 + ---
833 +
834 + ## References
835 +
836 + - [Godot 4.7 Documentation](https://docs.godotengine.org/en/4.7/)
837 + - [Godot 4.7 Class Reference](https://docs.godotengine.org/en/4.7/classes/index.html)
838 + - [Getting Started](https://docs.godotengine.org/en/4.7/getting_started/index.html)
839 + - [Tutorials](https://docs.godotengine.org/en/4.7/tutorials/index.html)
840 + - [Engine Details](https://docs.godotengine.org/en/4.7/engine_details/index.html)
841 + - [GDScript Syntax](https://docs.godotengine.org/en/4.7/tutorials/scripting/gdscript/index.html)
842 + - [Signals](https://docs.godotengine.org/en/4.7/tutorials/scripting/signals.html)
843 + - [Multiplayer](https://docs.godotengine.org/en/4.7/tutorials/networking/multiplayer_introduction.html)
844 + - [Window Management](https://docs.godotengine.org/en/4.7/classes/class_displayserver.html)
845 + - [Audio](https://docs.godotengine.org/en/4.7/tutorials/audio/index.html)
846 +
847 + ---
848 +
849 + *Last updated for Godot 4.7. Cross-reference with `AIFIX.md` for project-specific corrections.*

ZZ's Avatar ZZ a révisé ce gist 1786853206. Aller à la révision

Aucun changement

ZZ's Avatar ZZ a révisé ce gist 1786850842. Aller à la révision

Aucun changement

ZZ's Avatar ZZ a révisé ce gist 1786850796. Aller à la révision

1 file changed, 1 insertion, 1 deletion

Qwen-SUMMARY.md

@@ -225,4 +225,4 @@ Theme: ThemeSerializer (compressed JSON, hex colors, FastLZ)
225 225
226 226 ## License & Attribution
227 227
228 - Open-source. See repository for license file. Built with ❤️ and too much coffee. ☕
228 + See repository for license file. Built with ❤️ and too much coffee. ☕
Plus récent Plus ancien