22-02-2026_remove_engine_abstractions

since i go full Unity now … should I remove all the engine agnostic abstractions? or just bypass them for the new blocks (avoids creating engine-agnostic types)


Engine Abstraction Decision

Keep the abstraction layer, but make it pragmatic.

Here’s why:

Don’t Remove It:

  1. Sunk cost is minimal - abstraction already exists, works
  2. Future optionality - if Unity Asset Store fails, Godot pivot is still possible (Month 10-12 decision point)
  3. Marketing angle - “Cross-engine DSL” is unique, even if you only sell Unity version initially
  4. Code isolation - keeps Unity-specific messiness out of your core API design
  5. Testing - can unit test blocks without Unity runtime

But Bypass Strategically:

For new blocks in Weeks 1-2, use this decision tree:

Is this block wrapping Unity-specific API? (Rigidbody, NavMesh, specific UI Toolkit)
├─ YES → Direct Unity types, no abstraction
│   Examples: 
│   - Rigidbody.AddForce (Unity physics-specific)
│   - UI.BindVariable (Unity UI Toolkit specific)
│   - NavMesh.SetDestination (Unity NavMesh)
│
└─ NO → Use abstraction (Transform, Vector3, Collider concepts exist everywhere)
    Examples:
    - Transform.SetPosition (universal concept)
    - Collision.OnEnter (universal concept)
    - Audio.PlaySFX (universal concept)

Practical Implementation:

Week 1-2 blocks - Keep abstracted:

// These concepts are universal
Transform.SetPosition(IVector3 position)
Collision.OnEnter(ICollider collider)
Health.TakeDamage(float amount)
Audio.PlaySFX(string clipName)
Spatial.FindClosest(string tag)

Week 3+ blocks - Direct Unity (if needed):

// Unity-specific, no Godot equivalent
Rigidbody.AddForce(Vector3 force, ForceMode mode)
UI.SetUIDocument(UIDocument doc)
NavMesh.SetDestination(Vector3 target)

Hybrid API Pattern:

You can expose both:

// In Transform API
public TransformBlock SetPosition(IVector3 pos) => ... // abstracted
public TransformBlock SetPosition(Vector3 pos) => SetPosition(pos.ToIVector3()); // convenience overload

// In Collision API
public CollisionBlock OnEnter(ICollider collider) => ... // abstracted
public CollisionBlock OnEnter(Collider collider) => ... // Unity direct (optional)

Users get IntelliSense for Unity types, but your core uses abstractions.

Migration Path:

Now (Weeks 1-2):

Weeks 3-5 (Advanced features):

Post-launch (if Godot pivot needed):

What This Looks Like:

// Your API surface (Script.cs)
public TransformApi Transform => new(this); // abstracted
public ObjectApi Object => new(this); // abstracted
public HealthApi Health => new(this); // abstracted
public CollisionApi Collision => new(this); // abstracted

// Unity-specific APIs
public UnityPhysicsApi UnityPhysics => new(this); // direct Unity types
public UnityUIApi UnityUI => new(this); // direct Unity types
public UnityNavMeshApi UnityNavMesh => new(this); // direct Unity types

// Future: GodotPhysicsApi, GodotUIApi, etc.

Revenue Impact:

If you keep abstraction:

If you remove abstraction:

My Recommendation:

Keep the abstraction for blocks you’re building in Weeks 1-2 (the ~100 high-priority blocks). They’re:

Skip abstraction for Unity-specific features (NavMesh, specific physics modes, UI Toolkit bindings, Animator, etc.).

Rationale:

Estimated time saved by removing abstraction entirely: 20-30 hours over 8 weeks Risk if Asset Store fails and you need Godot pivot: 200+ hours of rework

The optionality is worth keeping. You’re solo with 12-18 month runway - preserve flexibility.