{"article":{"slug":"2d-vehicles","title":"2D Vehicles","subtitle":null,"summary":"Pat Kerr recreates, for its 30th anniversary, the 1996 weekend 2D physics demo written in GFA BASIC on an Atari ST that became the basis of the vehicle system in Grand Theft Auto, with a playable JavaScript Motion Lab and an illustrated walkthrough of its rigid-body physics, force models and approximate tyres.","content_type":"blog_post","language":"en","canonical_url":"https://patkerr.co.uk/2d-vehicles/","author":{"name":"Pat Kerr","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"patkerr.co.uk","url":"https://patkerr.co.uk/","listing_slug":null,"listing":null},"topics":[{"name":"Game Development","slug":"game-development","url":"https://listedarticles.com/topics/game-development"},{"name":"Physics Simulation","slug":"physics-simulation","url":"https://listedarticles.com/topics/physics-simulation"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1118,"reading_minutes":5,"published_at":"2026-10-10T20:07:06.391Z","added_at":"2026-10-10T20:07:06.391Z","updated_at":"2026-10-10T20:07:06.391Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/2d-vehicles","markdown_url":"https://listedarticles.com/articles/2d-vehicles.md","example":false,"citation":"Pat Kerr, patkerr.co.uk. \"2D Vehicles.\" 10 Oct 2026. https://patkerr.co.uk/2d-vehicles/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://patkerr.co.uk/2d-vehicles/"},"body_markdown":"A project history · 1996–2026\n\n# 2D Vehicles\n\nOne weekend in late August 1996, I wrote a 2D physics simulation which later became\nthe basis of the vehicle system in the eventually popular game \"Grand Theft Auto\" aka\n\"GTA\".\n\nIt began as a little wireframe demo written in GFA BASIC on my Atari ST home computer\n(and was later ported to C for use in the actual game).\n\nI have\nrecreated\\*\nit here in JavaScript for its 30th anniversary in a slightly prettier, \"remastered\"\nform, for anyone who is interested in seeing or playing it.\n\n[Play Motion Lab](https://patkerr.co.uk/motion-lab/)\n\n[![Play Motion Lab: a wireframe car leaving curved tyre trails across the simulation grid.](https://patkerr.co.uk/2d-vehicles/motion-lab-screenshot.jpg)](https://patkerr.co.uk/motion-lab/)\n\nThe 1996 idea, recreated in Motion Lab.\n\nInstructions\n\nYou can play the recreation above, with touch controls if you are on mobile.\n\nIn addition to the default \"Car\" mode (1), you can also select the technically simpler\nSpaceship aka \"Ship\" (2) and \"Brick\" (3) modes, either via the mode selector in Settings\nor by pressing the corresponding numbers on your keyboard.\n\nCollision barriers around the sides of the playfield can be toggled by clicking or\npressing \"B\", and \"G\" toggles vertical gravity (which only really makes sense in the\nShip and Brick modes).\n\nCamera controls are provided by \"Z\" and \"X\": \"Z\" toggles what is called the camera's\n\"dead zone\", which changes how far the vehicle can move before the camera follows it;\n\"X\" toggles a speed-related zoom feature which pulls the camera back a bit when you are\ngoing faster (just like in GTA).\n\n\\*(in an entirely non-copyright and non-trademark infringing way, of course)\n\n*[VOLUNTARY DISCLAIMER: This work is wholly independent of, and in no way affiliated\nwith, the \"Grand Theft Auto\" franchise and its publisher \"Take-Two\", or the developer\nentity known as \"Rockstar Games\". I am more than happy to make this abundantly clear.\nDelighted, even.]*\n\nHow it works\n\n## A small idea with two layers.\n\nThe prototype combined a general-purpose 2D rigid body with a deliberately simple\nmodel of a car.\n\nThe original simulation started with something like the \"Brick\", and I then added some\nenhancements to make the \"Ship\" (which is deliberately reminiscent of the classic game\n\"Thrust\" from 1986), before finally adding the elements which were required to make it\nfeel a bit more like a \"Car\".\n\nAt the core of the system is a simple classical 2D rigid body dynamics simulation.\nFrom what I can tell, this approach was not yet common in games at the time (with some\nnotable exceptions), and most game vehicles were done using basic high-school ‘point\nphysics’ (F = ma), with any rotational component being handled by various wonky\n\"hacks\". Using proper rigid-body physics (including torques) handles rotation more\ncoherently.\n\nOn top of that core, I then added a \"novel\" vehicle simulation layer, based on a\nsimple, approximate, and technically incorrect model of how tyres behave. It was\nbasically a semi-educated guess on my part and, although I knew it wasn't really\nphysically accurate, it nevertheless seemed to be \"good enough\" for my purposes at the\ntime.\n\n### From input to motion\n\nThese diagrams describe the current JavaScript recreation. The browser interface\nsupplies the controls, the simulation advances in fixed time steps, and the Canvas\nrenderer draws the resulting state. Keeping those jobs separate makes it easier to\nfollow where a button press becomes a force, and where that force becomes movement.\nSelect any diagram to open it at full size.\n\n[![Motion Lab runtime: browser controls feed a fixed-step simulation, which updates the vehicle before the Canvas renderer draws it.](https://patkerr.co.uk/motion-lab/docs/architecture.svg)](https://patkerr.co.uk/motion-lab/docs/architecture.svg)\n\nThe overall flow, from the page and controls to simulation and drawing.\n\n### One body, three behaviours\n\nA vehicle combines a rigid body with a shell that describes its display shape and\ncollision geometry, and a dynamics object that supplies its behaviour. The Brick\naccepts forces from a pointer drag; the Ship adds thrust at an attachment point; the\nCar adds engine force and steering, with resistance applied at four tyre positions.\nSwitching mode replaces the shell and behaviour while preserving the body's position\nand motion.\n\n[![Vehicle composition: Car, Ship and Brick each combine a shape and force model with the same persistent rigid body.](https://patkerr.co.uk/motion-lab/docs/vehicle-architecture.svg)](https://patkerr.co.uk/motion-lab/docs/vehicle-architecture.svg)\n\nHow the vehicle coordinator combines shape, behaviour and body state.\n\n### Forces can move and turn the body\n\nThe rigid body tracks position and velocity alongside angle and angular velocity. A\nforce through its centre changes its motion; a force applied away from the centre can\nalso turn it. The simulation adds up the forces and torque, updates velocity, then\nadvances position and angle. A point on a rotating body has its own velocity,\ncombining the body's movement with the motion around its centre.\n\nBarriers use that same point velocity. When a shape crosses an edge, the simulation\nmoves it back inside and applies a contact impulse if it is moving into the barrier.\nAn off-centre impact can therefore change both its velocity and its spin. This is a\nsimple barrier solver, with frictionless edges, rather than a general collision\nsystem.\n\n[![Rigid-body physics: forces and torque update motion, while barrier impulses account for contact velocity and the rotational lever arm.](https://patkerr.co.uk/motion-lab/docs/physics.svg)](https://patkerr.co.uk/motion-lab/docs/physics.svg)\n\nThe shared physics core and the steps used to resolve barrier contacts.\n\n### The deliberately approximate tyres\n\nFor each tyre, the Car measures the velocity at its position and resolves it into two\ncomponents: along the wheel's heading and sideways across it. It applies a small\nresistance to rolling and a much stronger resistance to sideways motion. Steering\nchanges the front wheels' headings, so their forces also turn the body. The handbrake\nincreases rear rolling resistance and reduces rear sideways grip.\n\nThose resistance forces are proportional to velocity, without a force cap. That is a\nconvenient damping model rather than a realistic account of tyre friction, slip or\navailable grip. It produces the useful feeling of wheels resisting sideways movement\nwith very little machinery. The Ship and Brick use the same physics core with\ndifferent ways of applying forces.\n\n[![The three force models: tyre resistance and steering for the Car, thrust for the Ship, and pointer-applied force for the Brick.](https://patkerr.co.uk/motion-lab/docs/dynamics.svg)](https://patkerr.co.uk/motion-lab/docs/dynamics.svg)\n\nThe force models, including wheel velocity components and handbrake behaviour.\n\n### Putting the pieces together\n\nThe Vehicle coordinator asks the selected dynamics object to apply its forces, then\nadvances the rigid body. It also converts the shell's local points into world\npositions for drawing and finds the surface point facing each barrier. When a flat\nface touches a barrier, it uses the midpoint of the contacting points, avoiding the\nartificial spin that choosing a single corner would introduce.\n\n[![Vehicle methods: install a mode, apply forces and integrate motion, transform shape points, and select a barrier contact location.](https://patkerr.co.uk/motion-lab/docs/vehicles.svg)](https://patkerr.co.uk/motion-lab/docs/vehicles.svg)\n\nA closer look at mode installation, simulation updates and contact geometry.\n","body_html":"<p>A project history · 1996–2026</p>\n<h1 id=\"2d-vehicles\">2D Vehicles</h1>\n<p>One weekend in late August 1996, I wrote a 2D physics simulation which later became\nthe basis of the vehicle system in the eventually popular game &quot;Grand Theft Auto&quot; aka\n&quot;GTA&quot;.</p>\n<p>It began as a little wireframe demo written in GFA BASIC on my Atari ST home computer\n(and was later ported to C for use in the actual game).</p>\n<p>I have\nrecreated*\nit here in JavaScript for its 30th anniversary in a slightly prettier, &quot;remastered&quot;\nform, for anyone who is interested in seeing or playing it.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/\" rel=\"nofollow ugc noopener\">Play Motion Lab</a></p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/2d-vehicles/motion-lab-screenshot.jpg\" alt=\"Play Motion Lab: a wireframe car leaving curved tyre trails across the simulation grid.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>The 1996 idea, recreated in Motion Lab.</p>\n<p>Instructions</p>\n<p>You can play the recreation above, with touch controls if you are on mobile.</p>\n<p>In addition to the default &quot;Car&quot; mode (1), you can also select the technically simpler\nSpaceship aka &quot;Ship&quot; (2) and &quot;Brick&quot; (3) modes, either via the mode selector in Settings\nor by pressing the corresponding numbers on your keyboard.</p>\n<p>Collision barriers around the sides of the playfield can be toggled by clicking or\npressing &quot;B&quot;, and &quot;G&quot; toggles vertical gravity (which only really makes sense in the\nShip and Brick modes).</p>\n<p>Camera controls are provided by &quot;Z&quot; and &quot;X&quot;: &quot;Z&quot; toggles what is called the camera&#39;s\n&quot;dead zone&quot;, which changes how far the vehicle can move before the camera follows it;\n&quot;X&quot; toggles a speed-related zoom feature which pulls the camera back a bit when you are\ngoing faster (just like in GTA).</p>\n<p>*(in an entirely non-copyright and non-trademark infringing way, of course)</p>\n<p>*[VOLUNTARY DISCLAIMER: This work is wholly independent of, and in no way affiliated\nwith, the &quot;Grand Theft Auto&quot; franchise and its publisher &quot;Take-Two&quot;, or the developer\nentity known as &quot;Rockstar Games&quot;. I am more than happy to make this abundantly clear.\nDelighted, even.]*</p>\n<p>How it works</p>\n<h2 id=\"a-small-idea-with-two-layers\">A small idea with two layers.</h2>\n<p>The prototype combined a general-purpose 2D rigid body with a deliberately simple\nmodel of a car.</p>\n<p>The original simulation started with something like the &quot;Brick&quot;, and I then added some\nenhancements to make the &quot;Ship&quot; (which is deliberately reminiscent of the classic game\n&quot;Thrust&quot; from 1986), before finally adding the elements which were required to make it\nfeel a bit more like a &quot;Car&quot;.</p>\n<p>At the core of the system is a simple classical 2D rigid body dynamics simulation.\nFrom what I can tell, this approach was not yet common in games at the time (with some\nnotable exceptions), and most game vehicles were done using basic high-school ‘point\nphysics’ (F = ma), with any rotational component being handled by various wonky\n&quot;hacks&quot;. Using proper rigid-body physics (including torques) handles rotation more\ncoherently.</p>\n<p>On top of that core, I then added a &quot;novel&quot; vehicle simulation layer, based on a\nsimple, approximate, and technically incorrect model of how tyres behave. It was\nbasically a semi-educated guess on my part and, although I knew it wasn&#39;t really\nphysically accurate, it nevertheless seemed to be &quot;good enough&quot; for my purposes at the\ntime.</p>\n<h3 id=\"from-input-to-motion\">From input to motion</h3>\n<p>These diagrams describe the current JavaScript recreation. The browser interface\nsupplies the controls, the simulation advances in fixed time steps, and the Canvas\nrenderer draws the resulting state. Keeping those jobs separate makes it easier to\nfollow where a button press becomes a force, and where that force becomes movement.\nSelect any diagram to open it at full size.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/docs/architecture.svg\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/motion-lab/docs/architecture.svg\" alt=\"Motion Lab runtime: browser controls feed a fixed-step simulation, which updates the vehicle before the Canvas renderer draws it.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>The overall flow, from the page and controls to simulation and drawing.</p>\n<h3 id=\"one-body-three-behaviours\">One body, three behaviours</h3>\n<p>A vehicle combines a rigid body with a shell that describes its display shape and\ncollision geometry, and a dynamics object that supplies its behaviour. The Brick\naccepts forces from a pointer drag; the Ship adds thrust at an attachment point; the\nCar adds engine force and steering, with resistance applied at four tyre positions.\nSwitching mode replaces the shell and behaviour while preserving the body&#39;s position\nand motion.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/docs/vehicle-architecture.svg\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/motion-lab/docs/vehicle-architecture.svg\" alt=\"Vehicle composition: Car, Ship and Brick each combine a shape and force model with the same persistent rigid body.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>How the vehicle coordinator combines shape, behaviour and body state.</p>\n<h3 id=\"forces-can-move-and-turn-the-body\">Forces can move and turn the body</h3>\n<p>The rigid body tracks position and velocity alongside angle and angular velocity. A\nforce through its centre changes its motion; a force applied away from the centre can\nalso turn it. The simulation adds up the forces and torque, updates velocity, then\nadvances position and angle. A point on a rotating body has its own velocity,\ncombining the body&#39;s movement with the motion around its centre.</p>\n<p>Barriers use that same point velocity. When a shape crosses an edge, the simulation\nmoves it back inside and applies a contact impulse if it is moving into the barrier.\nAn off-centre impact can therefore change both its velocity and its spin. This is a\nsimple barrier solver, with frictionless edges, rather than a general collision\nsystem.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/docs/physics.svg\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/motion-lab/docs/physics.svg\" alt=\"Rigid-body physics: forces and torque update motion, while barrier impulses account for contact velocity and the rotational lever arm.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>The shared physics core and the steps used to resolve barrier contacts.</p>\n<h3 id=\"the-deliberately-approximate-tyres\">The deliberately approximate tyres</h3>\n<p>For each tyre, the Car measures the velocity at its position and resolves it into two\ncomponents: along the wheel&#39;s heading and sideways across it. It applies a small\nresistance to rolling and a much stronger resistance to sideways motion. Steering\nchanges the front wheels&#39; headings, so their forces also turn the body. The handbrake\nincreases rear rolling resistance and reduces rear sideways grip.</p>\n<p>Those resistance forces are proportional to velocity, without a force cap. That is a\nconvenient damping model rather than a realistic account of tyre friction, slip or\navailable grip. It produces the useful feeling of wheels resisting sideways movement\nwith very little machinery. The Ship and Brick use the same physics core with\ndifferent ways of applying forces.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/docs/dynamics.svg\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/motion-lab/docs/dynamics.svg\" alt=\"The three force models: tyre resistance and steering for the Car, thrust for the Ship, and pointer-applied force for the Brick.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>The force models, including wheel velocity components and handbrake behaviour.</p>\n<h3 id=\"putting-the-pieces-together\">Putting the pieces together</h3>\n<p>The Vehicle coordinator asks the selected dynamics object to apply its forces, then\nadvances the rigid body. It also converts the shell&#39;s local points into world\npositions for drawing and finds the surface point facing each barrier. When a flat\nface touches a barrier, it uses the midpoint of the contacting points, avoiding the\nartificial spin that choosing a single corner would introduce.</p>\n<p><a href=\"https://patkerr.co.uk/motion-lab/docs/vehicles.svg\" rel=\"nofollow ugc noopener\"><img src=\"https://patkerr.co.uk/motion-lab/docs/vehicles.svg\" alt=\"Vehicle methods: install a mode, apply forces and integrate motion, transform shape points, and select a barrier contact location.\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></a></p>\n<p>A closer look at mode installation, simulation updates and contact geometry.</p>","headings":[{"level":1,"text":"2D Vehicles","id":"2d-vehicles"},{"level":2,"text":"A small idea with two layers.","id":"a-small-idea-with-two-layers"},{"level":3,"text":"From input to motion","id":"from-input-to-motion"},{"level":3,"text":"One body, three behaviours","id":"one-body-three-behaviours"},{"level":3,"text":"Forces can move and turn the body","id":"forces-can-move-and-turn-the-body"},{"level":3,"text":"The deliberately approximate tyres","id":"the-deliberately-approximate-tyres"},{"level":3,"text":"Putting the pieces together","id":"putting-the-pieces-together"}]}}