---
title: "Explaining the Magelight XP glitch in Skyrim"
slug: explaining-the-magelight-xp-glitch-in-skyrim
url: https://listedarticles.com/articles/explaining-the-magelight-xp-glitch-in-skyrim
canonical_url: https://blog.alexbeals.com/posts/explaining-the-magelight-xp-glitch-in-skyrim
content_type: blog_post
language: en
published_at: 2026-10-06T20:16:39.000Z
updated_at: 2026-10-07T11:11:01.188Z
author: "Vox Silva"
authored_by: human
publisher: "Vox Silva"
publisher_url: https://blog.alexbeals.com/
topics: ["Programming", "Systems Programming", "Culture"]
license: all-rights-reserved
word_count: 2494
reading_minutes: 11
citation: "Vox Silva, Vox Silva. \"Explaining the Magelight XP glitch in Skyrim.\" 6 Oct 2026. https://blog.alexbeals.com/posts/explaining-the-magelight-xp-glitch-in-skyrim (all-rights-reserved)"
# The full text follows. The web page shows an extract and sends readers
# to the source above; quote the citation and link the canonical URL.
---

# Explaining the Magelight XP glitch in Skyrim

> A reverse-engineering deep dive into why casting Magelight from a mountain outside Solitude grants huge Alteration XP in Skyrim. It debunks the distance and cloud-layer theories, traces how the projectile's collision and XP grant work in the game code, breaks down the bug, and gives a consistent setup guide to maximise it.

# Explaining the Magelight XP glitch in Skyrim

There's a place in Skyrim right outside the capital city, Solitude, where if you cast Magelight at the top of a mountain, you get *tons* of XP in Alteration — enough to [level you from 15 to 25](https://www.youtube.com/watch?v=eJU23Wy1EFU) in just one cast. But why?

There's a lot of wrong explanations for why this works, but the main one is some version based on how far the target is:

"Magelight grant XP on arrival based on how long it travelled. What you have found is a place where you are on the near edge of render distance, but there are tricks to increase it even further." - [@Jewbacca1991](https://www.reddit.com/r/skyrim/comments/11zdiyc/comment/jdc7bme/)


But as [others](https://www.reddit.com/r/skyrim/comments/1wywoga/comment/pe94e6f/) [quickly](https://www.reddit.com/r/skyrim/comments/1bm9rec/comment/kx80dvv/) [point](https://www.reddit.com/r/skyrim/comments/11zdiyc/comment/lv92u1g/) [out](https://www.reddit.com/r/skyrim/comments/11zdiyc/comment/lafv3ab/), it doesn't work for other far distances: something seems to be special about *this* mountain. The [UESP Skyrim wiki](https://en.uesp.net/wiki/Skyrim:Alteration#Magelight:~:text=The%20large%20XP%20gains%20at%20this%20location%20seem%20to%20be%20related%20to%20passing%20through%20multiple%20planes%20of%20weather%20effects) claims that it's because of the cloud layers that you can see:

"The large XP gains at this location seem to be related to passing through multiple planes of weather effects."


But there are plenty of cloudy mountains where this doesn't work. Let's reverse engineer the Magelight XP formula to put this to rest.

## How Magelight grants XP

Magelight is an Apprentice level spell. Loading it up in [TES5Edit](https://www.nexusmods.com/skyrim/mods/25859) we can see that it has a Magnitude of 5, a Duration of 60, and a base effect of `LightFFAimed`, or `0001EA6D`. If we load that effect we can see it has a Base Cost of 2, and a Skill Usage Multiplier of 0.15.

This all gets used to calculate the Skill Usage value. Because there's no Area for the spell it quickly simplifies:

$$ \begin{aligned} Skill\_Usage &= Base\_Effect\_Cost \times Area \times (Magnitude \times \frac{Duration}{10})^{1.1}\newline &= 2 \times 1 \times (5 \times \frac{60}{10})^{1.1}\newline &\approx 84.307 \end{aligned} $$

The Alteration XP takes this, multiplies it by the Skill Usage Multiplier (0.15 for Magelight) and then by the Skill Use Mult ([3 for Alteration](https://en.uesp.net/wiki/Skyrim:Leveling#Skill_XP)) for a raw XP of 37.938 per cast.

### Validating in game

Ideally we'd cast Magelight at a wall and see if this gives the expected amount of XP. Unfortunately there's no way in game (even using console commands) to get the exact XP. Luckily we can use [Cheat Engine](https://www.cheatengine.org/) to read the underlying memory directly with Lua.
<sup>1</sup>
You may remember Lua (my favorite programming language downstream of Brazilian oil companies) from my [previous post speedrunning Harry Potter 1 for the GBA](https://blog.alexbeals.com/posts/harry-potter-anatomy-speedrun#using-lua).

```
-- (Set the player's Alteration level to 15 with a console command)
-- player.setav alteration 15
-- Set the overflow XP to 0
local ALTERATION = 18
local player = readPointer(0x01B2E8E4)
local skills = readPointer(readPointer(player + 0x614))
local entry  = skills + 12 * ALTERATION - 0x40
writeFloat(entry + 4, 0)
print(string.format('Alteration XP: %.3f', readFloat(entry + 4)))
-- <Cast the spell>
-- Read out the current XP
print(string.format('Alteration XP: %.3f', readFloat(entry + 4)))
```
If we run the above script
<sup>2</sup>
I swapped to using the VEH debugger with 

But none of this incorporates distance. Why are we getting so much more than 38 XP?

## Reverse engineering when the XP grant runs

Magelight is unlike most other spells because it doesn't need to hit a person — it'll work, but it also works to cast it at a wall or a table or a rock. It grants XP in all of these cases, so how does it know when it hits something?

### How collision works

Casting the spell creates a `LightSpellProjectile` that travels along a path based on where you originally aimed it. Each tick it checks if it's collided with something, which roughly follows these three steps:

**Draw a path for where the object will move in the next tick** (`0x007A0090`)

It takes the speed of the projectile (512 units/s) and divides by your frame rate (60 fps
<sup>3</sup>
And yes, this means that the collision check rate is lower if you're playing on old Xbox consoles, and higher if you've cranked this above the normal value. It *also* goes higher if you use the [Slow Time shout](https://elderscrolls.fandom.com/wiki/Slow_Time) or use the Archery/Block perks to slow time, though collisions/s stay the same.
) to get $\frac{512}{60} = 8.5\bar{3}$ units/tick in the direction you cast in. The spell has a range of 10,000,
<sup>4</sup>
Again determined by the ESM file, though it wasn't in the above screenshot crop. Whoops.
 so it will continue along its path for $\approx 19.5$ seconds before it vanishes.

**Intersect that path with every object that has a collision shape and passes the collision layer filtering.** (`0x00DE0040`)  

Every object in the game has a collision layer which defines what it collides with (for instance `L_TRANSPARENT` won't stop projectiles or spells where `L_TERRAIN` will). If they don't match, a collision won't fire.

**Check if the path hit the object.** (`0x00EC41C0`)  

First, it finds the closest point on the surface of the object to the projectile. Then it finds the normal vector that points away from the surface with that closest point.

*Shown here on a rectangular prism, though there are much more complex normal maps for things like rocks or castles*

It then checks if the projectile is going in the same direction as the normal.
<sup>5</sup>
It does this by checking if the [dot product](https://en.wikipedia.org/wiki/Dot_product#Geometric_definition) is positive or negative. Yay math!
 If they are, it's moving *away* from the surface, so it says there's no collision. If they're moving in opposite directions then it flags a collision if it's already intersecting or inside of the object, or if it will hit it in this next tick step.

Note that even if the projectile is *inside* the object the normal check comes first: if it's made it over halfway through the object, such that the closest point is on the far side and the normal is in the same direction as movement, then it stops triggering collisions.

### What happens when it collides with something

Once the `LightSpellProjectile` has collided with something (or multiple things) it runs an "OnHit" function (`0x007A30FD`) for each collision, triggering what's supposed to happen. The function handles a lot of things that aren't relevant for Magelight
<sup>6</sup>
Like [wards](https://en.uesp.net/wiki/Skyrim:Ward) blocking spells at `0x006ECE30` or targets getting knocked back by Destruction spells at `0x006E99D0`.
 but finally either applies the effect to a person
<sup>7</sup>
Technically a magic target, which also includes stuff like activation triggers.
 (`0x00664740`) or the collision surface. Most single-cast spells handle the XP award as part of the person branch, but there's a special check at `0x00660353` that handles giving XP for spells that can handle alternative targets, like Magelight.
<sup>8</sup>
Actually not *like* Magelight, *just* Magelight. Technically it's all Reanimate and Light spells, but all of the [Reanimate spells](<https://en.uesp.net/wiki/Skyrim:Reanimate_(spells)>) override this location to just grant XP when you raise the body from the dead, and the only other Light spell is [Candlelight](https://en.uesp.net/wiki/Skyrim:Candlelight), which isn't a projectile.

Finally "OnHit" adds the impact at `0x007A2560`. It makes sure it only runs once, and checks the material that was hit to run accordingly (attaching to a person, for instance, or just floating near the wall for a wall). If there is no material, or it's an unsupported material, then no impact event happens.

### Stopping the projectile

Everything that's been described so far seems to work, and it mostly does, but here's where it breaks down. After colliding with something and running "OnHit" the code runs a "HandleHit" function to determine if the projectile should keep going or not. Usually it will stop the projectile, but there are two exemptions: it will keep going if it collides with something 1) non-corporeal
<sup>9</sup>
To be more specific, [`BROAD_PHASE_PHANTOM`](https://geckwiki.com/index.php?title=BhkRigidBody#:~:text=by%20most%20NIFs.-,BROAD_PHASE_PHANTOM,-Used%20by%20NIFs) from Havok's collision code, which is used for triggers (stuff like "if you walk here activate the trap/cutscene/dialogue"). This check happens at `0x0079f022`.
 or 2) has the layer type 26 or 28, which corresponds to `L_TRANSPARENT_SMALL` and `L_TRANSPARENT_SMALL_ANIM`.
<sup>10</sup>
This exemption is at `0x0079f063` if you're ~~curious~~ future me looking for proof.


`L_TRANSPARENT`, which doesn't collide with `L_SPELL`
*does*

`L_TRANSPARENT_SMALL`, which *collide with*

`L_PROJECTILE` and `L_SPELL`
Because `L_TRANSPARENT_SMALL` 'collides' with projectiles and spells in its collision layer, the surface continually registers collisions without stopping the projectile, leading to the bug.

## The bug breakdown

You cast Magelight until it enters a bounding box with `L_TRANSPARENT_SMALL`. That collision layer collides with `L_SPELL` so it counts as a collision. It's not a person or magic target, so it hits the fallback path and awards 38 XP. But `L_TRANSPARENT_SMALL` is exempt from the "HandleHit" and so the projectile keeps going. Next tick, same thing happens. It's in the bounding box, it counts as a collision, it awards 38 XP. It will keep doing this until the closest point has a normal in the same direction that it's going, which is roughly when it's gone halfway through.

But where are the `L_TRANSPARENT_SMALL` objects? You guessed it: the mountain right near Solitude.
<sup>11</sup>
Ï made the walls visible using a quick mod built off of the [Skyrim Creation Kit](https://store.steampowered.com/app/1946180/Skyrim_Special_Edition_Creation_Kit/), but you can do the same thing with .esm tweaks to add a debug color for the collision layer.

There are some other places that have it, like the sides of [High Hrothgar](https://en.uesp.net/wiki/Skyrim:High_Hrothgar):

Or around the statue in [Irkngthand](https://en.uesp.net/wiki/Skyrim:Irkngthand#Irkngthand_Sanctuary) at the conclusion of the Thieves' Guild questline:

Or as very thin planes surrounding the [Thalmor Embassy](https://en.uesp.net/wiki/Skyrim:Thalmor_Embassy):

But the biggest ones are all next to Solitude, which is why you have to cast at *that mountain*, not just *any* cloudy mountain that's far away.

## How to maximize

Most of the guides say to aim at the top of the mountain, but what you actually want to aim at is whatever line maximizes the amount of time that the spell will be passing through the `L_TRANSPARENT_SMALL` blocks (and in the right sections of them). The mountain is good, but we can do better.
<sup>12</sup>
The top of the mountain gives ~280 triggers vs. ~850 in the optimal place. 

Ï quickly
<sup>13</sup>
And I mean *quickly*, Claude Opus 5.5 two-shot the mod in about 10 minutes with only one screenshot to show what was wrong.
 wrote a mod using [SKSE](https://skse.silverlock.org/) that would render the invisible walls and react to where you were aiming the spell, dynamically calculating the number of expected XP triggers as well as the optimal angle to maximize XP gain. Just walking around the area quickly found the optimal location.
<sup>14</sup>
A lot of math also found the 'optimal' location, but it was underground and inaccessible. Ideal.

To get from Level 15 to Level 100 Alteration you need $\sum_{L=15}^{99} 2 * L^{1.95}$ = [528,804.0234 XP](https://en.uesp.net/wiki/Skyrim:Leveling#Skill_XP). At 37.938 XP per trigger, that's almost 14,000 triggers, so a line that does 250 triggers vs. 850 triggers is the difference between 55 casts and 17 casts. The key bit, though, is a consistent repro—it's all good to say "aim at this spot in the sky" but people can't follow that. So here's a followable guide!

### Consistent setup guide

Start by traveling to Solitude and then exiting the main door, so you're right outside. We're going to want to get up on the rock to the left. There's an invisible wall there, so line up against it and the castle wall in the farthest corner.

We're going to be aiming at the mortar line of the top left brick of the wall we're pressed up against.

To get the right angle we're going to **crouch**, and then line up the center of our crosshair with that mortar line (optimal line is the top left corner of the brick one to the right, but there's some leeway).

We're then going to strafe forward and left so we're pressed up against the invisible wall the whole time, keeping our angle consistent. This will show the two lines of the castle wall from the different pieces.

Our goal is to strafe back until the second line has *just* been hidden again. At this point you should be staring at a seemingly random patch of sky.

Cast away!
<sup>15</sup>
 [I got to level 100 in 17 casts in 1 minute and 15 seconds. If you'd prefer a video walkthrough, I](https://blog.alexbeals.com/images/explaining-the-magelight-xp-glitch-in-skyrim/29.jpg) [uploaded one to YouTube](https://www.youtube.com/watch?v=leJqh3Dzcqo).
<sup>16</sup>
I used Claude's computer use for the first time to build in support for the Skyrim-themed UI popups in DaVinci Resolve and watching it work was yet another "this is magic" moment. Perfect for one-offs.

With this, hopefully, *hopefully*, I'm done with Skyrim.

1. 
You may remember Lua (my favorite programming language downstream of Brazilian oil companies) from my [previous post speedrunning Harry Potter 1 for the GBA](https://blog.alexbeals.com/posts/harry-potter-anatomy-speedrun#using-lua) .[↩︎](https://blog.alexbeals.com#fnref1:lua)
2. 
I swapped to using the VEH debugger with Edit >Settings >Debugger method , though I'm not sure that's necessary.[↩︎](https://blog.alexbeals.com#fnref1:script)
3. 
And yes, this means that the collision check rate is lower if you're playing on old Xbox consoles, and higher if you've cranked this above the normal value. It *also* goes higher if you use the[Slow Time shout](https://elderscrolls.fandom.com/wiki/Slow_Time) or use the Archery/Block perks to slow time, though collisions/s stay the same.[↩︎](https://blog.alexbeals.com#fnref1:fps)
4. 
Again determined by the ESM file, though it wasn't in the above screenshot crop. Whoops. [↩︎](https://blog.alexbeals.com#fnref1:range)
5. 
It does this by checking if the [dot product](https://en.wikipedia.org/wiki/Dot_product#Geometric_definition) is positive or negative. Yay math![↩︎](https://blog.alexbeals.com#fnref1:dot)
6. 
Like [wards](https://en.uesp.net/wiki/Skyrim:Ward) blocking spells at`0x006ECE30` or targets getting knocked back by Destruction spells at`0x006E99D0` .[↩︎](https://blog.alexbeals.com#fnref1:wards)
7. 
Technically a magic target, which also includes stuff like activation triggers. [↩︎](https://blog.alexbeals.com#fnref1:person)
8. 
Actually not *like* Magelight,*just* Magelight. Technically it's all Reanimate and Light spells, but all of the[Reanimate spells](<https://en.uesp.net/wiki/Skyrim:Reanimate_(spells)>) override this location to just grant XP when you raise the body from the dead, and the only other Light spell is[Candlelight](https://en.uesp.net/wiki/Skyrim:Candlelight) , which isn't a projectile.[↩︎](https://blog.alexbeals.com#fnref1:reanimate)
9. 
To be more specific, [`BROAD_PHASE_PHANTOM`](https://geckwiki.com/index.php?title=BhkRigidBody#:~:text=by%20most%20NIFs.-,BROAD_PHASE_PHANTOM,-Used%20by%20NIFs) from Havok's collision code, which is used for triggers (stuff like "if you walk here activate the trap/cutscene/dialogue"). This check happens at`0x0079f022` .[↩︎](https://blog.alexbeals.com#fnref1:phantom)
10. 
This exemption is at `0x0079f063` if you're~~curious~~ future me looking for proof.[↩︎](https://blog.alexbeals.com#fnref1:layer)
11. 
Ï made the walls visible using a quick mod built off of the [Skyrim Creation Kit](https://store.steampowered.com/app/1946180/Skyrim_Special_Edition_Creation_Kit/) , but you can do the same thing with .esm tweaks to add a debug color for the collision layer.[↩︎](https://blog.alexbeals.com#fnref1:mod)
12. 
The top of the mountain gives ~280 triggers vs. ~850 in the optimal place. [↩︎](https://blog.alexbeals.com#fnref1:xp)
13. 
And I mean *quickly* , Claude Opus 5.5 two-shot the mod in about 10 minutes with only one screenshot to show what was wrong.[↩︎](https://blog.alexbeals.com#fnref1:quickly)
14. 
A lot of math also found the 'optimal' location, but it was underground and inaccessible. Ideal. [↩︎](https://blog.alexbeals.com#fnref1:optimal)
15. 
[↩︎](https://blog.alexbeals.com#fnref1:cast)
16. 
I used Claude's computer use for the first time to build in support for the Skyrim-themed UI popups in DaVinci Resolve and watching it work was yet another "this is magic" moment. Perfect for one-offs. [↩︎](https://blog.alexbeals.com#fnref1:claude)
