Platformer in Unity
Role
Level designer
Date

A lantern that takes your double jump away
For two weeks I built a 2D platformer level in Unity for my Level Design track. The brief asked for a level made of three chunks, justified with theory, and then implemented in the engine.
There is a single mechanic, and the whole level grows out of it:
Colored lanterns lie around on the floor. Each one turns the geometry of its own color visible and solid. But if you carry it, you lose your double jump, and you can only pick it up or put it down with your feet on the ground.
That rule holds up the entire level: seeing and moving are resources that compete. To cross, you need to see the path. To jump that path, you need to drop the lantern. And the moment you drop it, the path disappears.
The finished level, start to finish, no cuts, speed x3.
What was being graded
Structure. Three distinct chunks, connected into a route you can read.
Quantic Foundry. Primary: Mastery / Strategy. Secondary: Achievement / Completion and Creativity / Discovery.
Uncertainty. Primary: Solver's. Secondary: Hidden information and Performative.
Communication. Affordance, anti affordance, signifier and false affordance, with concrete examples inside the level.
How this is told
I recorded all four working sessions as a 50x timelapse. They are not a tutorial. They are the raw process, mistakes included. Each entry below is one session, in order, with its video.
One thing I think is fair to say up front: I used an AI as a programming assistant throughout the whole process. In the first sessions I wrote the code myself, line by line, learning what a MonoBehaviour was and why a period is not a comma. Later I delegated more and more of the code so I could focus on what was actually being graded here: the level design, the diagram and the spatial decisions.
I mention it because the process is the point of this post.
01: can this even be built?
The idea did not come out of nowhere, and it was not born for this assignment. It came out of an earlier class exercise I did with a classmate, Gastón. The brief there was to design a level whose uncertainty quality was hidden information. While looking for a way to satisfy that constraint, we came up with an object that reveals platforms. Everything else grew from there.
The problem was that I had opened Unity once or twice in my life, barely scratching the surface. So the first session was not about design. It was about finding out whether the idea existed or was just talk.
What had to be validated
The mechanic depended on light being able to reveal three different things at once:
Ground. Tiles you walk on.
Platforms. Geometry that appears in midair.
Levers. Interactive objects that are hidden until lit.
If it only worked for one of the three, the level I had in my head could not be built.
How it ended up working
Two components that talk to each other without knowing each other:
A lantern script that registers itself in a static list when it is enabled, and exposes a single question: is this point lit by a lantern of this color?
A revealable block script that asks that question every physics step and switches its sprite and its collider on or off together.
What matters is that the block knows nothing about lanterns, and the lantern knows nothing about blocks. That is what later let me paint entire levels with tilemaps without touching a line of code.
What I learned that day
Basic things I did not know, and that stopped me cold:
What a MonoBehaviour is, and why the file name has to match the class name.
That
transform, positionwith a comma is nottransform.positionwith a period, and that the period means belongs to.
50x timelapse. The first scripts, written by hand.
02: the script before the engine
Once I knew the mechanic worked, I spent the whole second session without opening Unity. I used it to write the level script: what I had to deliver, how, and what I wanted the player to feel in each stretch.
I went back over my class notes and forced myself to answer three questions by name.
What kind of player am I after
I used the Quantic Foundry model. I picked Mastery / Strategy as the primary motivation, because the level is solved by thinking before moving, not by reacting fast.
For secondary motivations I chose Achievement / Completion and Creativity / Discovery. The coins sit deliberately off the critical path: to grab them you have to drop the lantern and get your double jump back, so completing competes with advancing instead of going along with it.
What kind of doubt do I want to create
This one was easy, because it is what I like to play: Solver's uncertainty. The doubt is not can I make this jump? but how on earth is this solved?
I was very interested in the there and back puzzle: leave the lantern on one side so you can see, cross in the dark, trigger something, and come back for it. As secondary types I added Hidden information, since the geometry exists but is unknowable until light touches it, and Performative, which is the timed traps in the third chunk.
How do I split it into three
I got this wrong, and the correction was a good one.
I had planned three chunks that repeat: lantern, blocks, traps, and then the same three again, now with two lanterns. I liked the idea that the second pass would reuse the same space with the rules already learned.
Talking it through with my professor, it became clear that from the outside those are not three chunks walked twice. They are three large chunks: first part, second part, and ending. The real structure of the level was that one, not the one in my head.
The finished script was a drawn map with the intended route, built so I could later paint it straight into a Unity tilemap without having to decide anything on the fly.


50x timelapse. Writing the script and the diagram.
03: from paper into Unity
The longest and most intense session. I went in with the script finished and came out with the whole level built and playable. Only the respawns, the collectibles and the final door were left out.
While the scripts were being written, I was drawing the map following the script. Having the route decided in advance is what made this fit into a single session.
Painting the level with tilemaps
The trick that saved me the most time: instead of placing revealable blocks one by one, I wrote a script that walks an already painted tilemap and spawns one revealable block per cell, copying the sprite and the sorting layer from the tilemap itself.
That meant I could design with Unity's brush, as if painting ordinary terrain, and the moment I hit Play all of that terrain started depending on light. Redesigning a stretch took thirty seconds instead of fifteen minutes.
The tileset
I used Mines of Sharega, a 16px tileset imported at 40 pixels per unit. That sets the scale for the whole level: every tile is 0.4 world units, and all of the player's jumps are tuned against that measurement.

A short detour into the bugs
This is where the level handed me back things that were invisible on paper.
The trap that vanished. A timed trap stopped existing when it should not have: the lever would turn it off, and when I came back it was not where it belonged. The cause was that the temporary mode followed the lever's state, so every other pull did exactly the opposite thing. The fix was to treat it as a pulse instead of a switch.
The jump that stuck against walls. If you took off while hugging a block, the jump got cut in half. It turned out to be the template's own controller: any collision in midair killed vertical velocity, even a sideways one. I had to touch the movement code so it only kills the jump when the hit is genuinely upward.
The trap you could not stand on. When you disabled it, it became intangible instead of staying solid ground. It needed two colliders: a solid one that is never touched, and a trigger one that is what actually switches on and off. What gets disabled is the damage, not the floor.
50x timelapse. The whole level painted from scratch.
04: the color that lied
There was a class between the third and fourth sessions, so I arrived with feedback from my professor. The good news was that almost nothing needed fixing: the level was already on track. But there was one small change that is worth the whole entry.
The red platforms had to stop being red
My two lantern colors were red and green. It worked, but it had a communication problem I could not see because I was too deep inside the project.
In a platformer, red means danger. It is such an old convention that players do not even think about it. And in my level red meant the exact opposite: safe ground, geometry you are supposed to walk on.
That is an accidental anti affordance. The color was telling the player "do not touch this" about the surface they most needed to step on. Nobody falls because of it, but they hesitate for half a second on every jump, and that hesitation adds up.
I moved it to blue. Blue carries no danger baggage and contrasts just as well against green.
A detail that still makes me laugh: the material in the project is still called
Additive Red, and the enum in the code still saysLanternColor.Red. The only thing that changed was the color value. The rename never made it into the code, and that is where it is staying.
What I added in this session
Collectibles spread off the critical path, which force you to drop the lantern to reach them.
A HUD counter that discovers the total by counting what is in the scene instead of having the number typed in by hand.
An end of level screen with the collectible summary and buttons to restart or quit.
The final door. Two slots, one per color. You have to bring both lanterns and deposit them. Handing them over leaves your hands empty, so you get your double jump back exactly when the level ends.
50x timelapse. Collectibles, UI and the final door.
05: one comment that changed the level
This part is not on video. It happened between the build and the submission, and it is the part of the process I enjoyed most.
I exported a playable build and handed it to classmates. One of them came back with this:
"The timed levers confused me, and frustrated me a little. First because they looked the same as all the others, and second because I had no idea how much time I had left."
Two separate problems in one sentence. I split them and solved them separately.
Problem 1: no sense of how much time was left
A trap disabled for six seconds and one disabled for two look exactly the same. Without that information the player cannot make a decision. They can only always rush, or always wait. That is not difficulty, it is noise.
I added a telegraph. While the trap is disabled it tints with a configurable color and blinks faster and faster until it comes back.
What I cared about was that the pacing not be eyeballed. The frequency comes from a formula over the fraction of elapsed time, never over absolute seconds:
Here p runs from 0 to 1 across the duration, and a is the exponent that controls the acceleration. With a = 2, the halfway point is worth only 0.25: the level stays calm early and piles all of the alarm into the end.
Since there is not a single hardcoded second in there, the same formula works identically at 2 seconds and at 10. I type the number into the Inspector and the warning stretches itself.
A technical detail I am happy with: the blink phase accumulates frame by frame (
phase += frequency * deltaTime) instead of multiplying time by frequency. Because the frequency changes every frame, multiplying makes the blink jump and look dirty. Accumulating is the same thing a synthesizer does to slide pitch without clicks.
Problem 2: the levers all looked the same
I did not fix this one. I turned it into the false affordance I was missing.
Up to that point I had none, and I did not want to force one in. But there was already something happening on its own: in the first part of the level, levers open platforms. Later on, identical levers disable traps.
The player learns a convention without anyone explaining it, and then the level breaks it. That is precisely perceiving a possibility the object does not have.
The difference between an oversight and a false affordance is not in the object. It is in whether the convention was taught first. Since it already was, and since the new blink makes the deception short lived and non lethal, I decided to keep it and document it.

06: what I actually learned
The part of all this that will serve me most is not anything you can see in the video.
The theory is not decoration on the assignment. It is the script.
I used to think of uncertainty and Quantic Foundry as class concepts you quote in a document. Now I use them as a validation tool: they are what gives the game a script before it exists.
The shift in mindset was this. I did not pick a primary uncertainty because the level turned out that way. I picked Solver's first, and that decision forced specific things into the level.
If I want the challenge to be about reasoning rather than reflexes, I need:
Information the player does not have until they do something. Hence the invisible blocks.
A resource that cannot be in two places at once. Hence a single lantern you leave on the ground.
A cost for being wrong that is walking back, not dying. Hence the first two chunks having no traps.
None of those three would have occurred to me on their own. They came from taking the label seriously.
The secondary ones are what make the game complete
The same goes for the secondary choices, and this is what surprised me most.
When I added Performative as a secondary uncertainty, that demanded new mechanics. The timed traps were not in the original plan. They showed up because I needed a stretch where the player knows exactly what to do and doubts whether their hands will keep up.
When I added Achievement / Completion, that demanded the collectibles, but not just anywhere: off the critical path, so that gathering them competes with advancing.
Every axis you add asks you for tools, elements or mechanics to hold it up. That is what makes the game more complete, as long as they all point at the same focus.
The target audience is a compass, not paperwork
Defining the audience at the start stopped being a box to tick.
I know I am aiming at people who play puzzle platformers, who enjoy conditional geometry, and who score high on Mastery. Knowing that, I already know what to look for and what to add, and also what to leave out. I do not need combat, or constant time pressure, or anything social.
What I take away as a working rule: do not forget to include the mechanics that audience expects. Not to please everyone, but because if you already know who you are designing for, leaving that out wastes the only hard data you have.
Understanding why games are the way they are
Mechanics are not there for no reason. Each one is holding up something the game is trying to produce. When you have to build instead of analyze, that relationship becomes obvious: if you want a particular feeling, you have to put particular elements in, and if you remove one the feeling falls apart.
I play differently now. I see a mechanic and I ask myself what it is holding up.
Unity
And the most concrete lesson: I had opened Unity once or twice in my life, barely scratching the surface.
With the fundamentals properly understood and an AI as an assistant, I finished a complete, working level in two weeks. I did not become a programmer. But Unity stopped being a wall between the idea and the playable thing.
That, for me, is the biggest thing I take away: the tool no longer decides what I am allowed to design.
Play it
The level is up on itch.io. It is free, Windows only, and runs about 10 minutes.
Controls: A and D or the arrow keys to move, Space to jump, E to pick up, drop or deposit a lantern, F to pull a lever. Remember that the double jump only works with empty hands.
Download the .zip and extract it before running. The .exe needs its _Data folder next to it.

