diff --git a/docs/internal/agents/coordination-board.md b/docs/internal/agents/coordination-board.md index f04a017e..5bfa401e 100644 --- a/docs/internal/agents/coordination-board.md +++ b/docs/internal/agents/coordination-board.md @@ -3,6 +3,30 @@ **STOP:** Before posting, verify your **Agent ID** in [personas.md](personas.md). Use only canonical IDs. **Guidelines:** Keep entries concise (<=5 lines). Archive completed work weekly. Target <=40 active entries. +### 2025-12-26 imgui-frontend-engineer – Mobile layout + nav pass +- TASK: Improve iPad layout (responsive welcome cards + panel width clamps), add mobile nav switcher, tune iOS touch sizing, and track per-edge safe areas. +- SCOPE: src/app/editor/ui/welcome_screen.*, src/app/editor/menu/right_panel_manager.cc, src/app/editor/menu/activity_bar.cc, src/app/editor/layout/layout_coordinator.cc, src/app/editor/ui/ui_coordinator.*, src/app/platform/ios/ios_window_backend.mm, src/app/platform/ios/ios_platform_state.* +- STATUS: COMPLETE +- NOTES: Compact layout uses floating nav button; right/side panels clamp to viewport; safe-area insets stored for per-edge use. + +### 2025-12-25 imgui-frontend-engineer – iOS touch + safe area tuning +- TASK: Add touch target padding + safe-area padding for ImGui on iOS. +- SCOPE: src/app/platform/ios/ios_window_backend.mm +- STATUS: COMPLETE +- NOTES: TouchExtraPadding targets 44pt min; DisplaySafeAreaPadding uses max safe-area insets. + +### 2025-12-25 imgui-frontend-engineer – Dashboard responsive layout pass +- TASK: Rebuild dashboard/editor selection grid layout for responsive sizing + theme-based colors. +- SCOPE: src/app/editor/ui/dashboard_panel.cc, src/app/editor/ui/editor_selection_dialog.cc +- STATUS: COMPLETE +- NOTES: z3ed CLI not available; tracking sub-steps locally. + +### 2025-12-24 imgui-frontend-engineer – Graphics palette tint regression +- TASK: Fix red-tinted palettes across graphics previews (LoadAssets/Tile16). +- SCOPE: src/app/gfx/types/snes_color.cc, src/app/gfx/types/snes_palette.cc, src/app/editor/overworld/tile16_editor.* +- STATUS: COMPLETE +- NOTES: Corrected CGX palette conversion to avoid 0-255 vs 0-1 misuse; removed redundant set_rgb in palette constructors; restored palette-row offset mapping to skip HUD rows. Follow-up: tile16 palette pipeline preserves encoded CGRAM offsets end-to-end (tile8 + tile16 + previews) unless auto-normalize is enabled, and remaps rows using sheet base. + ### 2025-12-06 ai-infra-architect – Overworld Editor Refactoring Phase 2 - TASK: Critical bug fixes and Tile16 Editor polish - SCOPE: src/app/editor/overworld/, src/app/gfx/render/ @@ -10,6 +34,36 @@ - NOTES: Fixed tile cache (copy vs move), centralized zoom constants, re-enabled live preview, scaled entity hit detection, restored Tile16 Editor window, fixed SNES palette offset (+1), added palette remapping for source canvas viewing, visual sheet/palette indicators, diagnostic function. Simplified scratch space to single slot. Added toolbar panel toggles. - NEXT: Phase 2 Week 2 - Toolset improvements (eyedropper, flood fill, eraser tools) +### 2025-12-24 snes-emulator-expert – Overworld palette tint regression +- TASK: Investigate red-tinted overworld palette regression after history compaction. +- SCOPE: src/app/overworld/, src/app/gfx/, src/zelda3/overworld/ +- STATUS: COMPLETE +- NOTES: Tile16 palette row mapping now uses ROM palette indices directly (no HUD row offset); adjusted remap logging/comments. + +### 2025-12-23 imgui-frontend-engineer – Merge blockers + GLFW/iOS plan +- TASK: Patch merge blockers (dungeon map reserved writes, Asar temp cleanup, 2BPP save guard) and draft GLFW+iOS integration plan with lab/orchestration notes. +- SCOPE: src/zelda3/screen/dungeon_map.cc, src/core/asar_wrapper.cc, src/app/editor/graphics/*, docs/internal. +- STATUS: COMPLETE +- INITIATIVE_DOC: docs/internal/agents/initiative-glfw-ios-backend.md +- NOTES: z3ed CLI not available in environment; tracking sub-steps locally. + +### 2025-12-24 imgui-frontend-engineer – iOS rebuild phase 0 +- TASK: Start iOS-first execution; stabilize native file picker for iOS. +- SCOPE: src/app/platform/file_dialog.mm, src/ios/*, src/app/platform/ios/ios_host.mm, src/app/gfx/backend/metal_renderer.mm +- STATUS: ACTIVE +- NOTES: Added typed file dialog options + iOS picker type support; stubbed ios_host + metal_renderer, wired Metal renderer into factory/CMake, switched iOS main loop to IOSHost, added Xcode project + Info.plist updates (file sharing + sfc/smc UTTypes), added iOS window backend/platform state + Metal ImGui wiring, and fixed iOS framework links (SDKROOT + ModelIO + forced iOS linker flags). Continuing to split atomic commits + review remaining iOS/mobile changes. + +### 2025-12-24 backend-infra-engineer – iOS thin app + XcodeGen +- TASK: CMake-built iOS static libs + generated Xcode app shell. +- SCOPE: CMake presets/platform defs, cmake/dependencies, src/ios/project.yml, scripts/ios. +- STATUS: COMPLETE (added iOS presets + bundle target + XcodeGen spec + build-ios.sh; legacy pbxproj still in repo). + +### 2025-12-24 backend-infra-engineer – iOS file dialog async + bundle assets +- TASK: Fix iOS file picker re-entrancy and ensure bundled assets are discoverable. +- SCOPE: src/app/platform/file_dialog.*, src/app/editor/editor_manager.cc, src/app/editor/ui/ui_coordinator.cc, src/util/platform_paths.cc, src/ios/project.yml. +- STATUS: COMPLETE +- NOTES: Added async open dialog API; iOS ROM/project flows now async; assets copied into bundle for fonts/themes; iOS config/docs paths use sandbox via YAZE_IOS guard (avoid /.yaze). + ### 2025-12-22 zelda3-hacking-expert – Dungeon map save parity + palette wiring - TASK: Align dungeon map save flow with ZScream reference and unblock rom-dependent editor tests. - SCOPE: src/zelda3/screen/dungeon_map.cc, test/e2e/rom_dependent/screen_editor_save_test.cc, test/integration/zelda3/dungeon_graphics_transparency_test.cc, src/zelda3/game_data.cc, src/app/gfx/util/palette_manager.cc. @@ -22,6 +76,18 @@ - STATUS: IN_PROGRESS - NOTES: Replaced vanilla ROM with clean padded copy; fixed test SaveRomToFile to overwrite test copies; aligned expanded tile16 detection. +### 2025-12-22 imgui-frontend-engineer – Lab target for layout designer +- TASK: Move layout designer into a standalone lab target and decouple it from the main editor UI. +- SCOPE: src/lab/, src/lab/layout_designer/, editor menu, CMake, docs/internal/architecture. +- STATUS: COMPLETE +- NOTES: Added YAZE_BUILD_LAB option + `lab` executable, moved layout designer into src/lab/, removed main editor menu hook, and updated layout designer docs for lab usage. + +### 2025-12-22 backend-infra-engineer – Local nightly install workflow +- TASK: Create isolated nightly build/install flow for yaze + z3ed + yaze-mcp distinct from dev builds. +- SCOPE: scripts/, CMakeUserPresets.json.example, docs/public/build/quick-reference.md, scripts/README.md +- STATUS: COMPLETE +- NOTES: Added scripts/install-nightly.sh with wrapper commands; documented nightly flow + env overrides in quick-reference/install-options. + ### 2025-12-21 backend-infra-engineer – Codebase size reduction review - TASK: Audit repo size + build configuration outputs; propose shrink plan (submodules, build dirs, deps cache). - SCOPE: build*/ , ext/, vcpkg*, assets/, roms/, CMakePresets.json diff --git a/docs/internal/agents/initiative-glfw-ios-backend.md b/docs/internal/agents/initiative-glfw-ios-backend.md new file mode 100644 index 00000000..050aa380 --- /dev/null +++ b/docs/internal/agents/initiative-glfw-ios-backend.md @@ -0,0 +1,67 @@ +# Initiative: GLFW Backend + iOS Rebuild + Lab Orchestration + +Status: DRAFT +Owner: imgui-frontend-engineer +Created: 2025-12-23 +Last Reviewed: 2025-12-23 +Next Review: 2026-01-06 +Validation/Exit Criteria: +- GLFW backend can run the editor shell with ImGui viewports enabled and stable. +- iOS app boots, loads a ROM via native document picker, and renders the editor UI. +- Lab target supports backend selection and layout import/export for rapid UX iteration. +- Editor orchestration is separated from editor implementations and reusable across desktop/iOS/lab. + +## Goals +- Add a GLFW + OpenGL backend option to unlock ImGui viewports for experimentation. +- Rebuild the iOS host app with native iOS integrations and the ImGui editor system. +- Use the lab target as the sandbox for layout and orchestration experiments. +- Decouple UX orchestration from editor logic for fine-grained control. + +## Scope +- Window backend abstraction updates needed for non-SDL windows. +- OpenGL renderer path that satisfies `IRenderer` requirements (textures + blits). +- iOS host refactor (metal + imgui backend, document picker, app lifecycle hooks). +- Lab target improvements (backend selection, layout import/export, viewport stress tests). + +## Non-Goals +- Full emulator input parity on GLFW (defer to follow-up once input backend is defined). +- Complete SDL removal (GLFW remains optional). +- Shipping viewports as the default on desktop. + +## Phased Plan +### Phase 1: Backend Abstraction and GLFW Entry Point +- Define a backend-neutral native window handle and remove SDL-only assumptions in the renderer init path. +- Introduce `WindowBackendType::GLFW` and `RendererBackendType::OpenGL`. +- Add `GLFWWindowBackend` using `imgui_impl_glfw` + `imgui_impl_opengl3`. +- Add OpenGL renderer that can handle `CreateTexture`, `UpdateTexture`, and `RenderCopy`. + +### Phase 2: Lab Target Expansion +- Add backend selection flags to the lab target for quick viewport testing. +- Add layout import/export round-trip and preset management. +- Add viewport stress scenes (multi-dock + texture-heavy panels). + +### Phase 3: iOS App Rebuild +- New iOS host app with Metal-backed ImGui renderer and full app lifecycle support. +- Native integrations: document picker, share sheet, background/foreground safe handling. +- Mobile layout presets and a touch-first panel navigation surface. + +### Phase 4: Orchestration Decoupling +- Extract `UIOrchestrator` that owns dockspace/menu/panel visibility. +- Keep editors focused on data/model and panel registration. +- Expose per-panel visibility and orchestration state for fine-grained control. + +## Risks / Constraints +- `IRenderer` currently assumes SDL types; refactor must avoid breaking existing SDL2/SDL3 paths. +- OpenGL renderer must handle palette-indexed textures sourced from SDL surfaces. +- iOS input and file access require security-scoped bookmarks and careful threading. + +## Dependencies +- GLFW + OpenGL toolchain availability on macOS. +- ImGui OpenGL backend support (no GL loader assumed, use platform headers). +- iOS signing and entitlements for file access. + +## Milestones +- M1: GLFW backend runs lab target with viewports enabled. +- M2: OpenGL renderer draws tilemaps and editor textures. +- M3: iOS app boots with ROM load and core UI flow. +- M4: Orchestration decoupling merged and used by lab/iOS. diff --git a/docs/internal/testing/README.md b/docs/internal/testing/README.md index c5d934fa..85c8d020 100644 --- a/docs/internal/testing/README.md +++ b/docs/internal/testing/README.md @@ -8,6 +8,8 @@ This document serves as the central hub for all testing infrastructure in the yaze project. It coordinates testing strategies across local development, CI/CD, and release validation workflows. +**ROM policy**: GitHub CI runs without ROMs and skips ROM-dependent suites. Run ROM tests locally with `YAZE_ENABLE_ROM_TESTS=ON` and `YAZE_TEST_ROM_*` paths, or force-skip with `YAZE_SKIP_ROM_TESTS=1`. + ## Quick Links - **Developer Quick Start**: [Testing Quick Start Guide](../../public/developer/testing-quick-start.md) diff --git a/docs/plans/MCP_UNIFICATION.md b/docs/plans/MCP_UNIFICATION.md new file mode 100644 index 00000000..6eadb735 --- /dev/null +++ b/docs/plans/MCP_UNIFICATION.md @@ -0,0 +1,43 @@ +# Yaze MCP Unification Plan + +**Status:** Draft +**Goal:** Create a high-quality, unified toolset for AI-assisted debugging in Zelda3 ROM hacking. + +## 1. Backend Consolidation (C++) + +### A. Move `EmulatorServiceImpl` to `yaze_grpc_support` +- Relocate `src/cli/service/agent/emulator_service_impl.{cc,h}` to `src/app/service/`. +- Update `src/app/service/grpc_support.cmake` to include these files. +- This allows the GUI application to link against the emulator control logic. + +### B. Update `YazeGRPCServer` +- Modify `YazeGRPCServer::Initialize` to accept a `yaze::emu::Emulator*`. +- In `BuildServer()`, register the `EmulatorServiceImpl`. +- Result: A single gRPC port (default 50052) handles ROM I/O, GUI automation, AND Emulator control. + +## 2. MCP Server Enhancements (Python) + +### A. Semantic Translation (Knowledge Graph) +- Integrate `hafs` knowledge base. +- Add a lookup layer: if a tool returns an address (e.g., `$028000`), the MCP server should look up the label in `symbols.json` and append it: `$02:8000 [Module07_Underworld]`. +- Allow tools to accept labels directly: `read_memory("Link_X_Coord")` -> `read_memory("$7EF36D")`. + +### B. Visualization Support +- Implement `capture_screenshot` using the `CanvasAutomationService`. +- Return high-resolution PNGs to the AI agent for visual debugging of sprite positions and menu states. + +### C. Watchpoint History Analysis +- Improve `get_watchpoint_history` to provide a summary of *why* memory changed (e.g., "Address $7EF36D changed from $00 to $01 during `Link_MoveX`"). + +## 3. Sandboxed Test Suites + +### A. Headless Validation +- Use `z3ed` (the CLI) to run the unified gRPC server in a headless mode. +- Create a suite of Python scripts that use the MCP tools to verify common scenarios: + - Can I set a breakpoint and have it hit? + - Can I read Link's health and modify it? + - Can I step through a routine and verify the CPU flags change? + +### B. Integration with ALTTP ROMs +- Provide a set of "Golden State" snapshots for vanilla ALTTP. +- Test routines against these snapshots to ensure the MCP tools provide consistent and accurate data across different game regions. diff --git a/docs/public/build/install-options.md b/docs/public/build/install-options.md index be4fb539..36ae61ce 100644 --- a/docs/public/build/install-options.md +++ b/docs/public/build/install-options.md @@ -65,6 +65,15 @@ cd build-wasm && npx http-server . - When creating packages (Homebrew/Chocolatey/winget), pin the release URL and checksum and align dependencies to the CMake presets (`mac-*/lin-*/win-*`). - Keep CLI and GUI in the same archive to avoid mismatched versions; CLI entry is `z3ed`, GUI entry is `yaze`. +## Local Nightly (Self-Build) +For an isolated nightly build separate from your dev tree, use: +```bash +scripts/install-nightly.sh +``` +This installs into `~/.local/yaze/nightly/current` and exposes wrapper commands +(`yaze-nightly`, `z3ed-nightly`, `yaze-mcp-nightly`). +Re-run the script to update to the latest commit. + ## Quick Links - Build quick reference: `docs/public/build/quick-reference.md` - CMake presets: `CMakePresets.json` diff --git a/docs/public/build/quick-reference.md b/docs/public/build/quick-reference.md index c5c98b17..a11e7d50 100644 --- a/docs/public/build/quick-reference.md +++ b/docs/public/build/quick-reference.md @@ -50,6 +50,7 @@ YAZE uses CMake presets for consistent builds. Configure with `cmake --preset ` and updates `.../current` symlink. +- Writes wrapper scripts to `$YAZE_NIGHTLY_BIN_DIR` (default `~/.local/bin`). + +Updating: +```bash +scripts/install-nightly.sh # re-pulls and installs a new release +``` + +Removing: +```bash +rm -rf ~/.local/yaze/nightly ~/.local/bin/yaze-nightly* ~/.local/bin/z3ed-nightly ~/.local/bin/yaze-mcp-nightly +``` + +Key overrides: +```bash +export YAZE_NIGHTLY_REPO="$HOME/Code/yaze-nightly" +export YAZE_NIGHTLY_PREFIX="$HOME/.local/yaze/nightly" +export YAZE_NIGHTLY_BUILD_TYPE=RelWithDebInfo +export YAZE_GRPC_PORT=50051 +export YAZE_MCP_REPO="$HOME/Code/yaze-mcp" +``` + ### Shared Dependency Caches (Recommended) Set shared caches once per machine to avoid re-downloading dependencies after diff --git a/docs/public/developer/architecture.md b/docs/public/developer/architecture.md index 1d1cfc27..86619bdd 100644 --- a/docs/public/developer/architecture.md +++ b/docs/public/developer/architecture.md @@ -2,20 +2,28 @@ This guide summarizes the architecture and implementation standards used across the editor codebase. -## Editor Status (November 2025) +## Editor Status (December 2025) -| Editor | State | Panels | Notes | -|-------------------|--------------|--------|-------| -| Overworld | Stable | 8 | Full feature set with tile16 editor, scratch space. | -| Message | Stable | 4 | Message list, editor, font atlas, dictionary panels. | -| Emulator | Stable | 10 | CPU, PPU, Memory debuggers; AI agent integration. | -| Palette | Stable | 11 | Source of truth for palette helpers. | -| Assembly | Stable | 2 | File browser and editor panels. | -| Dungeon | Stable | 8 | Room selector, matrix, graphics, object editor. | -| Graphics | Stable | 4 | Sheet editor, browser, player animations. | -| Sprite | Stable | 2 | Vanilla and custom sprite panels. | -| Screen | Stable | 5 | Dungeon maps, inventory, title screen, etc. | -| Music | Experimental | 3 | Tracker, instrument editor, assembly view. | +**Status rubric**: +- **Stable**: Core workflows function reliably; remaining TODOs are UX polish. +- **Beta**: Core workflows exist, but important features are incomplete or experimental. +- **Experimental**: WIP, flagged experimental in UI, or has major TODOs in core paths. + +| Editor | State | Evidence | +|--------|-------|----------| +| Overworld | Stable | E2E coverage; TODOs for v3 settings UI and entity deletion. | +| Dungeon | Stable | E2E coverage; TODOs for usage tracker, selection preview, and rendering TODOs in `src/zelda3/dungeon`. | +| Message | Stable | TODO: replace workflow in message editor. | +| Palette | Stable | TODO: JSON export/import and notifications. | +| Graphics | Beta | Explicit experimental section; screen editor marked WIP. | +| Sprite | Stable | Core sprite panels present; no WIP markers in editor code. | +| Screen | Experimental | `screen_editor.h` labeled WIP; title/inventory TODOs. | +| Emulator | Beta | Debug UI + PPU TODOs; save-state UI not fully wired. | +| Assembly | Beta | TODOs in assembly editor and project file editor. | +| Hex | Beta | Memory editor lacks search and richer UX; see `src/app/editor/code`. | +| Agent | Experimental | Chain mode labeled experimental; collaboration TODOs. | +| Music | Experimental | Sample import/export and BRR tooling TODOs; serialization incomplete. | +| Settings | Beta | Settings/project manager and layout serialization TODOs. | ### Recent Improvements (v0.3.9) @@ -30,6 +38,67 @@ This guide summarizes the architecture and implementation standards used across - **Dungeon object rendering**: Regression with object visibility - **ZSOW v3 palettes**: Large-area palette issues being investigated +## Codebase Map + +```text +yaze/ +├── src/ +│ ├── app/ # Desktop app (editors, gfx, emu, UI) +│ ├── zelda3/ # Domain data + ROM parsing (overworld, dungeon, music) +│ ├── rom/ # Core ROM container, transactions, diagnostics +│ ├── cli/ # z3ed CLI + agent tooling +│ ├── lab/ # Sandbox targets (layout designer, UI experiments) +│ ├── web/ # WASM UI + browser integration +│ ├── core/ # Shared core utilities/patch logic +│ └── util/ # Logging, file IO, helpers +├── incl/ # Public C API headers +├── test/ # Unit/integration/e2e/benchmarks +├── tools/ # Dev tools and build helpers +├── assets/ # Built-in assets (no ROMs) +├── cmake/ # Build system and dependency wiring +├── scripts/ # Automation helpers +└── docs/ # Documentation (public/internal) +``` + +```mermaid +flowchart TD + app[src/app] --> zelda3[src/zelda3] + zelda3 --> rom[src/rom] + app --> gfx[src/app/gfx] + app --> emu[src/app/emu] + cli[src/cli] --> rom + cli --> zelda3 + web[src/web] --> app + tools[src/tools] --> rom +``` + +## ROM Operations and Data Flow + +- **Load**: `RomFileManager`/`SessionCoordinator` load ROMs into `Rom` and hydrate `zelda3::GameData`. +- **Read/Write**: `Rom` provides byte/word/long access; `Transaction` batches edits safely. +- **Domain parse**: `zelda3::*` modules interpret ROM data (overworld, dungeon rooms, sprites, music). +- **Edit**: Editors mutate domain models, then persist via save helpers (overworld, dungeon maps, palettes). +- **Patch/compare**: Asar wrapper, ROM diff tools, and doctor commands validate or patch data. +- **Test**: `TestRomManager` resolves ROMs locally; CI runs without ROMs and skips ROM-dependent suites. + +## UX/UI Feature Map + +- **Card-based layout**: EditorCardRegistry + LayoutManager for dockable panels and presets. +- **Session-aware UI**: Multi-session coordinator, per-editor panel visibility, activity bar. +- **Command tooling**: Command palette, shortcut manager, action registry. +- **Theming**: Shared palette + semantic color tokens via AgentUI theme helpers. +- **Agent UI**: Chat panels, tool execution, and multimodal test harnesses. +- **Layout designer**: WYSIWYG layout tooling for panel arrangements. + +## Density Reduction Opportunities + +- **Quarantine legacy ROM code**: `src/rom/rom_old.*` can move to a legacy target or be removed if unused. +- **Make WIP editors optional**: Gate agent UI and music editor behind build flags; layout designer now ships via the lab target. +- **Split editor system**: `yaze_editor_system_{panels,session,shortcuts}` targets now isolate editor system components. +- **Isolate experimental UI**: Layout designer now lives under `src/lab/` and builds via `YAZE_BUILD_LAB` (default OFF). +- **De-duplicate editor panels**: Consolidate shared panel patterns across dungeon/overworld/screen. +- **Reduce build surface**: Make emulator and web UI optional in minimal builds. + ## 1. Core Architectural Patterns These patterns, established during the Overworld Editor refactoring, should be applied to all new and existing editor components. diff --git a/docs/public/developer/testing-guide.md b/docs/public/developer/testing-guide.md index b49a61f5..11009f26 100644 --- a/docs/public/developer/testing-guide.md +++ b/docs/public/developer/testing-guide.md @@ -41,6 +41,8 @@ test/ | **E2E** | Simulate user workflows | GUI + ROM | Slow | | **Benchmarks** | Measure performance | None | Variable | +**ROM policy**: GitHub CI does not run ROM-dependent tests. Run them locally with `YAZE_ENABLE_ROM_TESTS=ON` and `YAZE_TEST_ROM_*` paths. Use `YAZE_SKIP_ROM_TESTS=1` to force-skip ROM suites. + ### Unit Tests Fast, isolated tests with no external dependencies. Run in CI on every commit. @@ -101,6 +103,8 @@ ctest --preset dev # Stable tests ctest --preset all # All tests ``` +ROM-dependent CTest suites are local-only and will be skipped when ROMs are not configured. + --- ## Writing Tests diff --git a/docs/public/developer/testing-without-roms.md b/docs/public/developer/testing-without-roms.md index 6ecbe83d..8afb771a 100644 --- a/docs/public/developer/testing-without-roms.md +++ b/docs/public/developer/testing-without-roms.md @@ -12,6 +12,8 @@ The `z3ed` AI agent now supports **mock ROM mode** for testing without requiring - **Contributors** - Test the agent without needing to provide ROMs - **Automated testing** - Consistent, reproducible test environments +GitHub CI does not run ROM-dependent editor tests; those must be exercised locally with real ROMs. + ## How Mock ROM Mode Works Mock ROM mode creates a minimal but valid ROM structure with: