The Written Difference
usr can be thought of as the user the that initially started the whole action. Or, the user who called a procedure.
src can be thought of as the source of the current level of procedures. It is what owns the current section of code that is happening and also what the procedure is called on.
Some Examples
In these examples, I will take some scripts from the Developer Help section and modify them to help you learn the difference.
obj/GUI
Self_Destruct
icon = 'boom.dmi'
icon_state = "explosion"
layer = 5
Click()
usr.self_destruct()
Quiz:
If Player 1 clicks the Self Destruct button, who is src and who is usr?
Answer (highlight/copy&paste to see):
src: The Self Destruct button
usr: Player 1
This is because Player 1 is the person who initiated the clicking. Therefore, they are the usr. Whereas src is the source of the procedure, the button. The button owns the Click() procedure and is deemed src.
mob/verb/Attack()
... //Perform attack script here
//M = Player 2 in front of Player 1
M.DeathCheck()
mob/proc/DeathCheck()
... //Perform calculations for death verification.
usr << "This is the example message 1."
src << "This is the example message 2."
Quiz:
If Player 1 clicks the Attack verb and DeathCheck() is called on Player 2, who is usr and who is src? Who gets message 1 and who gets message 2?
Answer (highlight/copy&paste to see):
usr: Player 1
src: Player 2
Player 1 will get message 1 and Player 2 will get message 2. Because DeathCheck() was called on Player 2, Player 2 now is the source (src) of DeathCheck(). And, as a result of that, Player 1 would have to be the usr that initially called this procedure.
The Twist
There are instances where usr can still be used in a similar instance of src. Lummox JR explains in a previous post when this twist occurs.
Paraphrased from Lummox JR:
Well, everything here is not exactly true. usr is the mob who called the verb. When that verb calls procs in turn, usr gets passed along as a hidden variable and keeps its initial value unless it's modified--including by the mob being deleted.
If you have any feedback on how to make this post more clear, feel free to comment below. I hope this post frees up any confusion and helps newcomers better understand the difference between the two. It really is a big difference.
Much later, though, I noticed a trend. People who don't understand the difference between usr and src often run into problems like this.
Now, this of course will give you compiler errors. This is because usr is cast as /mob, not /mob/player. Since show_menu is defined under /mob/player, the variable access is not valid on usr.
The two most common ways that people avoid this problem, is by using the ":" look-up operator, or by moving all variable definitions under /mob. This results in all player-specific variables being available to all mobs in the world --which is quite confusing and wasteful.
Basically, people who use usr wrongly are also committing other sins like improper embedding of members, failure to perform proper typecasting, and other such issues.
Usr abuse isn't so much a problem in itself so much as a symptom of bad habits that can potentially lead to worse habits.