Agent Instructions
Project Overview
Mazele Dazzle is a mobile maze generation and play app for Android (iOS planned for future).
Key Features
- Generate mazes with configurable size (10x10, 20x20, 30x30), difficulty (Easy/Medium/Hard), and shape (Rectangle/Circle/Diamond/Heart)
- Interactive maze play mode with joystick controls and pinch-to-zoom
- Save mazes as PNG images to device gallery
- Share via social networks/messengers
- Freemium model: 5 free mazes/day, unlimited with Google Play subscription
Tech Stack
- .NET 9 with C# 13, nullable reference types enabled, implicit usings enabled
- MAUI (Multi-platform App UI) - Android-only target (
net9.0-android) - xUnit for unit tests with coverlet for coverage
- SkiaSharp for image processing (export margins)
- Google Play Billing Client (
Xamarin.Android.Google.BillingClient) for subscriptions - Target: Android API 28+ (Android 9.0+)
Documentation
docs/concept.en.md- Full project concept and business modeldocs/screens.en.md- Screen descriptions and UI requirementsdocs/monetization.md- Subscription/freemium model detailsdocs/change-requests/- Change request specifications
Build, Test, and Run Commands
Development is done natively on Windows. MAUI builds do NOT work under WSL/Ubuntu.
# Build entire solution
dotnet build PuzzleDazzle.sln
# Build Android app only
dotnet build src/PuzzleDazzle/PuzzleDazzle.csproj -f net9.0-android
# Build core library only (fast, no Android SDK needed)
dotnet build src/PuzzleDazzle.Core/PuzzleDazzle.Core.csproj
# Run all tests
dotnet test tests/PuzzleDazzle.Core.Tests/PuzzleDazzle.Core.Tests.csproj
# Run a single test by fully-qualified name
dotnet test tests/PuzzleDazzle.Core.Tests/PuzzleDazzle.Core.Tests.csproj --filter "FullyQualifiedName~MazeGeneratorTests.Generate_ValidDimensions_CreatesMazeWithCorrectSize"
# Run all tests in a single test class
dotnet test tests/PuzzleDazzle.Core.Tests/PuzzleDazzle.Core.Tests.csproj --filter "FullyQualifiedName~UsageTrackingServiceTests"
# Run on connected device/emulator (fast rebuild + deploy)
dotnet build src/PuzzleDazzle/PuzzleDazzle.csproj -f net9.0-android -t:Run
# Build release APK + AAB
dotnet publish src/PuzzleDazzle/PuzzleDazzle.csproj -f net9.0-android -c Release
Notes:
- The Core library targets
net9.0(not Android), sodotnet buildanddotnet testwork from any OS/WSL. - The MAUI app targets
net9.0-androidonly and requires Android SDK on Windows. - XAML Hot Reload is unreliable; use fast rebuild (
-t:Run) for iteration. - No linter or static analysis is configured. No CI/CD pipeline exists.
Project Structure
PuzzleDazzle/
├── PuzzleDazzle.sln
├── src/
│ ├── PuzzleDazzle/ # MAUI app (Android-only)
│ │ ├── Controls/ # Custom UI controls (MazeView, JoystickView, PlayMazeView, EmojiAnimationView)
│ │ ├── Rendering/ # Maze renderers (IMazeRenderer, ClassicMazeRenderer)
│ │ ├── Services/ # App-level services (MazeExportService, MauiPreferencesService, subscription impls)
│ │ ├── Resources/ # Fonts (FontAwesome, OpenSans), icons, styles
│ │ ├── Platforms/Android/ # Android-specific code (MainActivity, manifest)
│ │ ├── GenerationPage.xaml(.cs) # Main screen - generate, save, share mazes
│ │ ├── MazePlayPage.xaml(.cs) # Interactive maze play screen
│ │ ├── SettingsPage.xaml(.cs) # Size/difficulty/shape settings
│ │ ├── PremiumUpgradePage.xaml(.cs) # Subscription purchase screen
│ │ └── MauiProgram.cs # DI registration and app bootstrap
│ └── PuzzleDazzle.Core/ # Core library (platform-independent, net9.0)
│ ├── Models/ # Maze, Cell, MazeShape, MazeDifficulty, MazeAlgorithm
│ ├── Generation/ # MazeGenerator + algorithm interface
│ │ └── Algorithms/ # RecursiveBacktrackingAlgorithm
│ └── Services/ # IPreferencesService, ISubscriptionService, UsageTrackingService
└── tests/
└── PuzzleDazzle.Core.Tests/ # xUnit tests (mirrors Core structure)
├── Models/ # CellTests, MazeTests, MazeShapeTests
├── Generation/ # MazeGeneratorTests
└── Services/ # UsageTrackingServiceTests (with in-memory test doubles)
Code Style Guidelines
C# Conventions
- Namespaces: File-scoped (
namespace PuzzleDazzle.Core.Models;), matching folder structure - Nullable: Enabled globally. Use
null!for properties initialized by framework. Use?for genuinely nullable types - Implicit usings: Enabled. No need to import
System,System.Collections.Generic,System.Linq, etc. - Access modifiers: Explicit
public/private. Default toprivatefor fields and helper methods - Fields:
_camelCasewith underscore prefix for private fields (private readonly Random _random;) - Properties: PascalCase. Use
{ get; private set; }for externally-read/internally-written properties - Methods: PascalCase. Async methods use
Asyncsuffix (GenerateAsync,CanGenerateAsync) - Constants: PascalCase (
private const string GenerationCountKey = "DailyGenerationCount";) - Enums: PascalCase members, defined in the same file as the primary class they relate to (e.g.,
MazeDifficultyinMaze.cs,ShapeTypeinMazeShape.cs) - Braces: Allman style (opening brace on new line). Single-statement
ifbodies may omit braces - Indentation: Tabs in MAUI app project, 4-space indentation in Core library. Follow existing file conventions
- XML doc comments: Required on all public types, interfaces, and non-trivial public methods using
<summary>tags - Event handlers:
async voidonly for MAUI event handlers (e.g.,OnStartClicked). All other async methods returnTask/Task<T>
Imports / Usings
- Rely on implicit usings for
System.*namespaces - Explicit
usingonly for project namespaces (using PuzzleDazzle.Core.Models;) - Order: framework usings first, then project usings
- No
global usingstatements beyond the implicit ones (xUnit test project has<Using Include="Xunit" />in csproj)
Architecture Patterns
- Core library (
PuzzleDazzle.Core): Platform-independent. NO MAUI/Android references. Contains models, algorithms, and service interfaces - App project (
PuzzleDazzle): MAUI-specific implementations. References Core - Dependency inversion: Core defines interfaces (
IPreferencesService,ISubscriptionService), app provides implementations - DI registration in
MauiProgram.cswith#if DEBUG/#elsefor mock vs real services - Code-behind pattern: Pages use XAML + code-behind (no MVVM ViewModels yet). Controls access elements by
x:Name - Conditional compilation:
#if DEBUGfor development conveniences (unlimited access, mock services, debug info in alerts)
Error Handling
- Guard clauses with
ArgumentException/InvalidOperationExceptionfor invalid inputs (seeMazeconstructor) try/catchwithDisplayAlertfor user-facing errors in page event handlers- Catch-and-log pattern in background services (e.g.,
GooglePlaySubscriptionService) - Return
nullfor out-of-bounds access rather than throwing (seeMaze.GetCell) - Suppress non-critical errors silently (e.g., media scanner failures in
MazeExportService)
Testing Patterns
- Framework: xUnit with
[Fact]and[Theory]/[InlineData]attributes - Naming:
MethodName_Condition_ExpectedResult(e.g.,Generate_ValidDimensions_CreatesMazeWithCorrectSize) - Structure: Arrange/Act/Assert pattern with comments separating sections
- Test doubles: In-memory implementations defined in the same test file (e.g.,
InMemoryPreferencesService,TestSubscriptionService) - Seeded randomness: Use
new MazeGenerator(seed: 42)for deterministic/reproducible tests - Test file location: Mirrors source structure (
Core/Models/Maze.cs->Core.Tests/Models/MazeTests.cs) - Only Core is tested: The test project only covers
PuzzleDazzle.Core. MAUI app code has no automated tests
XAML Conventions
- XML namespace aliases:
controlsforPuzzleDazzle.Controls,localforPuzzleDazzle - Colors via
{DynamicResource}referencingColors.xaml(Primary, Gray100-900) - Font Awesome icons via
{x:Static local:FontAwesomeIcons.IconName}withFontFamily="FontAwesome" - Semantic properties (
SemanticProperties.Hint) on interactive elements for accessibility
Issue Tracking
This project uses bd (beads) for issue tracking. Run bd onboard to get started.
Quick Reference
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --status in_progress # Claim work
bd close <id> # Complete work
bd sync # Sync with git
Landing the Plane (Session Completion)
When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.
MANDATORY WORKFLOW:
- File issues for remaining work - Create issues for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update issue status - Close finished work, update in-progress items
- PUSH TO REMOTE - This is MANDATORY:
git pull --rebase bd sync git push git status # MUST show "up to date with origin" - Clean up - Clear stashes, prune remote branches
- Verify - All changes committed AND pushed
- Hand off - Provide context for next session
CRITICAL RULES:
- Work is NOT complete until
git pushsucceeds - NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds