Integrated Coordinate and Transform Systems - bryanedds/Nu GitHub Wiki

Integrated Coordinate System & 2D/3D Transform Model

Overview

Nu Game Engine uses a unified transform system for both 2D and 3D entities. Unlike engines such as Unity or Godot—which maintain separate transform types for 2D and 3D—Nu intentionally avoids this separation to simplify the engine’s architecture and maintain a consistent entity pipeline across the entire stack.

This design choice can initially feel unfamiliar to developers coming from other engines, but it ultimately reduces complexity and avoids arbitrary distinctions between 2D and 3D entity types.


Virtual Resolution

Nu has a concept of virtual resolution. Virtual resolution represents the actual 2D coordinates of the display area, which is independent of window size. The resulting display resolution is defined as DisplayVirtualResolution * DisplayScalar, which default to [640 360] and 2, respectively. We chose this virtual resolution because it's a fraction of 1080, 1440, and 4k. Other than changing DisplayVirtualResolution, there's currently no way to change the aspect ratio.

Note that the resulting display resolution is also the default window size. When you resize the window in Nu, you're actually just changing the DisplayScalar.

You can change DisplayVirtualResolution and DisplayScalar in App.config like so -

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="DisplayVirtualResolution" value="[320 180]" />
    <add key="DisplayScalar" value="3" />
  </appSettings>
</configuration>

Currently, DisplayScalar can only be set to an integer value.


Unified Transform Model

Position as a Vector3

All entities in Nu—whether 2D or 3D—use a Vector3 for their Position field.

  • 2D entities:
    • Position.X and Position.Y are used normally
    • Position.Z is always 0
  • 3D entities:
    • All three components are used

This applies both to:

  • The entity’s transform, and
  • The model’s Position field

Using a Vector3 everywhere keeps the engine’s transform pipeline uniform and avoids branching logic based on dimensionality.


2D Coordinate System

2D Virtual Resolution

Nu’s 2D coordinate system does not map 1:1 to real pixels or physics meters. Instead, it uses said virtual resolution, which is then integer scaled by Constants.Render.DisplayScalar.

  • Default virtual resolution: 640 × 360
  • This acts as a common denominator for most landscape screens
  • Integer scaling is defined via Constants.Render.DisplayScalar

This ensures consistent layout and behavior across devices with different screen sizes.


2D Physics Units

Nu uses a virtual‑pixel‑to‑meter ratio for 2D physics:

  • 32 virtual pixels = 1 2D meter
  • This value can be changed at:
    Constants.Physics.Meter2d

This prevents unrealistic physics behavior that would occur if 1 pixel equaled 1 meter.


3D Coordinate System

The 3D coordinate system does map 1:1 to 3D meters.
There is no virtual scaling layer for 3D scenes.


Display Scaling & Form Factors

Nu currently supports one form factor per game, defined by:

  • Constants.Render.DisplayVirtualResolution

This means:

  • You choose a single virtual resolution for all targets
  • The engine scales it by Constants.Render.DisplayScalar

The default 640×360 resolution is chosen because it integer scales well on most landscape displays, including mobile.


Absolute vs. Relative Mouse Positioning

Nu provides a function to get the mouse position in 2D world space.
It includes an absolute parameter:

  • absolute = true

    • Mouse position is taken relative to the screen/UI
    • Used for UI elements that do not move with the camera
  • absolute = false

    • Mouse position is transformed into world space
    • Correct for gameplay interactions (e.g., player movement, aiming)

Using absolute = true for gameplay can cause issues such as:

  • Mouse distance from the player changing as the player moves
  • Movement thresholds shifting unexpectedly

Switching to absolute = false resolves these issues.


Summary

Nu’s integrated coordinate system is built around simplicity and consistency:

  • A single Vector3 transform model for both 2D and 3D
  • A virtual resolution for 2D rendering
  • A virtual‑pixel‑to‑meter ratio for 2D physics
  • A 1:1 meter system for 3D
  • A single form factor chosen per project
  • Clear distinction between absolute and world‑relative mouse coordinates

This unified approach reduces architectural complexity and keeps the engine’s design coherent across all dimensions.