<!-- MHonArc v2.4.4 --> <!--X-Subject: Re: [MUD-Dev] Modeling spells/skills as collections of affects --> <!--X-From-R13: pynjerapNphc.uc.pbz --> <!--X-Date: Fri, 12 Sep 1997 21:46:21 +0000 --> <!--X-Message-Id: 199709122034.NAA04454#xsvr3,cup.hp.com --> <!--X-Content-Type: text/plain --> <!--X-Reference: Pine.OSF.3.96.970911143441.11343A-100000#saul7,u.washington.edu --> <!--X-Head-End--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>MUD-Dev message, Re: [MUD-Dev] Modeling spells/skills as collections of affect</title> <!-- meta name="robots" content="noindex,nofollow" --> <link rev="made" href="mailto:clawrenc#cup,hp.com"> </head> <body background="/backgrounds/paperback.gif" bgcolor="#ffffff" text="#000000" link="#0000FF" alink="#FF0000" vlink="#006000"> <font size="+4" color="#804040"> <strong><em>MUD-Dev<br>mailing list archive</em></strong> </font> <br> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] <br clear=all><hr> <!--X-Body-Begin--> <!--X-User-Header--> <!--X-User-Header-End--> <!--X-TopPNI--> Date: [ <a href="msg01197.html">Previous</a> | <a href="msg01199.html">Next</a> ] Thread: [ <a href="msg01185.html">Previous</a> | <a href="msg01220.html">Next</a> ] Index: [ <A HREF="author.html#01198">Author</A> | <A HREF="#01198">Date</A> | <A HREF="thread.html#01198">Thread</A> ] <!--X-TopPNI-End--> <!--X-MsgBody--> <!--X-Subject-Header-Begin--> <H1>Re: [MUD-Dev] Modeling spells/skills as collections of affects</H1> <HR> <!--X-Subject-Header-End--> <!--X-Head-of-Message--> <UL> <LI><em>To</em>: <A HREF="mailto:mud-dev#null,net">mud-dev#null,net</A></LI> <LI><em>Subject</em>: Re: [MUD-Dev] Modeling spells/skills as collections of affects</LI> <LI><em>From</em>: <A HREF="mailto:clawrenc#cup,hp.com">clawrenc#cup,hp.com</A></LI> <LI><em>Date</em>: Fri, 12 Sep 97 12:45:31 -0700</LI> <LI><em>Reply-to</em>: <A HREF="mailto:claw#null,net">claw#null,net</A></LI> </UL> <!--X-Head-of-Message-End--> <!--X-Head-Body-Sep-Begin--> <HR> <!--X-Head-Body-Sep-End--> <!--X-Body-of-Message--> <PRE> In <<A HREF="msg01185.html">Pine.OSF.3.96.970911143441.11343A-100000#saul7,u.washington.edu</A>>, on 09/11/97 at 03:23 PM, Dan Shiovitz <scythe#u,washington.edu> said: >On Thu, 11 Sep 1997 clawrenc#cup,hp.com wrote: >> In <<A HREF="msg01116.html">Pine.OSF.3.96.970905163356.4223B-100000#saul4,u.washington.edu</A>>, >> on 09/05/97 >> at 04:49 PM, Dan Shiovitz <scythe#u,washington.edu> said: >> >> >On Thu, 4 Sep 1997 clawrenc#cup,hp.com wrote: >> >> In <<A HREF="msg00927.html">199708312324.3515400#bedford,net</A>>, on 08/31/97 >[..] >> >I'm still not precisely sure what to do with someone that wears >> >cursed gauntlets of fumbling that make her miss all the time and >> >wields the magic spear Elsinore that always hits its target. >> >> The spear hits its target after the player drops it. >Shoot, why didn't I think of that? I had the advantage of hanging out with an old D&D player who delighted in putting his DM's in such impossible positions. One of his favourite characters was a short fat guy ("Tubolard"?) who could chant certain magic words, with each incantation doubling his size with mass/weight following the cube law. Other than this singular ability, Tubolard was stupid, weak, and generally ineffectual. In one campaign of note the party had proceeded fairly well thru the various trials the DM put them up to, had finally cornered the evil wizard, only to have the evil wizard put his back to the mountain and then shield himself behind an impenentrable wall of magical force. Tubolard's response was to chant his magic words twenty times and then run at the wizard shouting, "Come to Pappa!". It took the DM nearly ten minutes of furious rule book searching and dice rolling to decide what happened when an effectively irresistable force (the charging Tubolard now many miles tall), met an impenetrable wall (the shield). FWLIW the decision was that the wizard died, squished between his wall and the mountain, and the entire party died, crushed under the falling splattered bits of Tubolard as both he and the shield simultaneously gave way in a cloud of improbability particles... The same friend also delighted in playing a stupid, weak, constipated, diabetic incredibly clumsy bard with incredible joke telling talents. In one particular campaign they party was stuck ouside a huge well defended and patrolled fortress containing the evil whatever and the the bauble the party was in search of. The party got busy trying to devise a cunning plot to crawl int hru the sewers, magically hide themselves with various spells while creating various diversions etc. Meanwhile the bard walked unhindered into the evil whatever's fortress disabling every guard, monster, and even the evil whatever himself with jokes along the way. Said bard then walked back out in the same manner, with the priceless bauble tucked under one arm, to then trip over a pebble in the road outside the fortress further reducing every guard and the party to helpess giggles.... The rest of the party wasn't terribly fond of this character after they were beset by a great horde of Orcs for which the bard cracked a joke leaving every Orc and the rest of the party rolling on the ground in giggles, followed by the bard walking off unbothered. The problem of course being that he left the party giggling on the ground amidst the giggling Orcs...who soon ceased giggling. >> >Or maybe I just shouldn't have any always- items in the >> >game :) >> >> I'd say this is a good suggestion. >The problem wih just not having them is that the concept I'm thinking >of is one where always- items are very apppropriate, if rare (eg, >Macbeth, who could not be slain by any man born of woman -- so he got >knocked off by a guy ripped forth from his mother's womb who was not >technically "born"). On the fourth hand, it might be best just to >handle these few items as special cases; it's entirely possible for >mountains to tremble and the seas to boil when the Invincible Warrior >Karnak battles Dargba the always-victiorious. Precisely. >> >I'm not quite clear on why spoofs are a good idea, though. It seems >> >like replacing the entire object just to modify its hitroll (or >> >whatever) is a bit excessive; can't you just have a list of affects >> >on the object and ask each of them if they modify its hitroll, and >> >have queries about the object's hitroll receive a consolidation of >> >all that information? >> >> A spoof is expensive if all you are doing is touching up a hitroll. >> They are really built for more complex and object-incasive cases where >> entire methods are replaced or altered, or the entire behaviour of the >> object is transformed, such as: >Hmm, I guess. I can see for cases where you transform a slug into a >dog, it would be easiest just to spoof it. (Well, actually, I'd swap >the slug's mind into another body and put the old body into storage, >but there you are). On the other hand, for stuff like the elven >forest scenario, I would personally give everything in castle krak a >permanent affect that alters their "draw magic" or "use magic" >skills. How about Bubba who flys a magical flying carpet into the castle, while bearing the Magical Sword of Glowing Light? All that magic works, and Bubba sits untouched in mid air in the throne room with his sword glowing brightly until Boffo takes the Sceptre to the Elven Forest. >The sort of affects I'm visualizing can have functions >attached to determine their effects, so it's no problem to give them >something like "if the scepter is in the forest, set draw_magic skill >to -999, else don't change it". I dunno. This way seems more sensible >to me .. but perhaps I'm not clear on how you plan to actually >implement the spoofs? Its easiest to diagram: Object A exists. Object A is spoofed: Object A is copied, creating Object B. Object A is deleted. Object C is created with the exact same ObjectID as the old ObjectA. Variation: Object A exists. Object A is spoofed: Object A is copied, creating Object B. The contents of Object A are deleted (all methods and attributes). The contents of the spoof objects are copied into Object A. Both have the same result: the spoof takes the place of the original object. I then allow spoofs to have a "generic method". Simply put, a generic method matches any and all incoming calls/messages (I'm message based, not stack based). This allows a spoof to accept ALL incoming messages and then pass them on (edited or not) to the original object (Object B above), and then forward the (possibly edited) results back to the original calling object. Thus a set of spoof intallations might look like: --<cut>-- Given ObjectX. ObjectX is spoofed. ObjectX is cloned to ObjectY The contents of ObjectX are replaced with the contents of the spoof. The general method on ObjectX passes calls back to ObjectY. ObjectY is the original object. ObjectX is spoofed again. ObjectX is cloned to ObjectZ. The contents of ObjectX are replaced with the contents of the spoof. The general method on ObjectX passes call back to ObjectZ. The general method on ObjectZ passes calls back to ObjectY. ObjectY is the original object. Object X is spoofed. ObjectX is cloned to ObjectA. The contents of ObjectX are replaced with the contents of the spoof. The general method on ObjectX passes call back to ObjectA. The general method on ObjectA passes calls back to ObjectZ. The general method on ObjectZ passes calls back to ObjectY. ObjectY is the original object. ObjectZ spoof is removed. The contents of ObjectZ are replaced with the contents of ObjectY. ObjectY is deleted. The general method on ObjectX passes call back to ObjectA. The general method on ObjectA passes calls back to (new) ObjectZ. ObjectZ is the original object. ObjectX spoof is removed. The contents of ObjectX are replaced with the contents of ObjectA. ObjectA is deleted. The general method on (new)ObjectX passes call back to ObjectZ. ObjectZ is the original object. --<cut>-- The following highlights some of the other fillips: --<cut>-- > 1. Bubba is carying the blessed suitcase of Googoo. > 2. Googoo activates the hidden powers of the $suitcase making it > green in color, full of gold and Xray proof. This creates a > spoof. > 3. Bubba finds the holy lockpick of Crom and uses it to unlock the > suitcase. > 4. Googoo deactivates the powers of the suitcase (removing the spoof). > > Is the suitcase still unlocked? Why? This is one of those side-effects I mentioned above. Its up to the spoof author to determine if he is interested in those methods (and subsequent changes) and if so to intercept or maintain them properly. The locked/unclocked state of the resultant suitcase depends on the methods defined on the spoof, and its destructor. *ANYTHING* _could_ be done. It could easily be arranged to be locked, unlocked, or something else (eg the destructor installs another spoof, the destructor replaces the original suitcase object with another object, the destructor destroys the original suitcase object, whatever). Simple cases: The suitcase is locked. The spoof is installed. The spoof does not intercept the lock/unlock methods on the suitcase. The spoof's destructor does nothing but remove the spoof. No clean ups. The user unlocks the suitcase. The spoof is removed. The spoof is still unlocked. The suitcase is locked. The spoof is installed. The spoof does not intercept the lock/unlock methods on the suitcase. The spoof's constructor logs the lock/unlock state of the suitcase as it install, and the destructor restores that state. The user unlocks the suitcase. The spoof is removed. The suitcae is locked. etc. --<cut>-- and: --<cut>-- A spoof is just a normal MUD object. The only specific difference between a spoof and other objects is that a spoof is used to *replace* a normal MUD object, relegating the original object to a backup copy. This leaves the rest of the system in ignorance -- it has no reason to think that anything happened. Thus message calls from other objects, intended for the spoofed object, now arrive at the spoof, and the spoof does with them whatever it wants (including passing the message straight back to the hidden original object). Diagrammed: ObjectA exists. ObjectA is spoofed. ObjectA is cloned to ObjectB. The contents of ObjectA are replaced with the spoof. ObjectX now calls ObjectA.get() Note that ObjectA is now the spoof. ObjectA does not have a method called "get()" defined. The general method on the spoof matches get(), and calls ObjectB.get() ObjectB is of course the original object, just with a different objectID now. ObjectB.get() is called and does whatever. Or, to show the spoofing in action: ObjectA exists. ObjectA is spoofed. ObjectA is cloned to ObjectB. The contents of ObjectA are replaced with the spoof. ObjectX now calls ObjectA.get() Note that ObjectA is now the spoof. ObjectA __does__ have a method called "get()" defined. ObjectA.get() is called instead of any get() method on the original ObjectB. ObjectB is of course the original object, just with a different objectID now. ObjectA.get() does whatever. --<cut>-- and --<cut>-- I had another look at this specific area over the weekend and came up with the following: There are three important processes here: 1) Determining that an object (no longer) needs to be monitored. 2) Determining that a monitored object has changed and thus triggering the monitor. 3) Determining what changed. Harking back to the example of the Great God GooGoo and his holy relics, #1 is pretty easy in that instance. GGGG knows ahead of time what objects he needs to monitor, and this can be hardcoded at the time GGGG is programmed. In the case of the Crystalline Tree, #1 is not so simple. Any object that is located within the CT needs to be monitored, however those objects could arrive in the CT as the result of a normal entry (moving from room to room in the normal and predicted manner), or as the result of a teleport (*Bink!* Its there!). Similarly objects could be removed from the CT in the same manner, requiring that monitoring stop. This is fairly elegantly addressable by altering the base container methods on the CT to install and remove the monitor on the contained or removed object. Simple, elegant, guaranteed. When ever an object is added to the contents list it gets a state change monitor installed on it, and when ever it is removed the monitor is removed. Other watcher relationships might be less elegant. Instead of a simple question of containment (eg the CT watched everything within itself), it could be some more indirect relationship (eg the DemonWroth watches all character objects (players) that have ever been in the same room as the PrincessBride, until those objects have been in the same room as the GGGG). The the question is coding this with all the normal rules intact. One solution is to have the DW spoof the containment methods on the PB so that every time the PB enters a room a spoof is set on the room (and removed from the room she left). The spoof overlays the containment methods on the room so that it in turn installs monitors on any objects that enter the room, _and_ spoofs the object to overlay _its_ containment methods to check for the presence of the GGGG when ever it enters a room (and remove the monitor and the spoof if it does). Diagrammed: DemonWroth installs spoof on PrincessBride Spoof(PrincessBride) adds features to PrincessBride.I_am_contained_by and PrincessBride.I_am_leaving_container. Spoof(PrincessBride).I_am_contained_by spoofs the room the PrincessBride is entering. Spoof(PrincessBride).I_am_leaving_container removes the same spoof from the old location. Spoof(room) adds features to the room.contain_objects. Spoof(Room).contain_objects installs monitors on any objects which enter the room (call it "thing"). Monitor(thing) reports back to the DemonWroth. Spoof(Room).contain_objects spoofs the object (thing) that just entered the room, adding features to thing.I_am_contained_by. Spoof(thing).I_am_contained_by checks every room the thing enters to see if the GGG is there, and if so removes itself (the spoof), and the monitor that reports back to the DemonWroth --<cut>-- >> The old Great God GooGoo and his holy relics scenario. (I'll repost >> on request). --<cut>-- I'll see if I can't remember the scenario that originally took me on this route. Do note that this is a fairly complex set that I used as a proof-case for a whole chunk of ideas, with spoofing etc just one of the results. The GreatGodGooGoo has a number of holy relics. Each relic has a non-magical base state, and a magical awakened state. If more than three of GGGG's relics are simultaneously awakened, the GGGG does nasty things. Relic #1 is a stone which awakens into the Gem of GGGG. The gem turns its bearer into a FireGod only for so long as he carries the gem. The FireGod is very hot. Food cooks when in his presence, metals get painfully hot, and candles melt. Other players near the FireGod are slowly damaged by the heat. Relic #2 is the Horn of the GGGG, which awakens only while it is blown and then reverts to the base state. Relic #3 is a sword which awakens to the sword of GGGG. The sword has interesting properties when awakened: 1) If the GGGG is awake (three relics etc), the the sword teleports to GGGG. 2) If it can detect the MistWraithe it magically teleports to the MW and begins attacking him. 3) If it is carried by a FireGod, then the sword is destroyed. #1 happens as soon as the GGGG is awake, and the sword can detect him and it can teleport. #2 happens as soon as it can detect the MW and can teleport. #1 has priority over #2, and #2 has priority over #3. There is a Magic Sack of Hiding. Anything in the MSH is hidden from the rest of the game. No magical effects can either enter of leave the MSH. Players, and the MW can enter the MSH. There is a Wizards Lair. Any magical effects, such as an awakening, occuring in the WL are hidden from the rest of the game. No magical effects or spells can enter the WL, but they can all leave the WL. ie in fails, out works. There is a Magic Cloak. Anyone wearing the MC appears to be the MW (more than the real MW (ie gets preferentially attacked)). Anyone carrying the MC appears to be the GGGG (non-preferentially). Base rule: Any effect on any object must be programmable without source access to any other objects. Challenge: Program the above, following the base rule. Now code the old sceptre/Castle Krak/Elven forest scenario, with the WL as part of Castle Krak, following the above rule. --<cut>-- >It's pretty obvious there's months and months of serious debate on >this stuff that I've missed. I have the vague idea this list is >archived .. how can I get at the archives? You request them from me at coder#ibm,net. I'll MIME attach everything back to Feb '97 in reply. Note: The affect/Affect/spoof/watcher threads occurred on the old CC list and partially on Wout's version of MUD-Dev back in the middle of last year. I don't have releasable archives of that traffic yet. -- J C Lawrence Internet: claw#null,net (Contractor) Internet: coder#ibm,net ---------------(*) Internet: clawrenc#cup,hp.com ...Honorary Member Clan McFUD -- Teamer's Avenging Monolith... </PRE> <!--X-Body-of-Message-End--> <!--X-MsgBody-End--> <!--X-Follow-Ups--> <HR> <!--X-Follow-Ups-End--> <!--X-References--> <UL><LI><STRONG>References</STRONG>: <UL> <LI><STRONG><A NAME="01185" HREF="msg01185.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></STRONG> <UL><LI><EM>From:</EM> Dan Shiovitz <scythe#u,washington.edu></LI></UL></LI> </UL></LI></UL> <!--X-References-End--> <!--X-BotPNI--> <UL> <LI>Prev by Date: <STRONG><A HREF="msg01197.html">Re: [MUD-Dev] Mud Games</A></STRONG> </LI> <LI>Next by Date: <STRONG><A HREF="msg01199.html">Re: [MUD-Dev] Affecting the world</A></STRONG> </LI> <LI>Prev by thread: <STRONG><A HREF="msg01185.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></STRONG> </LI> <LI>Next by thread: <STRONG><A HREF="msg01220.html">RE: [MUD-Dev] Modeling spells/skills as collections of affects</A></STRONG> </LI> <LI>Index(es): <UL> <LI><A HREF="index.html#01198"><STRONG>Date</STRONG></A></LI> <LI><A HREF="thread.html#01198"><STRONG>Thread</STRONG></A></LI> </UL> </LI> </UL> <!--X-BotPNI-End--> <!--X-User-Footer--> <!--X-User-Footer-End--> <ul><li>Thread context: <BLOCKQUOTE><UL> <LI><STRONG>Re: [MUD-Dev] Modeling spells/skills as collections of affects</STRONG>, <EM>(continued)</EM> <ul compact> <ul compact> <ul compact> <LI><strong><A NAME="01216" HREF="msg01216.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Travis S. Casey <a href="mailto:efindel#io,com">efindel#io,com</a>, Mon 15 Sep 1997, 15:40 GMT </LI> </ul> <LI><strong><A NAME="01215" HREF="msg01215.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Travis S. Casey <a href="mailto:efindel#io,com">efindel#io,com</a>, Mon 15 Sep 1997, 15:15 GMT <UL> <LI><strong><A NAME="01223" HREF="msg01223.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Jon A. Lambert <a href="mailto:jlsysinc#ix,netcom.com">jlsysinc#ix,netcom.com</a>, Tue 16 Sep 1997, 04:05 GMT </LI> </UL> </LI> </ul> <LI><strong><A NAME="01185" HREF="msg01185.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Dan Shiovitz <a href="mailto:scythe#u,washington.edu">scythe#u,washington.edu</a>, Thu 11 Sep 1997, 22:03 GMT <UL> <LI><strong><A NAME="01198" HREF="msg01198.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, clawrenc <a href="mailto:clawrenc#cup,hp.com">clawrenc#cup,hp.com</a>, Fri 12 Sep 1997, 21:46 GMT </LI> </UL> </LI> <LI><strong><A NAME="01220" HREF="msg01220.html">RE: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Caliban Tiresias Darklock <a href="mailto:caliban#darklock,com">caliban#darklock,com</a>, Mon 15 Sep 1997, 16:54 GMT <UL> <LI><strong><A NAME="01229" HREF="msg01229.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Nathan Yospe <a href="mailto:yospe#hawaii,edu">yospe#hawaii,edu</a>, Tue 16 Sep 1997, 20:39 GMT </LI> </UL> </LI> </ul> </LI> <LI><strong><A NAME="00927" HREF="msg00927.html">Modeling spells/skills as collections of affects</A></strong>, Brian Price <a href="mailto:blprice#bedford,net">blprice#bedford,net</a>, Mon 01 Sep 1997, 01:41 GMT <UL> <LI><strong><A NAME="00928" HREF="msg00928.html">Re: [MUD-Dev] Modeling spells/skills as collections of affects</A></strong>, Caliban Tiresias Darklock <a href="mailto:caliban#darklock,com">caliban#darklock,com</a>, Mon 01 Sep 1997, 02:21 GMT </LI> </UL> </LI> </UL></BLOCKQUOTE> </ul> <hr> <center> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] </center> <hr> </body> </html>