Cached at:
08/10/26, 11:05 PM
TL;DR: A developer recreates the atmosphere of Need for Speed 2015 in Game Maker using custom 3D models, shaders, raycast physics, recorded car sounds, and a DIY livery editor.
## Why Game Maker?
In 2015, Electronic Arts rebooted the Need for Speed franchise after a long break. It had a two-year development cycle and launched to mixed reviews. Many players reported issues that made it borderline unplayable, though the author bought it in 2018 on PS4 after most problems had been patched. What stood out was the atmosphere: perpetual rain, beautiful reflections, strong graphics, and excellent sound design.
The author wanted to create something similar in Game Maker, the only engine they have experience with for 17 years. Is it possible to make something that looks like Need for Speed 2015 in Game Maker? Yes and no — it depends on how much time you want to sink into remaking a beautiful 3D racing game with both hands tied behind your back. As a self-described masochist, they got to work.
## Modeling the Car
The project was split into two parts: first, make a working car with a decent 3D model; second, make the environment. The car chosen was a 1999 Toyota Celica, featured in both Underground 1 and Underground 2. It wasn't in Need for Speed 2015, but it fits the nighttime street racing aesthetic well.
The 3D model took a few weeks on and off. It lacks some details, but it does look a bit like the author's own car. Having the real car on hand was handy because the blueprints used for modeling didn't give all the necessary information to make it look convincing.
After setting up a new Game Maker project, a 3D camera follows the car. To make the camera lag behind the car smoothly, the author uses the angle difference function between two vectors instead of the car's facing direction, easing the camera in and out. The code difference has a noticeable impact on the game's feel.
## Building the Environment
Need for Speed 2015 is surprisingly detailed, so several 3D models were made in Blender: roads, sidewalks, street lights, buildings, facades, pipes, and more. They are exported as vertex buffers and loaded into Game Maker. A simple 3D room editor was set up using an array of structs storing the name of each model, the vertex buffer references, and the associated textures.
In the draw GUI event, a loop walks through this array, letting the author select each individual vertex buffer and place it into the map. None of these models are batched yet, despite some using texture atlases. That will be the next big optimization, but the game runs fine for now.
## Lighting and Shaders
Need for Speed 2015 takes place during a night where it never stops raining. The author loves the look of wet asphalt and its light reflections, something they wanted to add to their own game.
A shader was written to support multiple light sources, normal maps, specular highlights, and equirectangular reflections. For the asphalt, an albedo texture is combined with a normal map. Adding only albedo textures gives the scene a "very Sega Saturnish" look, so lighting was needed.
In the create event of the control object, arrays of light positions and light colors are sent to the shader alongside the array size. Looping through these arrays, the shader calculates the distance between the current vertex position and every light source, then uses the reflected vector to determine how much reflected light reaches the camera lens. This sets the size and power of the specular highlights.
Normal maps are used to transform RGB values into normal vectors, faking additional detail on otherwise flat meshes. The combination of the vertex normal attribute and the color sampled from the normal map makes the asphalt look much more detailed than it actually is.
The specular highlights are exaggerated, but as the author puts it, "much like our lord and savior Gabe Newell once said, realism simply doesn't interest me very much."
For reflections, a cubemap-like effect was attempted, but Game Maker doesn't support cubemap reflections — at least not in a way the author understands yet. Instead, they use a function that transforms 3D coordinates into 2D coordinates to sample pixels from an equirectangular texture. It's not perfect, but it looks pretty cool.
With lighting in place, the game has a strong atmospheric look. But environments are only a small part of a full racing game.
## Driving Physics and Sound
Two things are integral to an underground-style racing game: driving physics and sound.
In the create event of the player object, variables determine how the car behaves: stock horsepower, weight, flywheel weight, aspiration, and engine type. These also determine how the car sounds, shifts, and drives.
Controls are simple:
- **W** — accelerate
- **A / D** — steer left / right
- **S** — brake and reverse
When accelerating, a throttle value eases between 0 and 1, determining how fast the car accelerates. Acceleration also depends on the currently selected gear. Only a manual transmission exists for now, meaning you are responsible for which gear you are in at all times — you can even money shift if you wanted to.
Physics are partly faked by adding a slight rotation to the car's transformation matrix, making it look as though the car is affected by G-forces while accelerating and braking. Simple raycasts on the wheels determine whether the car is driving over a sidewalk. This will change when real elevation is implemented, but for now it works.
For sound, the author recorded their own car's exhaust using an old Blue Yeti, along with several other sound effects to make it sound as close as possible. Foley sounds for shifting and driving — like a slight whining noise from the belts and transmission — were also added. After all, it's a 28-year-old car.
The Celica is equipped with the 2ZZ engine from Yamaha, which has Toyota's "lift" — equivalent to Honda's VTEC. Once the engine reaches 6,200 RPM, the camshafts change, giving more horsepower and an aggressive sound, all while "barely keeping up with the Prius in front of you."
The `audio_sound_pitch` function makes engine sounds follow the car's RPM band. An RPM counter on the right closely resembles the Celica's own tachometer.
## Customization
Need for Speed 2015 was known for its customization. While body kits and aftermarket parts haven't been implemented yet, some customization options are in place.
You can change the car's paint color and the material used for that color, choosing between metallic, gloss, satin, and matte. Metallic adds subtle flakes to the paint, while matte dampens reflections. A color picker uses the `draw_get_pixel` method — something the author says they'll probably get lynched for mentioning to Game Maker folks.
The favorite feature is the livery editor. Players can add vinyls to their car, but the author initially had no idea how to do it. The first idea was to send five different surfaces to the shader as texture samplers, one for each side of the car. That wouldn't work because Game Maker natively supports only up to eight texture samplers, including the base texture.
The solution uses a single surface divided into five areas. The `gpu_set_scissor` function — discovered by accident while skimming the Game Maker manual — was exactly what was needed. The texture is divided into sections for each side of the car. Five separate arrays allow adding vinyls to each side individually. Each element in the array represents a vinyl, which can be moved, rotated, scaled, and placed. It's simple and doesn't support copying, pasting, or deleting yet.
To avoid infringing on anyone's work and staying away from generative AI, the author used an old drawing tablet to draw custom vinyls. The shader projects each part of the vinyl texture onto the desired side by comparing the vertex position and orientation with each part of the texture. This ensures that vinyls placed on the left side don't appear on the right side, and vice versa. In the fragment shader, coordinates received from the vertex shader project the texture onto the car. It's not perfect, but it works surprisingly well.
## Future Plans
The author has ambitious plans for the project:
- Races where you can wager your car and win your opponent's car
- More customization
- More cars
- Better optimization
- Better sound
In their opinion, the game does look a bit like Need for Speed 2015, just with worse graphics. The atmosphere comes quite close — but without those annoying phone calls.
Source: [Making Need For Speed 2015 with Game Maker](https://www.youtube.com/watch?v=ffGqjOBowIc)