4Dimensions Forum

Building & Scripting => Scripting Board => Topic started by: Fizban on February 26, 2008, 02:00:44 pm

Title: General Scripting Suggestions
Post by: Fizban on February 26, 2008, 02:00:44 pm
None of these things are overly hard or difficult to understand but just seem to be habits people pick up or simple things people don't think of immediately: Most of them lead to ambiguity or performance loss (lag) in the mud though, especially when the same small things are done repeatedly. They may seem insignificant, and truly, once or twice they are, 500 times across a zone and then in multiple zones, they do indeed add up.

Set vs. Eval

Wrong:
Code: [Select]
eval room %actor.room%
Correct:
Code: [Select]
set room %actor.room%
There's no reason to evaluate the ID of the room, it's a number, there's no parsing or math involved, by evaluating it only takes up more cpu time, it's also technically more to type.


Set vs. Nop

Wrong:
Code: [Select]
set %actor.gold(1000000)%
Correct:
Code: [Select]
nop %actor.gold(1000000)%
Again, they do the same thing except setting it creates an empty variable which is not intended and un-nneded, once again just un-needed cpu time. (I admit I'm guilty of this one myself semi-often but try to catch it.)

UID vs. Name

Wrong:
Code: [Select]
%send% %actor.name% This is a string of words.
Correct:
Code: [Select]
%send% %actor% This is a string of words.
%actor.name% is ambiguous, two mobs or players with the same name (meaning a mob and player with the same name, I'm aware two player's cant have the same name.) Also it takes un-needed cpu time to search the actor's char_data structure and retrieve their name when it doesn't need to. This is true for any time %actor% preceeds a DG-Command, ie. %teleport% %send% %echoaround% %goto% etc. On the other hand %actor.name% is needed when preceeding a mudcommand, such as give or look, or any social.

Also just something that seems odd that I find all over through most of the scripts. "endif" not sure where that really came from, but the if part is entirely superfluous and in fact it could endthegodforsakenscriptnow, and because of such all that is needed is end, which is also shorter and therefore faster to parse.

The purpose of Global Type Scripts:

This one isn't as common but is something I spotted the other day which made me quite certain that whoever wrote the script (not mentioning names) didn't know what the purpose of Global was.

Code: [Select]
set p %self.people%
if %p%

When those are the first two lines of a random global script attached to a room, all it being global does is kill cpu time. Random Triggers fire when a player and/or mob is in the room. Global Random Triggers fire regardless of whether someone is in the room or not. What that does is make it fire every time, but do nothing anyway if no one is in the room. Essentially, it's entirely wasteful and the Global Type on the script served no purpose butmaking the game run slower. A lot slower? No, but slower nonetheless.
Title: Re: General Scripting Suggestions
Post by: Mordecai on February 26, 2008, 08:21:20 pm
Good stuff Fizban.

One more thing of RANDOM GLOBAL triggers.
Non GLOBAL triggers only fire when no one is in the ZONE rather then the ROOM.

If an Imm has nohassle ON then they are treated as not being in a zone, and normal RANDOM triggers may not fire if they don;t have GLOBAL when you are testing them.
However, if the trigger doesn't need to run when no one is there to see it, make sure you remove the GLOBAL from its trig type list.
Title: Re: General Scripting Suggestions
Post by: Fizban on February 26, 2008, 10:34:34 pm
Hmm, I wonder if TBA is different then, or, if me and umm..everyone else on TBA have had that part wrong for quite some time heh...because from their helpfile:

Quote
TRIGEDIT-ROOM-GLOBAL TRIG-ROOM-GLOBAL

Not a trigger type by itself; used in conjunction with Random HELP
TRIGEDIT-ROOM-RANDOM and HELP TRIGEDIT-ROOM-TIME. While Random
and Time only trigger if players are in the same room, Global Random
and Global Time will trigger regardless.
 
Numeric Arg : not used.
Argument    : not used.

Variables:
%self% - the room.

Example: TSTAT 50

I read that originally and just took it at face value in assuming it was correct.
Title: Re: General Scripting Suggestions
Post by: Mordecai on February 27, 2008, 12:25:01 am
I will just check the code. BRB!
Title: Re: General Scripting Suggestions
Post by: Mordecai on February 27, 2008, 12:27:48 am
Code: [Select]
if (IS_SET(SCRIPT_TYPES(sc), WTRIG_TIME) &&
                    (!is_empty(IN_ROOM(ch)->zone) ||
                     IS_SET(SCRIPT_TYPES(sc), WTRIG_GLOBAL)))
                time_mtrigger(ch);

So on 4D it is if the ZONE is empty.

Let me just check the TBA code.
Title: Re: General Scripting Suggestions
Post by: Mordecai on February 27, 2008, 12:29:21 am
Code: [Select]
if (IS_SET(SCRIPT_TYPES(sc), WTRIG_RANDOM) &&
          (!is_empty(world[IN_ROOM(ch)].zone) ||
           IS_SET(SCRIPT_TYPES(sc), WTRIG_GLOBAL)))
        random_mtrigger(ch);
    }

That is the TBA mud code.

So yeah, checks the whole zone, not just the room.
Title: Re: General Scripting Suggestions
Post by: Fizban on February 27, 2008, 12:38:09 am
*Fizban starts editing TBA's helpfiles.*
Title: Re: General Scripting Suggestions
Post by: Fizban on March 07, 2008, 01:37:07 am
Seems people seem to repeat large chunks of script as well, mind the example below is an old script I believe, but it's certainly not the only of its kind, it's just one I noticed earlier and did rewrite and figured looking at the before and after might help others make their scripts shorter and easier to follow as well:

Before:

Code: [Select]
wait 3
emote examines the item.
if (%object.vnum% == 4951)
  if (%object.count(4936)% == 8)
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if (%actor.level% < 10)
      eval a 10
    elseif %actor.level% > 45
      eval a 45
    else
      eval a %actor.level%
    endif
    eval b 0
    eval d 0
    while %b% < %a%
      set %actor.exp(4000)%
      eval d %d%+4000
      eval b %b%+1
      global b
      global d
    done
    %send% %actor% You have just gained %d% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
  endif
elseif (%object.vnum% == 4952)
  if (%object.count(4937)% == 8)
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if (%actor.level% < 10)
      eval a 10
    elseif %actor.level% > 45
      eval a 45
    else
      eval a %actor.level%
    endif
    eval b 0
    eval d 0
    while %b% < %a%
      set %actor.exp(4000)%
      eval d %d%+4000
      eval b %b%+1
      global b
      global d
    done
    %send% %actor% You have just gained %d% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
  endif
elseif (%object.vnum% == 4953)
  if (%object.count(4938)% == 8)
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if (%actor.level% < 10)
      eval a 10
    elseif %actor.level% > 45
      eval a 45
    else
      eval a %actor.level%
    endif
    eval b 0
    eval d 0
    while %b% < %a%
      set %actor.exp(4000)%
      eval d %d%+4000
      eval b %b%+1
      global b
      global d
    done
    %send% %actor% You have just gained %d% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
  endif
elseif (%object.vnum% == 4954)
  if (%object.count(4939)% == 8)
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if (%actor.level% < 10)
      eval a 10
    elseif %actor.level% > 45
      eval a 45
    else
      eval a %actor.level%
    endif
    eval b 0
    eval d 0
    while %b% < %a%
      set %actor.exp(4000)%
      eval d %d%+4000
      eval b %b%+1
      global b
      global d
    done
    %send% %actor% You have just gained %d% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
  endif
elseif (%object.vnum% == 4955)
  if (%object.count(4940)% == 8)
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if (%actor.level% < 10)
      eval a 10
    elseif %actor.level% > 45
      eval a 45
    else
      eval a %actor.level%
    endif
    eval b 0
    eval d 0
    while %b% < %a%
      set %actor.exp(4000)%
      eval d %d%+4000
      eval b %b%+1
      global b
      global d
    done
    %send% %actor% You have just gained %d% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
    give %object% %actor.name%
    drop %object%
    say You go and get it right, and then come back again.
  endif
elseif (%object.vnum%==4956||%object.vnum% == 4957||%object.vnum% == 4958||%object.vnum% == 4959)
  return 0 
  wait 1 s
  emote shakes his head, refusing to receive the item.
  say Talk to my colleage, Mrs DelAngelo, my hands are full right now.
  give %object% %actor.name%
  drop %object%
else
  wait 1
  say I do not trade in items like this.
  say I am only interested in freshly grown vegetables.
  say And they have to be delivered in the Official 4D Containers as well.
  give %object% %actor.name%
  drop %object%
endif

After:

Code: [Select]
wait 3
emote examines the item.
if %object.vnum% == 4951 || %object.vnum% == 4952 || %object.vnum% == 4953 || %object.vnum% == 4954 || %object.vnum% == 4955
  eval num %object.vnum% - 15
  if %object.count(%num%)% == 8
    wait 1
    mjunk %object%
    wait 1 s
    say Thank you, %actor.name%.
    say A pleasure to do business with you.
    emote hands over 2 tradepoints.
    nop %actor.trade(2)%
    if %actor.level% < 10
      eval exp 10 * 4000
    elseif %actor.level% > 45
      eval exp 45 * 4000
    else
      set exp %actor.level%
    end
    nop %actor.exp(%exp%)%
    %send% %actor% You have just gained %exp% exp!
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object.name% %actor.name%
    drop %object.name%
    say You go and get it right, and then come back again.
    give %object.name% %actor.name%
    drop %object.name%
    say You go and get it right, and then come back again.
  end
elseif %object.vnum%==4956 || %object.vnum% == 4957 || %object.vnum% == 4958 || %object.vnum% == 4959
  return 0 
  wait 1 s
  emote shakes his head, refusing to receive the item.
  say Talk to my colleague, Mrs DelAngelo, my hands are full right now.
else
  return 0
  wait 1
  say I do not trade in items like this.
  say I am only interested in freshly grown vegetables.
  say And they have to be delivered in the Official 4D Containers as well.
end
Title: Re: General Scripting Suggestions
Post by: Mordecai on March 09, 2008, 11:36:39 pm
Code: [Select]
  else
    wait 1 s
    say I can only take full containers! This is wholesale, not retail.
    say All vegetables in it have to be of the right kind too!
    wait 2 s
    give %object.name% %actor.name%
    drop %object.name%
    say You go and get it right, and then come back again.
    give %object.name% %actor.name%
    drop %object.name%
    say You go and get it right, and then come back again.
  end

    give %object.name% %actor.name%
    drop %object.name%
    say You go and get it right, and then come back again.

Has that segment too that can be removed while refactoring.

%object.name% normally has multiple arguments, such as, 'small sword rusty'
So the script would actually be doing this:
give %object.name% %actor.name%
would be
give small sword rusty mordecai

So, it needs the keyword TO added in.

give %object.name% to %actor.name%

Since when you use the keyword TO it handles multiple arguments on either side.

IE:
Give fluffy kitten to black spider
Title: Re: General Scripting Suggestions
Post by: Leonardo on April 16, 2008, 04:07:59 am
I'd also replace the %actor.name% var with %actor%
Since the actor may be having a clone following, or a mob with his same name in the room.
give %object.name% to %actor% would be the perfect solution.
Title: Re: General Scripting Suggestions
Post by: Fizban on April 16, 2008, 11:56:12 am
That actually won't work at all. Give is an actual command, not a DG command as such it requires an actual name, not an ID when being used.   ie. %teleport% %actor% works    look %actor%  or give %object.name% %actor% don't
Title: Re: General Scripting Suggestions
Post by: Fizban on September 02, 2008, 10:35:57 pm
I will fix these where I see them but I'm also posting a request to not do it in the future instead of just changing one's I find so people don't continue doing it.

Don't do:
Code: [Select]
eval am (%actor.level%*(20000+%random.200%))
eval ab %%actor.exp(%am%)%%
nop %ab%

Do:
Code: [Select]
eval am (%actor.level% * (%random.200% + 20000))
nop %actor.exp(%am%)%

For the following reasons:

1. Less cpu time, so it's faster and causes less lag.
2. Far more importantly the first example gives twice as much experience as you want it to. eval am %%actor.exp(%am%)%% adjusts their exp itself. It's rather like why you don't do this:

eval command %cmd% %arg%

because it will raise their hp if the %cmd% is:

%actor.exp(10000)%

when it becomes evaluated.
Title: Re: General Scripting Suggestions
Post by: Tocharaeh on February 20, 2010, 08:49:38 pm
I have an important question for this small group  oriented zone I built...and for future zones that are intended for grouping.

Question 1:

Assuming there is a gate which cannot be opened directly, and requires A to pull on an object, and for B to pull on another object in order for C to get pass the gate in order to pull on a final object to keep it open so that A and B can then go inside. How would I go about creating a script that requires multiple people to split up and trigger scripts that effect a separate location regardless of order?

Question 2:

 And if I want to make a set order such as the have point X, Y, and Z triggered in the order of Z, X, and Y for a door to open somewhere, how would I go about doing that?

Title: Re: General Scripting Suggestions
Post by: Leonardo on February 21, 2010, 03:52:00 am
Ok, I've done the script. Nice idea Toch, I like realistic and complicated tasks instead of the usual search,search,search, find the key, enter the portal, find the right noun.

How much are you paying for the source code? :)
Title: Re: General Scripting Suggestions
Post by: Tocharaeh on February 21, 2010, 02:58:01 pm
I NEED TO KNOW!!!!!!

Sooner I learn how to script, especially this group oriented team work script, the sooner I'll get things completed :P
Title: Re: General Scripting Suggestions
Post by: Leonardo on February 22, 2010, 03:16:25 am
My milkscript is better than yours, I can teach you but I have to charge :P
Title: Re: General Scripting Suggestions
Post by: Tocharaeh on February 22, 2010, 10:53:33 am
Ummm....how about a plaque saying "Thanks to LH, we have a badass set of scripts that allowed you to fully enjoy the adventure", and 2 bronze? :P
Title: Re: General Scripting Suggestions
Post by: Leonardo on February 22, 2010, 01:52:36 pm
I plaque would suffice, but you have to make it very very nice and ascii surrounded.
Continue building fast, by the end of the week I'll make time to come with you on the BP and help you configure it in the rooms you wish to.
Title: Re: General Scripting Suggestions
Post by: Tocharaeh on February 22, 2010, 07:14:00 pm
sw33t
Title: Re: General Scripting Suggestions
Post by: Leonardo on February 23, 2010, 02:05:44 pm
sw33t

Add my name in zedit to your zone, then send me a note on BP with the VNUM of the rooms you want the script attached.
I'll work it out with standard messages, you modify it as you please afterward.
Title: Re: General Scripting Suggestions
Post by: Tocharaeh on February 24, 2010, 10:31:23 pm
Alright, Imma work on it to make sure things are in order, and then I'll make the small list of rooms and message you all of the details.
Title: Re: General Scripting Suggestions
Post by: Calypso on October 26, 2013, 04:14:14 pm
I plaque would suffice, but you have to make it very very nice and ascii surrounded.
Continue building fast, by the end of the week I'll make time to come with you on the BP and help you configure it in the rooms you wish to.

This would not happen to be the zone that finally came out this year, would it? :P