Introducción al Desarrollo de Videojuegos con GameMaker · Module 9: Music, Sound Effects, and Particles
Importing and Playing Sound Effects
Lesson 41 of 60 · 45 min
Also available in: ES
Introduction to Sound Design in 2D Video Games
Audio accounts for more than half of a video game's perceptual impact. A jump animation or a hit against an enemy may feature flawless pixel art, but without synchronized auditory feedback, the action feels disconnected and lacks weight. In game development, this tactile and sensory responsiveness is commonly referred to as 'game feel' or 'juice.' Sound effects (abbreviated as SFX) provide crucial feedback, confirming to players that their inputs have been received and processed by the system.
Up to this point, our retro platformer project already includes movement mechanics, collisions, basic patrol enemies, coin collection, and a complete graphical user interface. However, all these interactions unfold in complete silence. In this lesson, we will begin assembling the game's audio layer by learning how to import sound files, understanding how GameMaker manages audio assets in memory, and using the built-in audio_play_sound function to bring jumps, hits, and pickups to life.
Audio Formats and the Sound Asset in GameMaker
In GameMaker, any audio file you include in your project is managed within the Asset Browser as a Sound asset. Before importing audio, it is essential to understand which file formats are best suited for snappy sound effects versus continuous background music tracks.
The two standard formats widely used in GameMaker development are WAV (.wav) and OGG Vorbis (.ogg). WAV files contain uncompressed or minimally compressed PCM audio, preserving pristine fidelity without requiring CPU cycles for real-time decompression. This makes them ideal for short, immediate sound effects (typically under 1 to 2 seconds), such as a coin chime, a jump bounce, or a quick explosion. In contrast, OGG files employ efficient lossy compression, drastically reducing disk space and download size, making them the industry standard for long music tracks and continuous ambient loops.

When you create a new Sound asset in the Asset Browser (right-click a folder and select Create -> Sound), the Sound Editor opens. Here you can name the asset following a consistent naming convention (such as the snd_ prefix), import the audio file from your drive, and configure its compression type and playback attributes.
| Sound Editor Setting | Common Values | SFX Recommendation |
|---|---|---|
| Attributes | Uncompress on load, Compressed - Streamed, Compressed | Uncompress on load for immediate, short-duration sound effects. |
| Target Bitrate | 64 kbps to 320 kbps | For 8-bit or retro sound effects, 96 to 128 kbps provides clean fidelity while saving space. |
| Channels | Mono, Stereo | Mono for single-channel directional SFX (saves 50% RAM); Stereo for broad ambient sounds. |
| Volume (Base Gain) | Slider from 0 to 1 | Keep at 1.0 and balance relative volumes via code or audio groups. |
💡 Memory Tip: Selecting 'Uncompress on load' decompresses the entire audio file directly into system RAM when the room initializes. For short sound effects (such as jumps or gunshots), this guarantees zero playback latency and prevents frame drops during gameplay.
The Core Function: audio_play_sound
In modern versions of GameMaker, the primary function used to trigger sounds in game space is audio_play_sound. Its base syntax accepts several arguments specifying the asset to play, its priority, and whether it should loop:
// Classic function signature:
audio_play_sound(soundid, priority, loop);Let's break down each parameter in this function call:
1. soundid: The identifier of the Sound asset as defined in the Asset Browser, such as snd_salto or snd_moneda. 2. priority: A numerical value (integer or float, commonly ranging from 0 to 100) indicating the relative importance of this sound compared to others. Operating systems and audio middleware have a hardware limit on simultaneous audio channels (hardware voices). If the game attempts to trigger more sounds than available channels allow, GameMaker halts the lowest-priority sounds in favor of higher-priority ones. Crucial gameplay cues, such as UI clicks or player damage, should have higher priority (e.g., 10) than background environmental details (e.g., 1). 3. loop: A boolean value (true or false). Passing true causes the sound to repeat indefinitely until explicitly stopped through code. For one-shot sound effects such as jumps or impacts, this argument must always be false.
In modern GameMaker runtimes, audio_play_sound also supports optional extended parameters, including gain (volume), time offset, and pitch modulation:
// Extended signature available in modern GameMaker:
audio_play_sound(index, priority, loop, [gain], [offset], [pitch], [listener_mask]);This overloaded call allows you to adjust volume and playback speed/pitch directly on the same line of code—an invaluable technique for preventing repetitive sounds from causing ear fatigue.
Practical Implementation 1: Jump Sound in obj_jugador
In previous modules, we established the player's vertical movement logic, governed by variables like vspd (vertical speed), grav (gravity), and jump_spd (jump impulse). Now we will hook our snd_salto sound asset to trigger at the exact instant the player lifts off the ground.
Next, open obj_jugador and navigate to its Step event, specifically where the code checks if the player pressed the jump key while grounded:
// Object: obj_jugador
// Event: Step
// Input polling (defined in earlier modules)
var _key_jump = keyboard_check_pressed(vk_space) || keyboard_check_pressed(ord("W"));
// Jump logic when grounded
if (en_suelo && _key_jump)
{
vspd = -jump_spd;
en_suelo = false;
// Play jump sound effect
// Priority 8 (high tactile importance), non-looping (false)
audio_play_sound(snd_salto, 8, false);
}Notice that audio_play_sound is placed inside the keyboard_check_pressed check. If we had used keyboard_check (which returns true every frame the key is held), the engine would attempt to restart the sound 60 times per second, causing a harsh stuttering artifact known as audio machine-gunning.
Practical Implementation 2: Collecting Coins and Items
In our collectible mechanics, obj_moneda was designed to increment the global.monedas counter upon colliding with obj_jugador. Audio feedback is vital here, as it instantly informs the player that their pickup was registered.
Create a Sound asset named snd_moneda featuring a bright, bell-like tone or an upward arpeggio. There are two standard approaches to handle this collision: in obj_jugador colliding with obj_moneda, or inside obj_moneda colliding with obj_jugador. To maintain modular, self-contained pickups, it is cleanest to let the collectible handle its own destruction and audio cue:
// Object: obj_moneda
// Event: Collision with obj_jugador
// Increment global counters
global.monedas += 1;
global.puntos += 100;
// Play pickup sound
// Priority 6, non-looping
audio_play_sound(snd_moneda, 6, false);
// Destroy the coin instance in the current room
instance_destroy();Why does the sound continue playing if the instance is destroyed on the very next line? This is a common question among developers new to GameMaker. Calling audio_play_sound sends a playback request to the engine's global audio mixer subsystem. Once triggered, the sound instance is completely detached from the object that called it; it lives on in the mixer until playback naturally finishes, regardless of the calling instance's lifecycle.
Practical Implementation 3: Player Damage and Knockback
The third critical sound effect is the hit or damage cue. When obj_jugador collides with obj_enemigo_patrulla, the game subtracts a life and initiates temporary invulnerability (i-frames) to prevent immediate multi-hit damage.
Create an asset named snd_golpe containing a dull, heavy thud or distorted impact. Inside the Collision event between obj_jugador and obj_enemigo_patrulla, add the sound call within the vulnerability check:
// Object: obj_jugador
// Event: Collision with obj_enemigo_patrulla
// Only process if the player is not currently invulnerable
if (!es_invulnerable)
{
global.vidas -= 1;
es_invulnerable = true;
tiempo_invulnerable = 60; // 60 frames (approx. 1 second at 60 FPS)
// Apply vertical and horizontal knockback
vspd = -4;
hspd = (x < other.x) ? -5 : 5;
// Play impact sound with maximum priority
// Priority 10 (top tactical priority for player status)
audio_play_sound(snd_golpe, 10, false);
// Check for game over condition
if (global.vidas <= 0)
{
// Game Over transition logic
room_goto(rm_gameover);
}
}Assigning a high priority (10) to snd_golpe ensures that even if explosions, coins, and ambient loops are playing simultaneously, the player's damage cue will never be dropped or culled by the hardware voice manager.
Professional Technique: Pitch Shifting
A frequent issue in classic 2D games is ear fatigue: when an identical sound sample triggers dozens of times per minute (such as collecting a string of coins or hopping repeatedly), the brain quickly notices the robotic repetition, diminishing game feel.
You can solve this elegantly using pitch shifting. In GameMaker, the default pitch of an audio asset is 1.0. A value of 1.1 raises the pitch slightly and speeds up playback, while 0.9 lowers the pitch and slows it down. Applying subtle random pitch variation on each trigger creates an organic, dynamic feel using only a single sound file in your project.
// Dynamic pitch variation for coin collection
// Object: obj_moneda (Collision event with obj_jugador)
global.monedas += 1;
// Generate subtle pitch variation between 0.95 and 1.05
var _tono_aleatorio = random_range(0.95, 1.05);
// Use audio_play_sound with extended parameters:
// soundid, priority, loop, gain, offset, pitch
audio_play_sound(snd_moneda, 6, false, 1.0, 0, _tono_aleatorio);
instance_destroy();With just two lines of code, every collected coin sounds distinct, significantly enhancing the polish of your game without adding extra megabytes to the build.
Guided Hands-on Exercises
To reinforce your mastery of sound management and playback in GameMaker, complete the following three practical challenges in your project.
Summary
- Sound effects (SFX) deliver essential physical feedback and deepen player immersion in interactive environments.
- WAV format combined with the 'Uncompress on load' attribute is the industry-standard recommendation in GameMaker for short, latency-critical SFX.
- The audio_play_sound(soundid, priority, loop) function is the primary mechanism for triggering one-shot audio events.
- Audio priority ensures critical gameplay indicators (such as taking damage) are never dropped by voice-limiting hardware channels.
- Playing sounds remain active in the engine's global audio mixer even after the triggering instance is destroyed with instance_destroy().
- Dynamic pitch shifting with random_range eliminates auditory repetition and fatigue without increasing asset memory footprint.
Practise what you learned
Exercise 1 · 1 point
Match each audio-related parameter or setting in GameMaker to its corresponding technical description:
- soundid
- priority
- loop
- Uncompress on load
Exercise 2 · 2 points
Write the function call to play the jump sound effect using the `snd_salto` asset, with a priority of `8` and configured not to loop.
Your code is not executed: specific requirements are checked on the text.
Exercise 3 · 1 point
Upon colliding with a coin, the game runs `audio_play_sound(snd_moneda, 6, false);` immediately followed by `instance_destroy();`. What happens to the sound?
Sign in to save your progress — Sign in