Magic Carpet Rush is a 2D endless flying game I developed in Unity for browsers. The player guides an enchanted carpet above a fantasy city, flies through openings between towers, collects floating lanterns and tries to set a new high score.
The controls are intentionally simple: one action pushes the carpet upward while gravity continually pulls it down. However, turning that simple idea into an enjoyable game required careful work on movement, obstacle generation, collisions, difficulty, visual feedback and browser performance.
The completed version is available to play directly on Lalo.games in a compatible browser.
In this article, I will explain how I developed the game, the technical problems I encountered and what I learned while preparing it for WebGL.
Starting With a Simple Game Concept
I wanted to create an accessible browser game that players could understand within seconds. There are no complicated menus or lengthy instructions. The objective is immediately clear: keep the carpet flying and avoid hitting the towers.
Instead of building fixed levels, I designed the game as an endless experience. Tower formations continuously enter from the right side of the screen and move toward the player. Each formation contains an upper tower and a lower tower, leaving a safe opening between them.
Passing through an opening adds one point to the score. The game continues until the carpet collides with a tower or leaves the playable area.
I also added collectible lanterns to give players another objective. Lanterns occasionally appear inside the tower openings. They are optional, so players must decide whether collecting one is worth adjusting their flight path.
This gave the game two connected goals:
- Survive for as long as possible.
- Collect as many lanterns as possible.
Creating a Moroccan-Inspired Fantasy World
I did not want Magic Carpet Rush to feel like a generic flying game. Its identity is inspired by a fantasy interpretation of Moroccan architecture and traditional visual elements.
The environment includes decorated towers, distant city structures, clouds, floating lanterns and an ornate flying carpet. I used a palette built around gold, turquoise and purple to create a warm magical atmosphere.
The carpet is the most important visual element because the player watches it throughout the entire game. Its design needed to remain recognizable against both the background and the obstacles.
To make its movement feel more magical, I added a colored trail that begins with a warm golden tone and gradually fades into turquoise and transparency.
Building the Project in Unity
I developed Magic Carpet Rush using Unity 6000.3.15f1, also known as Unity 6, with C# as the programming language.
The project uses the Universal Render Pipeline and Unity’s 2D Renderer. The main systems include:
- Rigidbody2D physics
- 2D colliders
- Runtime obstacle generation
- Particle effects
- Trail rendering
- Unity UI
- Procedurally generated audio
- PlayerPrefs for saving the high score
- Responsive camera and background scaling
- WebGL build configuration
Most of the game is managed by a central C# controller. It creates and connects the gameplay objects, user interface, audio and visual effects when the game starts.
For a compact browser project, this made it easier to understand how the different systems interacted. If the game becomes substantially larger, I would separate responsibilities such as audio, spawning and UI into dedicated scripts.
Making the Carpet Feel Responsive
The carpet uses Unity’s Rigidbody2D physics component. Gravity continually pulls it downward, while player input gives it a fixed upward velocity.
Players can control the carpet using:
- Space
- Up Arrow
- Mouse click
- Touch or pointer input on supported devices
I chose to replace the carpet’s vertical velocity whenever the player acts. This produced more consistent movement than repeatedly adding force to its existing momentum.
The carpet also rotates according to its vertical speed. It tilts upward while climbing and gradually points downward while falling. I limited the rotation range so the movement remained expressive without making the carpet look unstable.
Getting the movement right required more than selecting random physics values. The upward velocity, gravity, obstacle gap and spawning interval all had to complement one another. A small change to any of these settings could make the game feel either too easy or unnecessarily frustrating.
Suggested image: A gameplay screenshot showing the carpet flying toward a tower opening.
Generating the Towers at Runtime
Because Magic Carpet Rush is an endless game, the obstacle layout cannot depend on manually arranged levels.
The game periodically creates a new tower formation outside the visible area. Each formation contains two towers with an opening between them. The vertical position of that opening changes randomly, forcing the player to adjust the carpet’s height.
The towers then move from right to left. When a formation passes the carpet, the player receives one point. The system records that the formation has already been counted so it cannot award the same point twice.
After an obstacle moves far enough beyond the screen, it is destroyed and removed from the active list. This prevents unused objects from accumulating during long sessions.
The initial movement speed is intentionally manageable. As the score grows, the towers move progressively faster. I placed a limit on this increase so the difficulty can rise without eventually becoming unreasonable.
Adding Collectible Lanterns
Some tower formations contain a floating lantern positioned within the opening.
Unlike the towers, the lantern uses a trigger collider. When the carpet touches it, the lantern disappears, the collection counter increases and the game plays a dedicated effect.
I added a gentle floating movement and slow rotation to make the lanterns noticeable without distracting the player. Collecting one also triggers:
- A short sound effect
- A golden particle burst
- An animation on the lantern counter
The lantern counter is separate from the main survival score. This allows the player to understand both results immediately after a run.
Designing the Menus and Interface
The game includes four main interface states:
Main menu
The main menu introduces the game and provides a Play button and short control instructions. It also displays the Lalo.games credit.
Gameplay interface
During a run, the interface shows the current score, number of collected lanterns and a pause button. I kept this interface minimal so it would not cover the gameplay area.
Pause menu
The pause screen allows players to resume, manage sound or return to the main menu. Opening it temporarily stops the game using Unity’s time-scale system.
Game-over screen
After a collision, the final screen displays:
- The player’s score
- Collected lanterns
- Best score
- Restart button
- Home button
The best score is saved locally with Unity’s PlayerPrefs, allowing returning players to continue challenging their previous record.
Making the Game Adapt to Different Screens
A browser game can be opened inside many different window sizes, so I could not design the presentation for only one resolution.
The interface uses a reference resolution of 1920 × 1080 and scales with the available screen size. The orthographic camera also adjusts when the display becomes narrow or portrait-shaped.
The background required special attention. It needed to cover the camera view without leaving visible empty edges or becoming divided into noticeable sections.
I calculated the camera’s visible width and height, compared those measurements with the background sprite and scaled the image until the complete display was covered.
This allowed one continuous illustration to fill the screen while preserving the visual atmosphere.
Creating Visual Feedback
Simple gameplay benefits greatly from clear feedback. Every important action should feel visible and understandable.
Magic Carpet Rush uses different effects for flying, collecting lanterns and colliding with obstacles. These include short particle bursts, sound effects, UI animation and a brief camera shake after a collision.
One small glow texture used by the particle effects is generated through C# rather than imported as a separate image. Its transparency fades from the centre toward the edges, producing a soft magical appearance.
The background also contains slowly moving particles that create subtle magical dust. I kept their speed and quantity low so they added atmosphere without making the screen visually busy.
Generating Audio Through Code
An unusual part of the project is that its music and sound effects are generated at runtime instead of being loaded from imported audio files.
The background music is created by calculating waveform samples and writing them into a looping Unity AudioClip. It combines a short melody with lower-frequency tones to support the fantasy setting.
The game uses the same general approach to create separate sounds for:
- Carpet movement
- Passing an obstacle
- Collecting a lantern
- Colliding
- Pressing interface buttons
I separated the background music and sound effects into different AudioSource components. This makes it easier to control them independently and allows the sound option to mute the experience correctly.
Problems I Solved During Development
The background looked divided
An early version made the fantasy environment appear divided because the artwork was being repeated in a way that did not suit the illustration.
Repeating an image works when it was specifically designed as a seamless texture. It did not work well for this detailed city background.
I solved the problem by displaying one complete background sprite and scaling it according to the camera’s visible area. The result was a continuous scene without an obvious seam.
The original particles did not match the game
The first movement effect used basic pink particles. Technically, the effect worked, but visually it felt disconnected from the carpet and the rest of the environment.
I replaced it with softer glowing particles using turquoise and gold colors. I also adjusted the particle shape, movement and fading to make the effect feel like magical energy rather than a generic burst.
This reminded me that an effect is not successful simply because it functions. It must also support the game’s visual identity.
Unity displayed a repeated particle warning
During testing, Unity repeatedly reported that the duration of a particle system was being changed while the system was still playing.
I corrected the initialization order by stopping and clearing the particle system before configuring its duration and other properties. After configuration, the system could safely play and clean itself up.
The warning did not completely break the game, but leaving a repeated Console issue unresolved would have made future debugging more difficult.
Preparing Magic Carpet Rush for WebGL
Browser games must load quickly and run within limited memory, so I kept the project focused and avoided unnecessary systems.
Several choices helped keep the game suitable for WebGL:
- Off-screen obstacles are removed.
- Temporary effects destroy themselves after playing.
- Particle counts have fixed limits.
- Imported textures use compression.
- Large sprite dimensions are restricted.
- Expensive camera post-processing is disabled.
- Unnecessary URP textures and features are disabled.
- The project targets 60 frames per second.
- WebGL data caching and compressed build output are enabled.
The default WebGL canvas is configured at 960 × 600, while the camera and interface adapt to the space provided by the browser.
Before publishing an update, I test the main controls, menus, collisions, scoring, obstacle generation, audio, particles and screen scaling. Browser testing remains especially important because behavior can differ from what is seen inside Unity’s Play Mode.
Suggested image: Magic Carpet Rush running on its Lalo.games page inside a desktop browser.
What I Learned From the Project
The main lesson I took from Magic Carpet Rush is that simple mechanics still require careful development.
The player only needs one main action, but the experience depends on many connected details: gravity, upward movement, collision size, tower spacing, obstacle speed, sound, animation and visual clarity.
I also learned that consistency matters more than adding large numbers of features. The background, carpet, towers, particles and audio all needed to feel like parts of the same world.
Finally, resolving small issues early made the project easier to maintain. A repeating Console warning, an unsuitable particle color or a visible background seam may appear minor individually, but together they can noticeably reduce the quality of the finished game.
Ideas for Future Updates
There are several ways I could expand Magic Carpet Rush:
- Additional carpet designs
- Unlockable cosmetic rewards
- More obstacle formations
- Alternative fantasy environments
- Multiple difficulty modes
- Persistent lantern totals
- Improved accessibility settings
- More detailed browser and device testing
- Object pooling for frequently generated obstacles
- Additional progression and achievement systems
Any future additions should preserve what makes the current version approachable: immediate controls, short sessions and quick restarts.
Final Thoughts
Developing Magic Carpet Rush allowed me to combine Unity physics, endless obstacle generation, responsive controls, procedural audio, particle effects, runtime UI and WebGL optimization in one focused project.
The final experience is deliberately easy to understand: keep the carpet in the air, pass through the towers, collect lanterns and try to beat your best score.
You can play Magic Carpet Rush on Lalo.games and see how far you can fly above the golden fantasy city.
Frequently Asked Questions
What engine was used to develop Magic Carpet Rush?
I developed the game using Unity 6000.3.15f1 with C# and the Universal Render Pipeline 2D Renderer.
How do you control the magic carpet?
Players can use Space, the Up Arrow, a mouse click or supported touch input. Each action pushes the carpet upward while gravity pulls it down.
Are the obstacles manually placed?
No. The tower formations are generated continuously during gameplay, and the vertical position of each opening is randomized.
How is the best score saved?
The highest score is stored locally using Unity’s PlayerPrefs system.
Does the game use imported music?
No. The music and sound effects are generated at runtime through C# and Unity’s audio system.
About the developer: Ismail Ettabani is the developer of Magic Carpet Rush and the creator of Lalo.games, where he develops original browser games and publishes online gaming content.