---
title: "API Reference"
description: "Every public type and member in NeoGameLib 0.3.2, compact."
canonical_url: "https://docs.ctrl-neo.dev/en/neogamelib/api-reference"
---
# API Reference

Every public type in NeoGameLib 0.3.2, compact. Namespaces:

- `NeoGameLib` (root)
- `NeoGameLib.Common`
- `NeoGameLib.NeoGO`
- `NeoGameLib.NeoRendering`
- `NeoGameLib.NeoCollision`
- `NeoGameLib.NeoInput`
- `NeoGameLib.NeoUI` / `NeoGameLib.NeoUI.Elements`
- `NeoGameLib.NeoStorage`
- `NeoGameLib.FuckingEvents` (see [Systems](https://docs.ctrl-neo.dev/8.systems#eventbus-avoid))

## NeoGameLib

### class NeoGame : Game

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        NeoGame()
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Singleton
      </code>
    </td>
    
    <td>
      <code>
        static NeoGame? Singleton { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ViewportAspect
      </code>
    </td>
    
    <td>
      <code>
        float? { get; set; }
      </code>
      
       — viewport ratio or null; throws on non-positive/non-finite
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        LetterboxColor
      </code>
    </td>
    
    <td>
      <code>
        Color { get; set; } = Color.Black
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ClearColor
      </code>
    </td>
    
    <td>
      <code>
        Color { get; set; } = Color.CornflowerBlue
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GraphicsDeviceManager
      </code>
    </td>
    
    <td>
      <code>
        GraphicsDeviceManager { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        RenderBus
      </code>
    </td>
    
    <td>
      <code>
        NeoRenderBus { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ColliderBus
      </code>
    </td>
    
    <td>
      <code>
        NeoColliderBus { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        TimerBus
      </code>
    </td>
    
    <td>
      <code>
        NeoTimerBus { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        InputBus
      </code>
    </td>
    
    <td>
      <code>
        NeoInputBus { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        UIBus
      </code>
    </td>
    
    <td>
      <code>
        NeoUIBus { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        WorldManager
      </code>
    </td>
    
    <td>
      <code>
        WorldManager { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Assets
      </code>
    </td>
    
    <td>
      <code>
        AssetManager { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GraphicsViewport
      </code>
    </td>
    
    <td>
      <code>
        Viewport { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        WindowMode
      </code>
    </td>
    
    <td>
      <code>
        NeoWindowMode { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ViewportBounds
      </code>
    </td>
    
    <td>
      <code>
        Rectangle { get; }
      </code>
      
       — window-pixel draw box
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GetScreenCenterCoords()
      </code>
    </td>
    
    <td>
      <code>
        Vector2
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        SetWindowMode(NeoWindowMode mode)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      hooks
    </td>
    
    <td>
      <code>
        protected virtual OnInitialize() / OnLoadContent(ContentManager) / OnUpdate(GameTime) / OnDraw(SpriteBatch, GameTime) / OnDrawUI(SpriteBatch, GameTime)
      </code>
    </td>
  </tr>
</tbody>
</table>

### class NeoGame<T> : NeoGame where T : NeoGame<T>

`public new static T Singleton { get; }`

### enum NeoWindowMode

`Windowed`, `Fullscreen`, `BorderlessFullscreen`

## NeoGameLib.Common

### class NeoTimer

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        NeoTimer(float duration)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Duration
      </code>
    </td>
    
    <td>
      <code>
        float { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        TimeLeft
      </code>
    </td>
    
    <td>
      <code>
        float { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsRunning
      </code>
      
       / <code>
        IsPaused
      </code>
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OnStart
      </code>
      
       / <code>
        OnStop
      </code>
      
       / <code>
        OnPause
      </code>
      
       / <code>
        OnResume
      </code>
      
       / <code>
        OnFinished
      </code>
    </td>
    
    <td>
      <code>
        Action
      </code>
      
       fields
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Start()
      </code>
      
       / <code>
        Stop()
      </code>
      
       / <code>
        Pause()
      </code>
      
       / <code>
        Resume()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
</tbody>
</table>

### class NeoTimerBus : NeoBus<NeoTimer>

`void Update(GameTime gameTime)`

### abstract class NeoBus<T>

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Add(T item)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — skips existing
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Remove(T item)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Count
      </code>
    </td>
    
    <td>
      <code>
        int
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Contains(T item)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        RemoveAll(Predicate<T> match)
      </code>
    </td>
    
    <td>
      <code>
        int
      </code>
    </td>
  </tr>
</tbody>
</table>

### readonly struct PassSnapshot<T> : IDisposable

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        PassSnapshot(IReadOnlyList<T> list)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Count
      </code>
    </td>
    
    <td>
      <code>
        int
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      indexer
    </td>
    
    <td>
      <code>
        T this[int index]
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Dispose()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — returns the rented array to the pool
    </td>
  </tr>
</tbody>
</table>

### abstract class NeoSingleton<T> where T : NeoSingleton<T>

`public static T Singleton { get; }` — ctor throws if a second instance is made.

### class NeoMover : NeoComponent

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        KeyUp
      </code>
      
       / <code>
        KeyDown
      </code>
      
       / <code>
        KeyLeft
      </code>
      
       / <code>
        KeyRight
      </code>
      
       / <code>
        KeyJump
      </code>
    </td>
    
    <td>
      <code>
        null
      </code>
    </td>
    
    <td>
      <code>
        Keys?
      </code>
      
       fields
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Speed
      </code>
    </td>
    
    <td>
      200
    </td>
    
    <td>
      <code>
        float
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Gravity
      </code>
    </td>
    
    <td>
      2000
    </td>
    
    <td>
      <code>
        float
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        JumpVelocity
      </code>
    </td>
    
    <td>
      600
    </td>
    
    <td>
      <code>
        float
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Omnidirectional
      </code>
    </td>
    
    <td>
      true
    </td>
    
    <td>
      <code>
        bool
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        UseLerp
      </code>
    </td>
    
    <td>
      true
    </td>
    
    <td>
      <code>
        bool
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        LerpSnappiness
      </code>
    </td>
    
    <td>
      10
    </td>
    
    <td>
      <code>
        float
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GroundComponentType
      </code>
    </td>
    
    <td>
      <code>
        null
      </code>
    </td>
    
    <td>
      <code>
        Type
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Grounded
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CollisionWhitelist
      </code>
      
       / <code>
        CollisionBlacklist
      </code>
    </td>
    
    <td>
      empty
    </td>
    
    <td>
      <code>
        List<Type> { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Velocity
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        Vector2 { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Move(Vector2 direction)
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Jump()
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — only grounded
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddImpulse(Vector2 impulse)
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddToWhitelist<T>()
      </code>
      
       / <code>
        RemoveFromWhitelist<T>()
      </code>
      
       / <code>
        AddToBlacklist<T>()
      </code>
      
       / <code>
        RemoveFromBlacklist<T>()
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        void
      </code>
      
       where T : NeoComponent
    </td>
  </tr>
</tbody>
</table>

### class AssetManager

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Load<T>(string path, bool forceLoad = false)
      </code>
    </td>
    
    <td>
      <code>
        T
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Unload(string path)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — disposes if <code>
        IDisposable
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        UnloadAll()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
</tbody>
</table>

### enum Direction2D

`Left`, `Right`, `Up`, `Down`

### static class Direction2DExtensions

`ToVector2(this Direction2D) : Vector2`, `Invert(this Direction2D) : Direction2D`

### enum PlayerControlsKeyboardMode

`WASDF`, `UHJKL`, `ArrowsShift` — defined, not used anywhere in the library.

## NeoGameLib.NeoGO

### class NeoObject

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctors
    </td>
    
    <td>
      <code>
        (string name)
      </code>
      
      , <code>
        (Transform transform)
      </code>
      
      , <code>
        (string name, Transform transform)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Name
      </code>
    </td>
    
    <td>
      <code>
        string { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Transform
      </code>
    </td>
    
    <td>
      <code>
        Transform { get; set; }
      </code>
      
       — setter copies fields
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Components
      </code>
    </td>
    
    <td>
      <code>
        List<NeoComponent> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        World
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld { get; internal set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsDestroyed
      </code>
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddComponent<T>()
      </code>
      
       / <code>
        AddComponent<T>(T component)
      </code>
    </td>
    
    <td>
      <code>
        T
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GetComponent<T>()
      </code>
    </td>
    
    <td>
      <code>
        T
      </code>
      
       (null if absent)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        TryGetComponent<T>(out T)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        HasComponent<T>()
      </code>
      
       / <code>
        HasComponent(Type)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        RemoveComponent(NeoComponent)
      </code>
      
       / <code>
        RemoveComponent<T>()
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OnInstantiate()
      </code>
    </td>
    
    <td>
      <code>
        virtual void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        DestroyToQueue()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        DestroyImmediate()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Tick(GameTime)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       (called by the world)
    </td>
  </tr>
</tbody>
</table>

### abstract class NeoComponent

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ParentObject
      </code>
    </td>
    
    <td>
      <code>
        NeoObject { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ParentTransform
      </code>
    </td>
    
    <td>
      <code>
        Transform { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ParentWorld
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Assets
      </code>
      
       / <code>
        WorldManager
      </code>
      
       / <code>
        RenderBus
      </code>
      
       / <code>
        ColliderBus
      </code>
      
       / <code>
        TimerBus
      </code>
      
       / <code>
        InputBus
      </code>
    </td>
    
    <td>
      manager shorthands (<code>
        null
      </code>
      
       before game init)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Enabled
      </code>
    </td>
    
    <td>
      <code>
        bool { get; set; }
      </code>
      
       = true
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsAttached
      </code>
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        HasRanOnStart
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
      
       field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OnAwake()
      </code>
      
       / <code>
        OnStart()
      </code>
      
       / <code>
        OnUpdate(GameTime)
      </code>
      
       / <code>
        OnDestroy()
      </code>
    </td>
    
    <td>
      <code>
        virtual void
      </code>
    </td>
  </tr>
</tbody>
</table>

### class NeoWorld

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        (string name)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Name
      </code>
    </td>
    
    <td>
      <code>
        string { get; internal set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Objects
      </code>
    </td>
    
    <td>
      <code>
        List<NeoObject> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Instantiate(string name)
      </code>
    </td>
    
    <td>
      <code>
        NeoObject
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Instantiate(string name, Vector2 position)
      </code>
    </td>
    
    <td>
      <code>
        NeoObject
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Instantiate(string name, Transform transform)
      </code>
    </td>
    
    <td>
      <code>
        NeoObject
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Instantiate<T>(T obj)
      </code>
      
       / <code>
        (T obj, Vector2)
      </code>
      
       / <code>
        (T obj, Transform)
      </code>
    </td>
    
    <td>
      <code>
        T where T : NeoObject
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Destroy(NeoObject obj)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       (queued)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Update(GameTime)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Clear()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — destroy all objects now
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FindObjectByHashCode(int)
      </code>
      
       / <code>
        FindObjectByComponent<T>()
      </code>
      
       / <code>
        FindObjectByName(string)
      </code>
    </td>
    
    <td>
      <code>
        NeoObject?
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FindObjectsByName(string)
      </code>
      
       / <code>
        FindObjectsByComponent<T>()
      </code>
    </td>
    
    <td>
      <code>
        List<NeoObject>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FindComponent<T>()
      </code>
    </td>
    
    <td>
      <code>
        T
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FindComponents<T>()
      </code>
    </td>
    
    <td>
      <code>
        List<T>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        TryFind...
      </code>
      
       variants of the above
    </td>
    
    <td>
      <code>
        bool
      </code>
      
       + <code>
        out
      </code>
    </td>
  </tr>
</tbody>
</table>

### class WorldManager

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        LoadedWorlds
      </code>
    </td>
    
    <td>
      <code>
        List<NeoWorld> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CreateWorld(string name, Action<NeoWorld> build = null)
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld
      </code>
      
       — throws on duplicate
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CreateWorld(NeoWorld world, Action<NeoWorld> build = null)
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Load(string name)
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Unload(string name)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        UnloadAll()
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GetWorld(string name)
      </code>
      
       / <code>
        this[string name]
      </code>
      
       / <code>
        TryGetWorld(string, out NeoWorld)
      </code>
    </td>
    
    <td>
      <code>
        NeoWorld
      </code>
      
       / <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsLoaded(string name)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        RenameWorld(string name, string newName)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GroupCollisions(string groupName, params string[] worldNames)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        UngroupCollisions(string worldName)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Update(GameTime)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
</tbody>
</table>

### class Transform

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctors
    </td>
    
    <td>
      <code>
        ()
      </code>
      
      , <code>
        (Vector2 pos, float rot = 0)
      </code>
      
      , <code>
        (Vector2 pos, Vector2 scale)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Position
      </code>
    </td>
    
    <td>
      <code>
        Vector2 { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Rotation
      </code>
    </td>
    
    <td>
      <code>
        float { get; set; }
      </code>
      
       (radians)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Scale
      </code>
    </td>
    
    <td>
      <code>
        Vector2 { get; set; }
      </code>
      
       = (1,1)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Up
      </code>
      
       / <code>
        Down
      </code>
      
       / <code>
        Right
      </code>
      
       / <code>
        Left
      </code>
    </td>
    
    <td>
      <code>
        Vector2 { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Move(Vector2 direction, GameTime)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FaceTowards(Direction2D side, Vector2 | Transform | NeoObject target)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
</tbody>
</table>

## NeoGameLib.NeoRendering

### class NeoRenderBus

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        (GraphicsDeviceManager)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GraphicsViewport
      </code>
    </td>
    
    <td>
      <code>
        Viewport { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Cameras
      </code>
    </td>
    
    <td>
      <code>
        IReadOnlyList<NeoCamera> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        MainCamera
      </code>
    </td>
    
    <td>
      <code>
        NeoCamera { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        HasAnyCamera
      </code>
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ViewMatrix
      </code>
    </td>
    
    <td>
      <code>
        Matrix { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        WorldToScreen(Vector2 world)
      </code>
    </td>
    
    <td>
      <code>
        Vector2
      </code>
      
       — window pixels, main camera
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ScreenToWorld(Vector2 screen)
      </code>
    </td>
    
    <td>
      <code>
        Vector2
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Draw(SpriteBatch)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — identity pass
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Draw(SpriteBatch, NeoCamera)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — camera pass (culling mask)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddSprite
      </code>
      
       / <code>
        RemoveSprite
      </code>
      
       / <code>
        AddText
      </code>
      
       / <code>
        RemoveText
      </code>
    </td>
    
    <td>
      registration plumbing; renderers self-register in <code>
        OnAwake
      </code>
      
      , no manual calls needed
    </td>
  </tr>
</tbody>
</table>

### class NeoSpriteRenderer : NeoComponent

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        (NeoRenderBus bus, Texture2D? texture = null)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Texture
      </code>
    </td>
    
    <td>
      null
    </td>
    
    <td>
      <code>
        Texture2D { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        SourceRectangle
      </code>
    </td>
    
    <td>
      null
    </td>
    
    <td>
      <code>
        Rectangle? { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Color
      </code>
    </td>
    
    <td>
      White
    </td>
    
    <td>
      <code>
        Color { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Depth
      </code>
    </td>
    
    <td>
      0
    </td>
    
    <td>
      <code>
        float { get; set; }
      </code>
      
       — higher = behind
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Anchor
      </code>
    </td>
    
    <td>
      (0.5, 0.5)
    </td>
    
    <td>
      <code>
        Vector2 { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Order
      </code>
    </td>
    
    <td>
      auto
    </td>
    
    <td>
      <code>
        int { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Layer
      </code>
    </td>
    
    <td>
      1
    </td>
    
    <td>
      <code>
        int { get; set; }
      </code>
      
       — culling bitmask
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Bounds
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        Rectangle { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ScreenBounds
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        Rectangle { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        WithinViewportBounds
      </code>
      
       / <code>
        VisibleInViewportBounds
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsOverWindowBounds(Direction2D)
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        virtual bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ContainsScreenPoint(Vector2)
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsCursorOnSprite()
      </code>
    </td>
    
    <td>
      
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
</tbody>
</table>

### class NeoCamera : NeoComponent

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        (NeoRenderBus bus)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Zoom
      </code>
    </td>
    
    <td>
      <code>
        float { get; set; }
      </code>
      
       = 1 — invalid values rejected silently
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Order
      </code>
    </td>
    
    <td>
      <code>
        int { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CullingMask
      </code>
    </td>
    
    <td>
      <code>
        int { get; set; }
      </code>
      
       = -1
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GetViewMatrix(Viewport)
      </code>
    </td>
    
    <td>
      <code>
        Matrix
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        WorldToScreen(Vector2, Viewport)
      </code>
      
       / <code>
        ScreenToWorld(Vector2, Viewport)
      </code>
    </td>
    
    <td>
      <code>
        Vector2
      </code>
      
       — viewport-local
    </td>
  </tr>
</tbody>
</table>

### class NeoTextRenderer : NeoComponent

`ctor(NeoRenderBus bus, SpriteFont? font = null)`; `Font`, `Text` ("")
`Color` (White), `Depth` (0), `Anchor` (0.5,0.5), `Order` (auto), `Layer` (1).

### class NeoAnimation

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        (List<Rectangle> frames, float frameDuration, bool loop = true, bool holdLastFrame = true)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Frames
      </code>
    </td>
    
    <td>
      <code>
        List<Rectangle> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FrameDuration
      </code>
    </td>
    
    <td>
      <code>
        float { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Loop
      </code>
      
       / <code>
        HoldLastFrame
      </code>
    </td>
    
    <td>
      <code>
        bool { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FromGrid(...)
      </code>
    </td>
    
    <td>
      <code>
        static NeoAnimation FromGrid(Point gridSize, Point cellSize, float frameDuration, bool loop = true, Direction2D horizontal = Right, Direction2D vertical = Down, Point padding = default, Point margin = default, bool horizontalFirst = true, bool holdLastFrame = true)
      </code>
    </td>
  </tr>
</tbody>
</table>

### class NeoAnimator : NeoComponent

`Play(NeoAnimation)`, `Stop()`, `OnAnimationFinished` (`Action`),
`CurrentFrameIndex` (`int { get; }`). Requires a `NeoSpriteRenderer` on the
same object (throws in `OnAwake` otherwise); null/empty animation throws in
`Play`.

### abstract class NeoSpriteRenderFeature : NeoComponent

`Renderer` (`NeoSpriteRenderer { get; }`);
`virtual OnDrawBehind(SpriteBatch, in NeoSpriteDrawInfo)`,
`virtual OnDrawFront(SpriteBatch, in NeoSpriteDrawInfo)`,
`protected virtual OnFeatureAwake()`, `protected virtual OnFeatureDestroy()`.
Requires a `NeoSpriteRenderer` on the same object (throws otherwise).

### readonly struct NeoSpriteDrawInfo

`Texture`, `SourceRectangle`, `Position`, `Color`, `Rotation`, `Origin`,
`Scale`, `Effects`, `Depth` (all get-only);
`void Draw(SpriteBatch, Texture2D, Color, Vector2 offset = default)`.

### class NeoOutlineFeature : NeoSpriteRenderFeature

`Color` (White), `Thickness` (2f, world pixels). Needs a non-compressed
`SurfaceFormat.Color` texture for the silhouette.

## NeoGameLib.NeoCollision

### class NeoBoxCollider : NeoComponent

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Offset
      </code>
    </td>
    
    <td>
      (0, 0)
    </td>
    
    <td>
      <code>
        Vector2 { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Size
      </code>
    </td>
    
    <td>
      (1, 1)
    </td>
    
    <td>
      <code>
        Vector2 { get; set; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Bounds
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      <code>
        virtual Rectangle { get; }
      </code>
      
       — world-space, scale-aware, rotation ignored
    </td>
  </tr>
</tbody>
</table>

### class NeoSpriteCollider : NeoBoxCollider

`override Rectangle Bounds` — the sprite renderer's bounds on the same object
(empty without one).

### class NeoColliderBus : NeoBus<NeoBoxCollider>

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ctor
    </td>
    
    <td>
      <code>
        (WorldManager? worldManager = null)
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Collisions
      </code>
    </td>
    
    <td>
      <code>
        List<NeoCollision> { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Colliders
      </code>
    </td>
    
    <td>
      <code>
        List<NeoBoxCollider> { get; }
      </code>
      
       — live registered list
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Update()
      </code>
    </td>
    
    <td>
      <code>
        List<NeoCollision>
      </code>
      
       — detect pairs, fire callbacks
    </td>
  </tr>
</tbody>
</table>

### class NeoCollision

`NeoBoxCollider A`, `NeoBoxCollider B`, `Rectangle Overlap` (public fields).

### interface ICollision

`void OnCollision(NeoBoxCollider other, NeoCollision collision)`

## NeoGameLib.NeoInput

### class NeoInputBus : NeoBus<NeoInputMap>

`void Update()`; `void Update(KeyboardState current)`;
`void Update(KeyboardState current, MouseState mouse)`;
`Keys[] ListenInput()`.

### class NeoInputMap

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        AddDigital(string action, params Keys[] keys)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddMouseButton(string action, params MouseButtons[] buttons)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AddAxis(string action, NeoAxisRange range, Keys? positive = null, Keys? negative = null)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        SetAction(string action, params Keys[] keys)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — throws if unknown
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        SetAction(string action, NeoAxisRange range, Keys? positive = null, Keys? negative = null)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
      
       — throws if unknown
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        HasAction(string)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        RemoveAction(string)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        IsDown(string)
      </code>
      
       / <code>
        IsPressed(string)
      </code>
      
       / <code>
        IsReleased(string)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
      
       — throws if unknown
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GetAxis(string)
      </code>
    </td>
    
    <td>
      <code>
        float
      </code>
      
       — throws if unknown
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Subscribe(NeoInputBus? bus = null, bool dedupe = true)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Unsubscribe(NeoInputBus? bus = null, bool dedupe = true)
      </code>
    </td>
    
    <td>
      <code>
        void
      </code>
    </td>
  </tr>
</tbody>
</table>

### static class Input

`LeftMouseButton` / `MiddleMouseButton` / `RightMouseButton` / `XButton1` /
`XButton2` (`NeoMouseAction`), `MousePosition` (`Vector2`, window pixels).

### sealed class NeoMouseAction

`bool IsDown()`, `bool IsPressed()`, `bool IsReleased()`.

### enum NeoAxisRange

`Positive` (0→1), `Negative` (0→-1), `Full` (-1→1),
`PositiveInverted` (1→0), `NegativeInverted` (-1→0), `FullInverted` (1→-1).

### enum MouseButtons

`Left`, `Middle`, `Right`, `XButton1`, `XButton2`

## NeoGameLib.NeoUI

### sealed class NeoUIBus : IDisposable

`Count`, `Contains(NeoCanvas)`,
`void Add(NeoCanvas canvas, bool dedupe = true)`,
`void Remove(NeoCanvas canvas, bool dedupe = true)`, `void Clear()`,
`void Update(GameTime, Rectangle viewport)`, `void Draw(SpriteBatch)`,
`void Dispose()`.

### class NeoUIElement

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Signature
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Children
      </code>
    </td>
    
    <td>
      <code>
        NeoUIChildren { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Parent
      </code>
    </td>
    
    <td>
      <code>
        NeoUIElement? { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Transform
      </code>
    </td>
    
    <td>
      <code>
        ScreenTransform { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Enabled
      </code>
      
       / <code>
        Visible
      </code>
    </td>
    
    <td>
      <code>
        bool { get; set; }
      </code>
      
       = true
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        VisualMatrix
      </code>
    </td>
    
    <td>
      <code>
        Matrix { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        Canvas
      </code>
    </td>
    
    <td>
      <code>
        NeoCanvas? { get; }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ScreenToLocal(Vector2)
      </code>
    </td>
    
    <td>
      <code>
        Vector2
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ContainsScreenPoint(Vector2)
      </code>
    </td>
    
    <td>
      <code>
        bool
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OnUpdate(GameTime)
      </code>
    </td>
    
    <td>
      <code>
        virtual void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        OnDraw(SpriteBatch)
      </code>
    </td>
    
    <td>
      <code>
        protected virtual void
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        MeasureContent()
      </code>
    </td>
    
    <td>
      <code>
        protected virtual Vector2
      </code>
    </td>
  </tr>
</tbody>
</table>

### sealed class NeoUIChildren : Collection<NeoUIElement>

Collection with validation: no canvases as children, no double-parenting, no
cycles. Safe to mutate during UI traversal.

### class ScreenTransform : Transform

`Size` (0,0), `Anchor` (0.5, 0.5), `Pivot` (0.5, 0.5),
`WidthMode` / `HeightMode` (`NeoUISizing`, `Fixed`),
`DesiredSize` / `LayoutPosition` / `LayoutSize` (read-only),
`HasVisualTransform` (`bool { get; }`). Throws on non-finite sizes and
anchors/pivots outside 0..1.

### enum NeoUISizing

`Fixed`, `Fill`, `Fit`

### class NeoCanvas : NeoUIElement

`Order` (0), `ScaleMode` (`ConstantPixelSize`), `ScaleFactor` (1),
`ReferenceResolution` (1280x720), `Match` (0, must be 0..1), `PixelPerfect`
(false), `Scale` (`float { get; }`), `ViewportOrigin` (`Vector2 { get; }`),
`Bus` (`NeoUIBus? { get; }`), `ScreenToCanvas(Vector2)`,
`CanvasToScreen(Vector2)`, `Subscribe(NeoUIBus? bus = null, bool dedupe = true)`,
`Unsubscribe(NeoUIBus? bus = null, bool dedupe = true)`.

### enum NeoCanvasScaleMode

`ConstantPixelSize`, `ScaleWithScreen`

### class NeoPanel : NeoUIElement

`Color` (White), `Padding` (`NeoPadding`).

### class NeoFlexBox : NeoPanel

`Direction` (`Row`), `Gap` (0), `Justify` (`Start`), `Align` (`Start`).

### enum NeoFlexDirection

`Row`, `Column`

### enum NeoFlexAlign

`Start`, `Center`, `End`, `SpaceBetween`, `Stretch`

### class NeoLabel : NeoUIElement

`Font` (null), `Text` (""), `Color` (White). Defaults to `Fit` sizing.

### class NeoButton : NeoUIElement

`Font`, `Text`, `Color` (White), `HoverColor` (LightGray),
`PressedColor` (Gray), `Hovered` (`bool { get; }`), `OnClick` (`Action?`).
Defaults to `Fit` sizing. Fires on press+release over the button.

### class NeoImage : NeoUIElement

`Texture` (null), `Color` (White), `SourceRectangle` (`Rectangle?`, validated
non-negative).

### readonly struct NeoPadding

ctors `(all)`, `(horizontal, vertical)`, `(left, top, right, bottom)`;
`Left` / `Top` / `Right` / `Bottom` (init-only, non-negative, finite);
`TopLeft : Vector2`, `Total : Vector2`; `implicit operator NeoPadding(float)`.

## NeoGameLib.NeoStorage

### class FileStore

`FilePath` (`string { get; }`); `virtual Load()`, `Get()` (`string`),
`GetAsLines()` (`List<string>`), `Set(string)`, `Set(List<string>)`,
`virtual Write()`.

### class JsonStore : FileStore

`Options` (`JsonSerializerOptions`, default `IncludeFields = true`);
`override Load()`, `override Write()`, `Get<T>(string key)`,
`Set(string key, object value)`.

### class FolderStore

`FolderPath` (`string { get; }`), `Files` (`List<string> { get; }`),
`Load()`, `Instantiate<T>(string fileName) : T where T : FileStore`.

## NeoGameLib.FuckingEvents

### class EventBus

`void Subscribe<T>(Action<T> handler)`, `void Publish<T>(T eventData)`.
No unsubscribing. Not used by the library; see
[Systems](https://docs.ctrl-neo.dev/8.systems#eventbus-avoid).


## Sitemap

See the full [sitemap](https://docs.ctrl-neo.dev/sitemap.md) for all pages.
