To explain it with more rigor, here is how it seems to work :
- before you enter a Perl script, the individual qglobals $XXX variables are loaded in the Perl interpreter for this zone server. Any variable defined in qglobals is set with its value from the DB, for this character (accounting for timestamps, NPC-specific variables etc)
- the $qglobals map is also initialized ANEW, at the same time (the ANEW is important here, the $qglobals starts from scratch for each script interpretation)
- there is a good chance that the Perl interpreter is reused as-is in the next script, to reduce CPU-load. The qglobals for the new PC/NPC are simply reloaded FOR THE VALUES DEFINED, but nothing is undefined as it is a complex problem to know what variables need to be undefined in the global store.
The real problem is "stale" variables from the previous PC. They are not undefined in the Perl interpreter before switching to the next PC/NPC. The $qglobals variable is not undefined either, but as it is overwritten each time with the full qglobals map (which is computed from an empty map for each script) it does not have any noticeable effect. This is why the $qglobals map is more reliable.
One test you could make to validate this assumption is : have two PCs of different levels (say 72 and 74) do the delevel quest. Their $max_level will be set to the appropriate value. If they do the turn-in they will both return to their proper level, because the variable is defined for them. Then have a level 70 character do the delevel-relevel. As its $max_level will not be set (you can see it in the DB), it should use the $max_level of the previous PC for this zone server.
Doing a #reloadquest reinitializes the Perl interpreter so the "stale" variables are removed (and the problem hidden).
I had a similar problem with temporary variables that were not erased unless I undefined them forcefully. Looks like using $qglobals will avoid this forceful deletion. I will try it when I am back to that point in my tools
Validating that (on another server than mine) would be a clear indication that $qglobals is a must from now on.