Noriegoh/Incode

Incode Documentation

Generated May 13, 2026View repository ↗

Project Documentation

🚀 1. Overview

Incode: A Built-in IDE for Unity

Project Overview

Incode is an integrated development environment (IDE) designed specifically for Unity, aiming to streamline the scripting and debugging workflow within the Unity Editor. Unlike external IDEs (e.g., Visual Studio, Rider), Incode embeds itself directly into Unity’s UIToolkit framework, providing a native, lightweight, and extensible development environment. The project is still in its early stages, with a phased roadmap outlined in docs/TestShellWorkbenchEvolutionPlan.md, which details plans to evolve the current "TestShell" into a modular, extensible workbench leveraging Unity’s UIToolkit for a modern, performant UI experience.

The core purpose of Incode is to reduce context-switching between Unity’s Inspector, Project Window, and an external IDE by providing a unified interface for scripting, debugging, and asset management. This is particularly valuable for Unity developers who frequently work with DAX (Data Analysis Expressions), a formula language used in Power BI and other Microsoft analytics tools. The inclusion of a DAX syntax highlighter (tm-grammars/Ignored/dax.json) suggests that Incode may also cater to developers working with data-driven applications in Unity, such as those using Unity for data visualization, business intelligence tools, or custom analytics dashboards.

Incode’s architecture appears to be modular, with a focus on extensibility. The presence of a tm-grammars directory (TextMate grammar files) indicates support for syntax highlighting across multiple languages, while the TestShellWorkbenchEvolutionPlan.md hints at a phased approach to integrating additional features like debugging tools, code navigation, and asset management. The project’s long-term vision seems to be transforming Unity’s default scripting workflow into a full-fledged, in-editor IDE experience.

Core Problem & Solution

The primary problem Incode solves is the fragmentation in Unity’s development workflow. Currently, Unity developers rely on external IDEs for scripting, debugging, and asset management, which introduces inefficiencies such as:

  • Context-switching overhead (switching between Unity Editor and an external IDE).
  • Lack of native Unity integration (e.g., no direct access to Unity’s API documentation, asset database, or scene hierarchy from the IDE).
  • Limited real-time debugging (debugging Unity scripts often requires manual log inspection or external tools).

Incode addresses these issues by:

  1. Embedding an IDE directly into Unity’s UIToolkit, reducing the need for external tools.
  2. Providing syntax highlighting for DAX and other languages, improving code readability for data-driven applications.
  3. Enabling modular extensibility, allowing developers to add custom tools (e.g., debugging, asset management) without leaving the Unity Editor.

Tech Stack at a Glance

CategoryTechnologyPurpose
Core FrameworkUnity EditorHost environment for the embedded IDE.
UI FrameworkUnity UIToolkitProvides the UI components and layout system for the IDE.
Syntax HighlightingTextMate Grammar (tmLanguage)Defines syntax rules for DAX and other languages (e.g., dax.json).
ScriptingC#Primary language for Unity development and IDE logic.
Planning DocsMarkdownDocumentation for project evolution (e.g., TestShellWorkbenchEvolutionPlan.md).
Version ControlGitSource control for tracking changes and collaboration.

Future Directions

While Incode is still in its early stages, the roadmap suggests a phased evolution toward a fully modular workbench. Key milestones likely include:

  • Phase 1: Basic script editing with syntax highlighting (DAX, C#).
  • Phase 2: Debugging integration (breakpoints, variable inspection).
  • Phase 3: Asset management (directly browsing/modifying Unity assets).
  • Phase 4: Extensibility (plugins for custom tools, language support).

The inclusion of DAX syntax support hints at a niche but growing use case: Unity for data-driven applications (e.g., interactive dashboards, analytics tools). If Incode matures, it could become a compelling alternative to external IDEs for Unity developers, particularly those working in business intelligence, finance, or custom analytics.

Would you like a deeper dive into any specific aspect of the project (e.g., architecture, syntax highlighting, or roadmap)?


📂 2. Project Structure

Directory Structure

The codebase contains the following primary files and directories:

  • .gitattributes
  • .gitignore
  • Editor.meta
  • Editor/Core.meta
  • Editor/Core/Commands.meta
  • Editor/Core/Commands/BuiltInCommandIds.cs
  • Editor/Core/Commands/BuiltInCommandIds.cs.meta
  • Editor/Core/Commands/CommandRegistry.cs
  • Editor/Core/Commands/CommandRegistry.cs.meta
  • Editor/Core/Commands/ContextKeyService.cs
  • Editor/Core/Commands/ContextKeyService.cs.meta
  • Editor/Core/Commands/KeybindingService.cs
  • Editor/Core/Commands/KeybindingService.cs.meta
  • Editor/Core/Commands/MenuRegistry.cs
  • Editor/Core/Commands/MenuRegistry.cs.meta
  • Editor/Core/Configuration.meta
  • Editor/Core/Configuration/BuiltInSettings.cs
  • Editor/Core/Configuration/BuiltInSettings.cs.meta
  • Editor/Core/Configuration/PreferenceValueDtos.cs
  • Editor/Core/Configuration/PreferenceValueDtos.cs.meta

Generated via local analysis.


🏗️ 3. Architecture & Data Flow

Incode Editor Architecture Deep Dive


1. Deep-Dive Architecture Reasoning

1.1 Overview: A Modular, Extensible IDE Core

The Incode Editor is a C#-based, Unity-integrated IDE designed to provide a modern, extensible, and performant code editing experience within the Unity Editor. It follows a modular architecture, separating concerns into distinct subsystems such as syntax highlighting, language services, commands, configuration, document management, and UI rendering.

The architecture is heavily inspired by VS Code’s design, particularly in its use of:

  • Extension-based extensibility
  • Language Server Protocol (LSP)-like services
  • Event-driven communication via an Event Bus
  • State management through services and registries

Despite being a Unity Editor tool, it avoids tight coupling to Unity’s UI system by abstracting UI rendering through UIToolkit, allowing for potential standalone use or portability.


1.2 Core Architectural Principles

PrincipleDescription
Separation of ConcernsEach subsystem (e.g., syntax, commands, configuration) is isolated into its own namespace and module.
Dependency Injection via RegistriesServices are registered and resolved via ServiceRegistry, LanguageServiceRegistry, etc., enabling loose coupling.
Event-Driven ArchitectureThe EventBus mediates all inter-module communication, enabling decoupled and reactive design.
Extensibility via ContributionsExtensions implement IExtension and contribute functionality via ExtensionContext.
Immutable State & Functional PatternsMany components (e.g., ImmutableScopeStack, PieceTable) use immutable data structures for thread safety and predictable state transitions.
Language Server Protocol (LSP) AnalogyLanguage services (e.g., ILanguageService, IExpressionEvaluator) mimic LSP behavior, enabling rich language features without tight coupling.

1.3 Module Interactions & Design Patterns

A. Command System (Editor/Core/Commands/)

  • Pattern: Command Pattern + Observer
  • Key Components:
    • CommandRegistry: Singleton registry of all commands.
    • KeybindingService: Maps key chords to command IDs.
    • ContextKeyService: Enables conditional command visibility based on editor state.
    • MenuRegistry: Builds UI menus (e.g., File, Edit) dynamically.
  • Interaction Flow:
    1. User presses Ctrl+S → KeybindingService resolves to BuiltInCommandIds.Save.
    2. CommandRegistry invokes the command handler.
    3. ContextKeyService checks if the command is enabled (e.g., "canSave" context).
    4. If enabled, the command executes (e.g., TextDocument.Save()).
  • Advanced Design:
    • Commands are contributed via extensions.
    • Uses delegates (Action<CommandContext>) for execution.
    • Supports menu contributions via MenuRegistry.

B. Document & Text Model (Editor/Core/Document/)

  • Pattern: Piece Table + Observer + Strategy
  • Key Components:
    • TextDocument: High-level document model.
    • PieceTable: Efficient immutable text buffer (inspired by VS Code).
    • PieceTree: Tree-based indexing for fast line/character lookups.
    • FindReplaceController: Handles search and replace.
    • FoldingController: Manages code folding regions.
  • Advanced Design:
    • PieceTable uses immutable segments to avoid copying large text.
    • Supports diffing via IDiffAlgorithm (e.g., MyersDiffAlgorithm).
    • TextEdit represents atomic edits (insert/delete/replace).
    • Event-driven: Fires TextChangedEvent, SavedEvent, etc.

C. Language Services (Editor/Core/LanguageServices/)

  • Pattern: Facade + Strategy + Observer
  • Key Components:
    • ILanguageService: Core interface for language features (completion, diagnostics, hover).
    • LanguageServiceRegistry: Registers language services by file extension.
    • DiagnosticsManager: Aggregates and displays errors/warnings.
    • IGhostTextProvider: Enables inline suggestions (e.g., AI-assisted code).
    • ReflectionEvaluator: Evaluates expressions in context (e.g., for hover tooltips).
  • Interaction Flow:
    1. User opens a .cs file → LanguageServiceRegistry resolves CSharpLanguageService.
    2. CSharpLanguageService registers completion, definition, and diagnostic providers.
    3. On typing, TextDocument fires TextChangedEvent → DiagnosticsManager triggers re-analysis.
    4. Results are published via EventBus → HoverWidget/CompletionWidget update.
  • Advanced Design:
    • Mimics Language Server Protocol (LSP) but runs in-process.
    • Supports async analysis via Task-based APIs.
    • Uses cancellation tokens to abort stale requests.

D. Syntax Highlighting (Editor/Core/Syntax/)

  • Pattern: Repository + State Machine
  • Key Components:
    • GrammarRegistry: Loads .tmLanguage.json files (TextMate grammars).
    • LexerManager: Manages lexers per language.
    • RegexLexer, IDocumentLexer: Tokenize text using regex or line-by-line.
    • TokenState: Tracks lexer state (e.g., in a string, comment, or code).
  • Advanced Design:
    • Uses Oniguruma regex engine (via Onigwrap) for high-performance pattern matching.
    • Supports stateful lexing (e.g., tracking scope in nested structures).
    • Tokens are immutable and cached for performance.
    • Themes are applied via ThemeManager (maps token types to colors).

E. Configuration & Preferences (Editor/Core/Configuration/)

  • Pattern: Registry + Strategy
  • Key Components:
    • PreferencesService: Centralized settings store.
    • SettingsRegistry: Registers settings (e.g., fontSize, theme).
    • SettingScope: Supports global, workspace, and user-level settings.
    • PreferenceValueDtos: Strongly typed settings.
  • Advanced Design:
    • Uses decorator pattern (SettingDescriptor) to define settings.
    • Supports live reload of settings.
    • Settings are serialized to JSON and persisted.

F. Event Bus & Main Thread Dispatcher (Editor/Core/Events/)

  • Pattern: Observer + Mediator
  • Key Components:
    • EventBus: Pub-sub system for inter-module communication.
    • MainThreadDispatcher: Ensures UI updates happen on the main thread.
  • Advanced Design:
    • Events are strongly typed (e.g., TextChangedEvent, ThemeChangedEvent).
    • Uses C# events under the hood but abstracted via EventBus.
    • Prevents race conditions by enforcing main-thread execution for UI updates.

G. Extensions System (Editor/Core/Extensions/)

  • Pattern: Plugin Architecture + Context Passing
  • Key Components:
    • IExtension: Base interface for extensions.
    • ExtensionHost: Loads and manages extensions.
    • ExtensionContext: Provides access to services (e.g., CommandRegistry, LanguageServiceRegistry).
  • Advanced Design:
    • Extensions are discoverable via *.incode.* assemblies.
    • Can contribute commands, language services, grammars, themes.
    • Example: incode.csharp extension registers C# language features and Roslyn-based analysis.

H. UI System (Editor/UI/)

  • Pattern: MVVM + Pooling + Dynamic Rendering
  • Key Components:
    • CodeEditorView: Main editor UI.
    • CompletionWidget, HoverWidget: Floating UI elements.
    • DynamicScrollView: Virtualized rendering for performance.
    • Pool<T>: Object pooling for UI elements (e.g., lines, tokens).
  • Advanced Design:
    • Uses UIToolkit (Unity’s retained-mode UI system).
    • Virtualization: Only renders visible lines.
    • Dirty tracking: Only updates changed UI elements.
    • Theme-aware: Applies colors from ThemeManager.

1.4 Integration with Unity Editor

  • The editor is embedded in Unity via IncodeEditorWindow.
  • Uses Unity’s Assembly Definition Files (asmdef) to isolate dependencies.
  • Editor-only code (no runtime impact).
  • Threading: Heavy computation (e.g., lexing, diagnostics) happens on background threads, with results marshaled to the main thread via MainThreadDispatcher.

1.5 Advanced Patterns & Techniques

Pattern/TechniqueUsage
Immutable Data StructuresPieceTable, ImmutableScopeStack, Token
Object PoolingPool<T> for UI elements and tokens
Strategy PatternIDiffAlgorithm, ILanguageService
Facade PatternTextDocument hides complexity of PieceTable
Observer PatternEventBus for decoupled communication
Registry PatternCommandRegistry, LanguageServiceRegistry
State PatternTokenState for lexer state
Dependency InjectionServices are resolved via registries
Cancellation & AsyncStale requests are cancelled
VirtualizationOnly visible lines are rendered

2. Data Flow & State Transitions

OriginActionLogic HandlerResulting State
UserPresses Ctrl+SKeybindingService → CommandRegistryCommand Save is triggered
CommandRegistryExecutes Save commandTextDocument.Save()Document is saved to disk
TextDocumentFires TextChangedEventEventBusSubscribers (e.g., DiagnosticsManager) are notified
DiagnosticsManagerRe-analyzes documentCSharpLanguageService (Roslyn)Diagnostics are updated
DiagnosticsManagerPublishes DiagnosticsUpdatedEventEventBusProblemsPanel updates UI
UserTypes in editorTextDocument → PieceTableText buffer is updated immutably
PieceTableFires TextChangedEventEventBusLexerManager is triggered
LexerManagerTokenizes textRegexLexer (Oniguruma)Tokens are generated and cached
LexerManagerPublishes TokensUpdatedEventEventBusSyntaxHighlighter updates UI
UserHovers over symbolHoverWidget requests infoCSharpLanguageService provides hover text
CSharpLanguageServiceEvaluates symbolReflectionEvaluatorHover tooltip is displayed
UserChanges themeThemeManager loads new themeUI colors are updated
ThemeManagerPublishes ThemeChangedEventEventBusAll UI elements re-render with new theme
ExtensionRegisters commandExtensionContext.RegisterCommand()Command is added to CommandRegistry
ExtensionRegisters language serviceExtensionContext.RegisterLanguageService()Language features are enabled for .cs files
PreferencesServiceSaves settingSettingsRegistry → JSON fileSetting persists across sessions

3. Mermaid.js Architecture Diagram


4. Summary: Why This Architecture Works

  • Modularity: Each subsystem is self-contained and testable.
  • Extensibility: New languages, commands, and themes can be added without modifying core code.
  • Performance: Immutability, pooling, and virtualization minimize overhead.
  • Maintainability: Clear separation of concerns and strong typing reduce bugs.
  • Unity Integration: Runs as an editor tool without runtime impact.

This architecture positions Incode as a modern, extensible IDE core that could even be adapted for standalone use outside Unity.

📈 System Architecture Diagram

Rendering diagram…

🛠️ 4. Function Breakdowns

Core Functionality

Based on the file tree, this project implements logic across 9 key source files including README.md, Editor/Core/Syntax/tm-grammars/Ignored/dax.json, Editor/Core/Syntax/tm-grammars/Ignored/cobol.json.

Generated via local analysis.