Coordinate Systems in Game Development
Cartesian Coordinates
Cartesian coordinates use perpendicular axes (x, y in 2D; x, y, z in 3D) where each point is specified by its distance along each axis from the origin. This is the default coordinate system for virtually all game math, physics, and rendering. Addition, subtraction, and the other vector operations all assume Cartesian coordinates.
The orientation of axes varies between systems, which is a constant source of confusion. In mathematics and many game engines, y points up and x points right. In screen coordinates (Canvas, DOM, most 2D game frameworks), y points down and x points right. In 3D engines, the choice between y-up and z-up conventions differs: Three.js uses y-up (matching OpenGL), Unreal Engine uses z-up (matching architectural convention), and Babylon.js uses y-up with a left-handed system (z goes into the screen instead of out of it).
Left-handed vs right-handed coordinate systems differ in the direction of the z-axis relative to x and y. In a right-handed system (Three.js, OpenGL), if you point your right hand's fingers from x toward y, your thumb points along positive z (out of the screen). In a left-handed system (Babylon.js, DirectX), the same gesture with your left hand gives z pointing into the screen. The practical difference is that rotation direction and cross product sign are reversed. Objects that rotate clockwise in one system rotate counterclockwise in the other.
Screen Space
Screen space uses pixel coordinates with (0, 0) at the top-left corner of the canvas or viewport. The x-axis increases to the right, and the y-axis increases downward. This is the coordinate system of the browser DOM, Canvas 2D, mouse events, and touch events. Screen space coordinates are what the player actually sees: the pixel position of elements on their display.
Canvas dimensions and CSS dimensions can differ. A canvas with CSS width of 800px might have an internal resolution (canvas.width) of 1600 for high-DPI displays. Mouse coordinates from events are in CSS pixels, so you must scale by the ratio of canvas.width to the canvas's CSS client width to get the correct canvas-space coordinates. Forgetting this scaling is a common bug on Retina and high-DPI displays where clicks appear offset from their visual targets.
Converting from screen space to a game's world space requires knowing the camera's position and zoom level. For a 2D game with a scrolling camera: worldX = screenX / zoom + cameraX and worldY = screenY / zoom + cameraY. The inverse (world to screen) is: screenX = (worldX - cameraX) * zoom and screenY = (worldY - cameraY) * zoom. This conversion is essential for mouse interaction: when the player clicks at screen position (400, 300), you need to know which world-space tile, entity, or button they targeted.
World Space
World space is the global coordinate system of your game's environment. All objects have a position in world space. Physics calculations happen in world space. Distance checks, visibility tests, and spatial queries operate in world space. The origin is arbitrary: some games place it at the center of the map, others at one corner, and others at the player's spawn point.
For large game worlds, floating-point precision becomes a concern far from the origin. At coordinates like (1,000,000, 500,000), a 32-bit float can only represent positions to the nearest 0.06 units, which causes visible jittering. Solutions include origin rebasing (periodically moving the world origin to the player's current position and adjusting all other positions), double-precision coordinates for physics, or chunked coordinate systems where each chunk has its own local origin. Most web games do not encounter this problem because their worlds are much smaller, but it is worth knowing about for large-scale or procedurally infinite games.
Model Space (Local Space)
Model space (also called local space or object space) is the coordinate system centered on an individual object's origin. A character model's vertices are defined relative to the model's own center point. A car's wheels are positioned relative to the car's origin. When you rotate an object, it rotates around its model-space origin.
The model matrix (also called the world matrix) transforms points from model space to world space. It encodes the object's position, rotation, and scale in the world. Every renderable object has a model matrix, and the rendering pipeline multiplies each vertex by this matrix to compute its world-space position.
Choosing a good model-space origin matters for gameplay. For characters, the origin is typically at the feet (for ground alignment) or at the center of mass (for physics). For rotating objects like turrets, the origin should be at the pivot point. For UI elements, the origin is typically at the center (for centered scaling) or top-left corner (for alignment). An incorrectly placed origin causes objects to rotate, scale, or align from an unexpected point, which is one of the most common "it looks wrong" problems in game development.
View Space and Projection
View space (camera space, eye space) positions everything relative to the camera. The camera sits at the origin of view space, looking along the negative z-axis (in right-handed systems) or positive z-axis (left-handed). The view matrix, which is the inverse of the camera's model matrix, transforms world-space positions into view space. Objects in front of the camera have positive depth values; objects behind it have negative values.
The projection matrix transforms view-space positions into clip space, a normalized coordinate system where visible points fall within a specific range. Perspective projection makes distant objects smaller by dividing x and y by z (the perspective divide). The field of view angle controls how much of the scene is visible: 60 degrees produces a normal view, 90 degrees produces a wide-angle view, and 120 degrees creates a fisheye-like extreme. The aspect ratio (width divided by height) prevents the image from stretching.
Orthographic projection preserves sizes regardless of distance, producing a flat, architectural look. It is used for 2D games rendered in a 3D engine, minimap views, UI rendering, and isometric perspectives. The orthographic matrix defines a rectangular viewing volume instead of a pyramidal frustum, so objects at any depth appear the same size.
Normalized Device Coordinates and Clip Space
After projection, coordinates are in clip space. The GPU divides x, y, and z by the w component (the perspective divide) to get normalized device coordinates (NDC). In OpenGL/WebGL NDC, x and y range from -1 to 1 (left to right, bottom to top), and z ranges from -1 to 1 (near to far). In DirectX/Vulkan, z ranges from 0 to 1. WebGPU uses the DirectX convention with z from 0 to 1.
Points outside the -1 to 1 range in x or y are off-screen and get clipped (not rendered). Points outside the z range are before the near plane or beyond the far plane and also get clipped. The viewport transform then maps NDC to screen pixels: NDC x of -1 maps to the left edge of the viewport, +1 maps to the right edge, and so on.
Understanding NDC is important for effects that operate in screen space: post-processing shaders, screen-space reflections, deferred rendering, and UI overlay positioning. It is also essential for the inverse operation: converting screen pixels back to world-space rays for mouse picking. The unprojection operation applies the inverse of the projection and view matrices to screen coordinates, producing a world-space ray from the camera through the clicked pixel.
Polar Coordinates
Polar coordinates represent a 2D position as a distance (radius, r) and an angle (theta) from a reference direction. Converting to Cartesian: x = r * Math.cos(theta), y = r * Math.sin(theta). Converting from Cartesian: r = Math.sqrt(x*x + y*y), theta = Math.atan2(y, x).
Polar coordinates are more natural than Cartesian for problems involving circles, arcs, and rotations. Radar displays plot contacts at (distance, angle) from the center. Radial menus arrange options at equal angle intervals around a center point. Circular motion is trivially expressed as incrementing theta at constant r. Tower defense range checks compare r to the tower's range radius. Aiming systems measure the angle to the target directly.
Spherical coordinates extend polar to 3D with (r, theta, phi), representing radius, azimuth angle, and polar angle. They are useful for camera systems that orbit around a target: the player drags horizontally to change theta (orbiting left/right) and vertically to change phi (looking up/down). Three.js's OrbitControls and Babylon.js's ArcRotateCamera both use spherical coordinates internally.
UV Coordinates
UV coordinates map 2D texture images onto 3D geometry. The U axis runs from 0 (left edge of the texture) to 1 (right edge), and V runs from 0 (bottom in OpenGL, top in DirectX) to 1 (the opposite edge). Each vertex of a 3D model stores UV coordinates that tell the renderer which pixel of the texture covers that vertex's neighborhood.
UV values outside the 0-1 range cause the texture to tile (repeat), clamp (stretch the edge pixels), or mirror, depending on the texture wrap mode setting. Tiled UVs are used for repeating patterns like brick walls, grass, and water. Clamped UVs are used for unique textures like character skins and UI elements.
UV mapping affects texture quality. Stretching (when a large surface area maps to a small UV area) causes blurriness. Compression (small surface, large UV area) wastes texture resolution. Good UV layouts distribute texture resolution proportionally to the visual importance of each surface. Game modeling tools like Blender provide automated UV unwrapping algorithms, but artists typically adjust the results manually for character models and hero assets.
Games use model, world, view, clip, NDC, and screen coordinate spaces. The model, view, and projection matrices transform between them. Most "wrong position" bugs come from confusing which space a value is in. Always be explicit about the coordinate space of every position and direction vector in your code.