Something that happens sometimes...

Dev Log Chapter

Contextual Filtering and Chronology Shifting

The layout of product pages using the standardized template was completed. Performance optimization was conducted: heavy CSS background masks were replaced with pre-processed images (background-image). A product-centric idea for contextual navigation was introduced: now, from a project's page, users can transition into its development log with one click. To achieve this, log filtering by URL parameter was configured in the MarkdownService, where the post order automatically switches to chronological (\(1 \rightarrow 2 \rightarrow 3\)). This allows reading the product's creation history as a sequential narrative, while preserving architectural purity (KISS) without complicating the main layout.

Custom Markdown Engine and Bilingual Architecture

The architecture for the dynamic C# engine for publishing posts was implemented. The Markdig and YamlDotNet libraries were integrated to automatically read metadata (dates, titles, screenshot arrays) from the YAML headers of .md files. Within the MarkdownService, a mechanism was configured to parse bilingual sections directly in the document body via HTML comments (<!--en--> and <!--ru-->), pulling the current language from the session. For the One Man Army section, a "newspaper" Z-layout based on floats with alternating art was developed, and for the Dev Log, an isolated, lightweight screenshot viewer (Lightbox) was created.

DevLog Screenshot
DevLog Screenshot

The reorganization of the Breadcrumbs system was completed. The logic for forming them was moved to the global _Layout level, completely eliminating HTML code duplication and styling desynchronization. Concurrently, a custom module for handling server exceptions (404/500) was developed. Through the UseStatusCodePagesWithReExecute middleware, requests are redirected to a unified Error page without changing the URL. Multi-status localization and a dynamic illustration of Schrödinger's Cat were introduced, changing depending on the active site theme.

DevLog Screenshot
DevLog Screenshot

Standardization of project pages has begun. The initial idea of a horizontal carousel for the media gallery failed testing: mixing 16:9, 9:16 formats, and videos broke the composition, and UI compression rendered screenshots unreadable. The concept was completely overhauled in favor of a "Category Grid + Native Lightbox" system. The close-up viewer is built on the HTML <dialog> element utilizing the browser's Top Layer API mechanism. This freed the architecture from CSS layer conflicts (z-index) and ensured proper modal overlay above the rest of the content. A JS module was written for looped keyboard navigation.

Implementing Multilingual Support and Eliminating Hardcode

The interface localization system was designed and implemented. A complete elimination of hardcoded text was achieved: UI elements were moved to centralized JSON dictionaries. To process them, a LocalizationService was written and injected into the Razor Pages. A mechanism for seamless language switching was implemented via a global middleware interceptor in Program.cs. The selected language is saved in the session, and the switch happens transparently, preserving the current page without complex server-side routing. Dynamic content rendering was configured to correctly pass HTML tags from the JSON database to modal windows.

DevLog Screenshot
DevLog Screenshot

Projects Grid and Particle Physics on HTML5 Canvas

The Projects page was developed. The layout approach was architecturally modified: the InCubation block was moved inside the main Flex container, turning into a "fluid" closing module (flex-grow) that automatically fills the space without a single media query. Inside this block, a background particle system based on HTML5 Canvas was deployed. "Vacuum breathing" was programmed: Brownian motion of dots with a timer that periodically assembles static isometric cube structures out of the chaos. For the project cards, a layered poster overlay was implemented, where the colored layer smoothly appears via CSS transitions on hover.

Home Page Layout and CSS Masking

The Hero Section was laid out using Flexbox. During the process, an issue with incorrect background image scaling on ultrawide monitors was identified. The solution involved hard-locking the background size (1440x1080) pinned to the center and implementing a combined CSS mask with the calc() function to smoothly dissolve the image borders into the base color. To protect the desktop layout from deformation, a width lock (min-width: 1200px) was applied, activating a horizontal scroll. Micro-interactions were added to the navigation cards: an outer glow and a custom @keyframes icon-pop CSS animation for icon hover feedback.

DevLog Screenshot
DevLog Screenshot

Master Template, SVG Graphics, and Seamless Themes

The Production phase has begun. The base ASP.NET Core project was deployed, and the _Layout master template was created. The key interface feature became the mechanics of dynamically switching between Dark and Light themes via CSS Variables without reloading the page. To support this system, all text indicators and raster icons were replaced with Inline SVG graphics. Using the fill="currentColor" property ensured automatic icon recoloring when switching themes. A Hot Reload environment was configured, and the core typography was built around the Inter font family, incorporating thin weights.

Database-Free Architecture and the Choice of Markdown

A detailed analysis of the future site's operational logic was conducted, and the content architecture was approved. A strategic decision was made to abandon heavy databases in favor of a Stateless concept based on ASP.NET Core (Razor Pages). For content sections (Dev Log, One Man Army), a publication system via a .md document file repository was introduced. The engine is planned to parse the YAML Front Matter metadata block to extract dates and tags, dynamically wrapping the text into the approved design code. Separated routing logic was also established: the Dev Log feed will be built using a LIFO principle (newest posts on top), while the author's history will follow a FIFO principle (chronological reading).

DevLog Screenshot

Pre-production, UI-Driven Approach, and the Birth of inHub

Development of a personal web platform began, intended to become the central hub for all software projects. During the pre-production phase, the Project Vision was formed with the philosophy "One Mind. Endless Ideas." A UI-driven approach was chosen: designing the technical architecture was consciously postponed until the visual concepts were fully understood. Mockups for the Home page were created in light and dark themes, and the core navigation logic with an intermediate project hub was mapped out. During the design process, the platform received the official name inHub and was classified as a fully independent product, acting as the primary testing ground for mastering the web technology stack.

DevLog Screenshot

Storefront Merchant Obstacles and Release Pause

The commercial distribution phase encountered insurmountable infrastructure and financial platform roadblocks for individual developers. During Microsoft Partner Center setup, merchant payout onboarding stalled indefinitely due to mandatory corporate account requirements (Entra ID) and business registration verification, freezing individual profile submissions.

Attempts to deploy standalone sales via Gumroad and Lemon Squeezy reached similar dead ends: Stripe Connect integrations disabled direct payouts for the region, while alternative payout methods remained blocked for individual accounts lacking US business registration.

The product was frozen at Production Ready status (v1.0). The compiled installers, marketing assets, and codebase were archived locally. Confronting these distribution barriers highlighted the necessity of building an independent web platform, providing the direct catalyst for transitioning into web development.

Standalone Installer, MSIX Packaging, and Update Engine

The product reached full distribution readiness. A standalone inNote_Setup_v1.0.exe installer was compiled via Inno Setup using LZMA2 compression, reducing a ~162 MB footprint into a compact 48.6 MB executable. Concurrently, an x64 native MSIX package (.appxupload) was generated via Windows Application Packaging Project for Microsoft Store deployment.

An asynchronous background update service (UpdateService) was developed. The engine queries a public GitHub configuration file via non-blocking HttpClient calls with a strict 3-second timeout. Custom notification UI was created, and an IsStoreVersion toggle was added: when set to true, the internal update engine is completely disabled for Microsoft Store builds, letting the OS manage updates natively.

DevLog Screenshot

Multi-Monitor Rescue Mechanism and Atomic Persistence

Comprehensive alpha testing was conducted on a dual-monitor workstation. Coordinate boundaries were updated to SystemParameters.VirtualScreen. A "Lost Window Syndrome" edge-case was resolved: when a secondary monitor was disconnected, notes remained stranded in off-screen space. A rescue mechanism was written to detect out-of-bounds coordinates and automatically teleport orphaned notes to the center of the primary display.

To safeguard data against abrupt power loss or crashes, a three-tier Data Resilience system was integrated into DataManager:

Atomic Writes: Saves target a temporary .tmp file before instantly swapping with the active file.

Auto-Recovery: A .bak backup file is generated upon every successful write cycle.

Quarantine: If primary files corrupt, data recovers seamlessly from backup while the damaged file is isolated into a .corrupted log for manual inspection.

DevLog Screenshot

Dynamic i18n Localization Engine and Feature Refactoring

A dynamic internationalization (i18n) architecture was developed, supporting English, Spanish, German, and French. Hardcoded XAML strings were extracted into isolated resource dictionaries (Lang.*.xaml). LanguageManager was built to auto-detect system language (CultureInfo.CurrentUICulture) and hot-swap merged dictionaries at runtime without restarting the application.

Feature scope was also refactored: the text strike-through (checklist) feature was officially cut. Standard TextBox lacked partial line formatting support, while upgrading to RichTextBox bloated JSON payloads and conflicted with font auto-scaling routines. The decision was made to preserve clean architecture and lightweight performance.

Global Win32 API Hotkeys and Registry Integration

A global hotkey feature was implemented to spawn notes instantly from anywhere within the operating system. A dedicated HotKeyManager class was designed using low-level Win32 API P/Invoke imports from user32.dll, registering Ctrl+Alt+N directly against window handles. To prevent startup crashes, registration binds to the SourceInitialized event, ensuring a valid window Handle is allocated by Windows first.

Concurrently, StartupManager was created to manage system startup integration. It interfaces directly with the Windows Registry (HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run). The module writes clean process paths and syncs toggle states cleanly with configuration options stored in appConfig.json.

Background Launch and Hybrid System Tray Manager

The application was restructured to operate as a silent, background utility. Removing StartupUri from App.xaml and switching the shutdown mode to ShutdownMode.OnExplicitShutdown enabled a headless startup sequence without spawning phantom windows.

To manage application states, a hybrid TrayManager service was engineered. Bypassing the outdated visual styling of WinForms NotifyIcon, the tray context menu was generated programmatically in pure WPF, referencing shared resource dictionaries. To fix menu dismissal issues when clicking outside the tray bounds, a hidden 0x0 px helper window was integrated to pull OS window focus to the WPF thread prior to menu rendering.

Global NoteManager Orchestrator and Smart Debounce

Core window management logic was completed with the creation of NoteManager, a global orchestrator built on the Singleton pattern. The manager retains an in-memory ObservableCollection, tracks active MainWindow instances, manages window Z-indexing, and binds UI layers to models through DataContext assignment.

Executing disk writes on every single keystroke created unnecessary storage overhead and file I/O queues. To resolve this, a smart auto-save mechanism (Debounce) was built using DispatcherTimer. The timer waits for 500 milliseconds of user inactivity (after typing, dragging, re-coloring, or rotating) before committing a single batched JSON state write to disk.

DevLog Screenshot

Trigonometric Rotation and Space Isolation

A custom note rotation feature was developed to allow subtle desktop tilting. To eliminate visual jitter when dragging, angle calculations were shifted from the dynamic coordinates of the rotating canvas to the static coordinate space of the root window.

Vector delta calculations utilize Math.Atan2 relative to the stationary window center (180, 180). A discrete snapping mechanism locks angles in 5° increments via mathematical rounding (Math.Round(angle / 5.0) * 5.0). The final rotation value is strictly constrained between -15° and +15° and bound to the data model. To prevent accidental rotation triggers during text editing, interaction zones were split: clicking within 35 px of any corner activates rotation mode with a custom rotate_cursor.cur, while central clicks manage typing and dragging.

Embedded Typography and Text Auto-Scaling

Work on the text layer was finalized by integrating the custom handwritten font Caveat (Caveat-Regular.ttf) directly into the binary assembly as an embedded resource. This guarantees identical rendering across any host machine without requiring OS font installation.

Addressing WPF's default typography engine revealed excessive line spacing issues with handwritten glyphs. By switching to LineStackingStrategy.BlockLineHeight, systemic WPF spacing constraints were bypassed, locking line heights to an optimal 0.88 multiplier of the font size. A reactive auto-scaling algorithm was implemented, smoothly scaling font size down from 50 px to 20 px as text volume increases. To prevent overflow beyond the physical paper bounds (ExtentHeight > 253 px), a hard limit trigger interrupts both keyboard entry and clipboard pastes, performing safe state rollbacks while preserving caret position.

DevLog Screenshot

Bypassing Windows Input and Custom Right-Click Dragging

A core interaction mechanic was implemented—moving the window across the desktop using the right mouse button (RMB). During development, an architectural conflict emerged: the standard TextBox input layer completely absorbed right-clicks, while WPF's built-in this.DragMove() method is hardware-bound exclusively to the left mouse button.

The event swallowing issue was resolved by subscribing to tunneling events: PreviewMouseRightButtonDown, PreviewMouseMove, and PreviewMouseRightButtonUp. This intercepted input signals before they bubbled down into the TextBox. A custom coordinate calculation algorithm was written: PointToScreen() evaluates absolute cursor coordinates, subtracts the initial click offset, and dynamically updates the window's Left and Top properties. Input capturing via CaptureMouse() prevents cursor drift during rapid movements, while a 3-pixel deadzone threshold distinguishes dragging from context menu clicks.

DevLog Screenshot

Canvas Geometry, Borderless UI, and 3D Volume Mask

The custom visual layout was constructed, completely discarding default Windows borders and title bars (WindowStyle="None", AllowsTransparency="True"). To transform a standard window into a realistic paper sheet, a rectangular NoteCanvas was engineered with baseline dimensions of 283x283 px.

During initial layout testing, a clipping issue was identified: enabling diffuse DropShadowEffect caused the window bounds to crop the soft shadow edges. The outer MainWindow container was forcibly expanded to 360x360 px, creating the necessary breathing space. To replicate physical paper texture, a vector LinearGradientBrush mask was overlaid at a 50° angle with 8 color stops, producing a subtle cylindrical bend and light glare effect. A palette of 8 pastel colors was implemented using XAML DataTriggers, alongside a Dark Mode inversion where the black gradient automatically switches to a matte white highlight.

Starting Point and MVVM Architecture

A decision was made to expand the engineering stack and master Windows desktop development as a second focus area following game development. The project was conceived as a lightweight alternative to default sticky notes, emphasizing aesthetics and a distraction-free UI.

An architectural foundation was established in C# 12 and .NET 8 using the MVVM pattern. The core NoteModel class was designed to describe note states, including coordinates, dimensions, color index, rotation angle, Z-layer, and visibility flags. The model implements INotifyPropertyChanged using the [CallerMemberName] attribute under a strict .NET 8 Nullable context, achieving zero compiler warnings. For disk operations, a static DataManager utility class was implemented to handle baseline JSON serialization of note lists.

DevLog Screenshot

Google Play Release and Retrospective

The full development pipeline has been navigated: from early notebook sketches to Unity assembly and production on Google Play.

Release asset preparation was finalized, and Google Play Console's regulatory verification checks were cleared. To comply with 2024+ platform policy requirements, a mandatory 14-day closed beta sprint was completed with 22 testers recruited via Reddit on a Test-for-Test basis.

The project is officially published in the store, marking the first completed milestone in this solo development journey.

Battles for the Save System

Integrating the save system near the tail end of development brought significant architectural friction. The first two iterations (naive JSON serialization and fragmented data management across subsystems) proved unreliable: onboarding broken, code complexity ballooned, and the Continue button behaved unpredictably. The resolution involved rolling back to a clean build and consolidating state control under a unified GameManager (SaveGame(), LoadGame(), DeleteSave()).

A edge-case bug caused by GameManager missing in the start scene was bypassed via direct file deletion (File.Delete()). Three clean progress reset pathways were established: within the pause menu, main menu, and post-game completion.

Build DRiot_v0.9.1 was locked as a stable pre-release candidate.

DevLog Screenshot

Order in Audio Chaos

Global audio system implementation was completed. A centralized AudioManager was established using the Singleton pattern with cross-scene persistence (DontDestroyOnLoad).

All SFX were mapped to specific triggers: UI button clicks, tile shuffles, part assembly, drone spawns, and victory triggers. Effect volumes were balanced, and smooth music crossfades were configured. The Victory scene was dramatized by layering an extended explosion sound that smoothly fades into the final audio track.

Sound isn't mere decoration; it drives gameplay rhythm and emotional weight.

DevLog Screenshot
DevLog Screenshot

The Battle for a Single Button (Skip Puzzle)

A dedicated sprint focused on UI polish, the Victory scene, resolving interface layer collisions, and handling coroutine states. The project was restored from a stable archive and rebuilt.

PauseMenu logic was refactored: menu panels are now properly isolated, while drone and fire animations are hidden via CanvasGroup without disrupting background coroutines. A confirmation modal was added to the New Game button to prevent accidental progress wipes. The delay preceding the final scene transition was extended to make the Victory moment feel more impactful.

Polishing isn't just cosmetic—it tests architectural resilience.

The Battle for a Single Button (Skip Puzzle)

A bug requiring a week of debugging was identified. The issue stemmed from state interactions tied to the puzzle skip button. In the PuzzleActive state, the button should spawn a new blueprint, whereas in IntroNext, it should act as a pause toggle.

The logic kept failing because PuzzleManager lacked a reference to GameManager. The problem was resolved by injecting a direct reference and explicitly invoking SetState(GameState.PuzzleActive) upon starting a puzzle.

Lesson learned: even a minor UI feature can expose major architectural flaws.

Assets and Classes

Asset suites were prepared: game objects, backgrounds, UI panels, and buttons. Strict object naming conventions were given special priority. Instead of non-descript names like Game Background 1, a structured system was implemented: 1_Background_Start, 2_Background_Intro, 3_Background_Game, 4_Background_Final. A similar approach was applied to component parts (e.g., FinishedPart-1).

The initial class architecture was designed in Unity, establishing global and local managers and defining their interactions. The design process proceeded iteratively—moving from high-level entities to detailed subsystem implementations.

To freeze stable states and maintain rollback capabilities, a manual versioning system was established. Working builds were archived into separate directories (e.g., DRiot_v0.2), preserving the contents of Assets, Packages, and ProjectSettings.

Starting Point

Initial idea exploration for the first Unity project began. Pushing aside "dream game" concepts, a simple 2D puzzle direction was chosen instead. The theme crystallized almost immediately: a tech setting with robots, lasers, and resistance. The core mechanics were inspired by the classic 15-puzzle board game.

The gameplay concept took shape around assembling drones from schematics. On the game board, players reconstruct scrambled component blueprint fragments. To build a single combat drone, a full set of 6 distinct parts must be assembled, after which the drone automatically deals damage to the enemy Megacorporation.

With the core idea locked in, the process of drafting initial sketches and visual assets in Photoshop and Illustrator got underway.

Screenshot view