usr seems to be the main misconception of the langauge and is dangerous to be used even in places which are "safe" since the exact nature of what usr is is dependant on the what initiated the starting call of the callstack leading up to usr's use.
For instance
mob/say(msg as text)
world << "[usr]:[msg]"
Here usr for the most part won't pose any problem since say() will be the top of the callstack if a player uses it. Of course the issue then comes up when you call the verbs as procs say for the AI.
mob/NPC/SayHello()
say("Hello World!")
In any decent object oriented programming scheme this should work fine since you should be able to treat like objects in the same fashion. But here since usr was used in say() it has unwanted and undefined results(ie what exactly happens depends on what procs were run before SayHello()). This is very bad since any time usr is required(like verbs from objects which players can call like get) can't be made in a robust way so the best way to handle the situation is to make a proc and pass in usr as the parameter and never call the verb directly. While this works it makes the code look tacky with a bunch of what appears to be duplicate procs(ie: get() and Get(), equip() and Equip(), etc).
I think a good work around to the problem is in cases where usr is neccessary an optional(and unaccessable to dream seeker clients) parameter is tacked to the end of the verb which defaults to what usr would normally be. Then if you need to call this verb from a proc you can pass in the appropriate initiator of the action and get results which aren't determined by the base of the callstack. Then you could saftely remove usr from the language and the world would be a happier place.
ID:135531
![]() Jul 2 2004, 2:49 pm
|
|
![]() Jul 2 2004, 7:27 pm
|
|
Just because it causes confusion doesn't mean it should be removed. I think a better solution would to have a little "tip of the day, which actually isn't for today, but is instead based on the number of times you have opened this program" that pops up and points out a number of useful tips, the first (and second and third) would point out where usr is and isn't acceptable.
|
Better than usr in procs
I used url tags, but accidentally typed usr. I laughed, correct myself, then realized that <url> is not a tag. |
Theodis wrote:
This is very bad since any time usr is required(like verbs from objects which players can call like get) can't be made in a robust way so the best way to handle the situation is to make a proc and pass in usr as the parameter and never call the verb directly. While this works it makes the code look tacky with a bunch of what appears to be duplicate procs(ie: get() and Get(), equip() and Equip(), etc). If you fon't like the verb calls proc system, you can also set usr manually for NPCs before calling their verbs. Then you could saftely remove usr from the language and the world would be a happier place. The main problem is that a change this massive would break nearly every existing BYOND game. Dantom tries to insure compatibility between BYOND versions, and I don't see them ever axing something so integral to the basic operation of DM. |
Just because it causes confusion doesn't mean it should be removed. Not only does it cause confusion but any verb/proc or whatever it's used in is incapable of being robust. It's NOT good for any clean solution which is why it's a shame you need to use it in certain cases for the sake of more sensible verb argument listings which is why I say it should be passed into the verbs/procs as a parameter at the end which player don't have access to when typing out the verb. This would make verbs cleaner and reusable for AI code rather than having to have a seperate set of procs for AI interactions with objects/mobs. |
Shadowdarke wrote:
The main problem is that a change this massive would break nearly every existing BYOND game. Dantom tries to insure compatibility between BYOND versions, and I don't see them ever axing something so integral to the basic operation of DM. Makes me wonder how much BYOND could be improved (since I'm sure Dan and Tom have gained a lot of experience since they started) if that weren't the case. If Dantom stopped worrying about the old games and just improved BYOND because of it, would it be worth it? |
Theodis wrote:
While this works it makes the code look tacky with a bunch of what appears to be duplicate procs(ie: get() and Get(), equip() and Equip(), etc). I don't have enough proper coding background to be a great judge of what's stylistically ideal, but I find that more often than not I'm wanting to do this anyways, because for virtually any action that can be performed both by player input and forced by other procedures I generally prefer to have slightly different functionality for either case, and splitting things up into multiple procedures actually means less redundancy (I do try to keep my verb/proc names slightly more descriptive than that, though). I think a good work around to the problem is in cases where usr is neccessary an optional(and unaccessable to dream seeker clients) parameter is tacked to the end of the verb which defaults to what usr would normally be. Then if you need to call this verb from a proc you can pass in the appropriate initiator of the action and get results which aren't determined by the base of the callstack. Not an expert, but can't you set usr manually to accomplish the same effect? From the DM reference: "Essentially, usr is an implicit parameter that is passed to every proc or verb. Each procedure inherits the value from its caller." mob/hypnotize(mob/target as mob in world) usr = target target.say("Cluck cluck! I'm a chicken!") |
If you fon't like the verb calls proc system, you can also set usr manually for NPCs before calling their verbs. Would be fine and dandy if BYOND didn't play with usr for you to protect those who are incorrectly using it :P. Try out this segment of code and watch as behind your back BYOND changes the usr on you! world The main problem is that a change this massive would break nearly every existing BYOND game. Yes it would break most game but any game that had been doinging things properly shouldn't take much work to fix. There have been several times in the past my code has been broke from radical changes like when they changed how BYOND parses and recogonizes different scopes, when they changed savefiles to work more like C++ streams, and when they changed how new worked(though it just gave you a warning that you were using the old style new format). There was good cause to make radical changes and the same applies here. usr feels like it was thrown in as a hack to clean up verbs from the client side. Dantom tries to insure compatibility between BYOND versions, and I don't see them ever axing something so integral to the basic operation of DM. It took me forever to clean up all the indentation problems in my original CTF game :P. |
Not an expert, but can't you set usr manually to accomplish the same effect? From the DM reference: "Essentially, usr is an implicit parameter that is passed to every proc or verb. Each procedure inherits the value from its caller." As noted in my other post BYOND changes usr behind your back. This would be fine and dandy if this was documented so you could plan for it but it isn't so I'm not sure if it's just a bug or a hack to keep poorly programmed DBZ games working :P. |
If Dantom stopped worrying about the old games and just improved BYOND because of it, would it be worth it? I think so since first of all usr is defined as "The only time usr is assigned for you is when a player (in Dream Seeker) executes a verb, clicks something with the mouse, or any other such action. " So it's dependant on how the current call stack was started which means you can't be sure what or who usr is(and if you have the actual object to test it against why bother with usr :P?) Next you have the fact that there is a lot of usr behaviour that's not even defined in the reference such as usr getting set equal to src in New() which shouldn't even be a possibility since this action wasn't spawned by a player action. That also gets rid of what usr used to be until after New() is finished(and yes that's finished not in the default action). So if you tried to do the trick of setting usr beforehand to get access to the right usr in verbs from within New() you're screwed and it makes no sense that BYOND would even do this because you already have src so there is no need to change usr at all. New() is also just one of the many functions that does things like this making usr unreliable as an implicit variable and as a means of getting verbs to work right when not directly called from the player. This makes usr unreliable, unpredictable, and pretty much meaningless except in a verb directly called by a player. Which means you can't reliably use this verb except with rigorous testing to make sure BYOND doesn't do something behind your back with usr before it gets to the verb. And even then you shouldn't rely on it because it's undocumented which leads me to believe that it's either a bug or an undocumented feature. If it isn't documented that means it's probably highly subject to change. |
I first believe that it would be a lot messier to have verb arguments that don't act like verb arguments, and second believe that removing usr would result in the majority of programs becoming obsolete and unusable.
|
I first believe that it would be a lot messier to have verb arguments that don't act like verb arguments, It may make the parameter listing have a bit more but it's a lot more reliable than usr and it would certainly clean up any one's source code that is trying to be robust since you'd no longer need a matching proc for every verb. and second believe that removing usr would result in the majority of programs becoming obsolete and unusable. It's already happened several times before, but for good reason just like this. |
Ok how about instead of taking the entirely radical resort of removing usr completly how about letting people define verbs as such.
verb/say(msg as text, usr as mob) world << "[usr]:[msg]" usr could still be used as normal but if you have usr as mob at the end of a verb you can pass in an extra argument which usr would be set as(and if nothing is passed in usr would be what it would normally be for the proc). And client side this argument would completly be ignored when a player is typing out a command. This would clean things up and make verbs safe to be called from elsewhere in your code rather than just safe for players to call. |
Why not, you know, just add a SINGLE LINE OF CODE where you want this to be done?
verb/say(msg as text, newusr as mob) |
That's not usr just randomly changing. The problem is that Move() seems to override the value for usr. That should be looked into.
|
Why not, you know, just add a SINGLE LINE OF CODE where you want this to be done? Heh and let players set the usr :)? |
That's not usr just randomly changing. The problem is that Move() seems to override the value for usr. That should be looked into. No it's not randomly changing but these changes are undocumented and happen in several procs with no way to override the behaviour. |
Then, like I said, it's a problem with built-in procs not properly passing usr, which is obviously not intended behavior.
|
Then, like I said, it's a problem with built-in procs not properly passing usr, which is obviously not intended behavior. And I've reported it several times :P. Odds are it's the only thing holding together most DBZ games since it always sets usr to the one who is moving. Make it null or the appropriate mob and you'll end up breaking a lot of poorly done games. |