Buy Stuff!

Synthetic Reality
Well of Souls
Testers Page
Well of Souls:
Home Page
Contact Us
Download It!

Guild Hall
About Guilds
WoS Ladders
Bulletin Board
Hall of Heroes

Custom Skins
Other Worlds
Cheat Codes
Beta Testers Page

Synthetic Reality

Wanna Be a Tester? It's EASY!

Just pop me an email at telling me you would like to take part. I don't impose any formalities. Just download the current version from here, try it out, and mail me about stuff you do and don't like, problems you had, ideas for improvement. That sort of thing. Actually, you should probably post directly to the Well of Souls Bulletin Board.

Current Events:

ALPHA 96 INSTALLER and PATCH A96 are now on line.



12/5/08 A97 includes:

  • some small fixes I have forgotten
  • new activation code algorithm
  • extension of timeout

6/8/2008 A96 includes:

  • * NEW MINI-GAME: WoS Tactics

    This is a multiplayer mini-game where each player commands an army of up to nine 'pieces' on a tile-based map. Full details at
  • * Quest Script can now GIVE/TAKE PP

    World developers begged for this, now let's see if it is a big mistake :-)

    The magic letter is 'P'

    GIVE P100

    Gives 100 P. Ditto for TAKE, HOST_GIVE, PARTY_TAKE etc.

    So, when you 'sell' your training back for PP, you can no longer sell yourself below your 'starting_xxx_pp' (as set in the levels.txt table for your character class).

    I think there was an inadvertent size limit on the number of missions you could have, which I have hopefully removed. There is aprobably still a practical maximum of number of missions, but it should be much more than 20 ish now.
  • * NO LONGER ENDS UP WITH NO SKIN when world developers define default skins which people don't have.

    This lowercases a string (which should be unnecessary since the string comparison operators are not cases sensitive)

    STRLWR cookieName input

    So the first argument is just a cookiename where the output will be stored. The second argument could be any normal thing. If you really wanted to lowercase the content of a cookie (and overwrite the same cooke), you would do this:

    STRLWR cookieName, #<cookieName>

    This allows you to 'parse' a string which contains some number of tokens separated by some delimiter, say a comma.

    For example

    NTH_TOKEN cookieName, 3, "zero,one,two,three,four"

    would result in "three" being put into cookieName. (the first token in the string is 0). Of course your actual string you are looing at will probably be a cookie itself, so a more realistic example is

    NTH_TOKEN cookieName, 5, #<input>, ":"

    And just to confuse the example, I included the optional final argument which defines the actual delimiter character to be used. (which defaults to comma, but in this example I overrode it to a colon).

    Yet another optional argument (after the delimiter) is whether you want to clip leading spaces from the tokens

    NTH_TOKEN cookie, 2. "zero, one, two, three", ",", 1

    will set the cookie to "two" instead of " two"

    You can now specify that a spell or item requires N of a particular trophy to be used (4 bullets, 3 gold bars, etc)

    You can also specify that a spell which creates a trophy can create N of them (if you lack bag space, no promises are made for delivery)

    So, you can now have a spell which burns 4 gold bars, to make 2 platinum bars. Anything more complicated than that (like 2 wings of the wyvern AND 23 snail eyes) is up to yourmad scripting skillz.

    This is accomplished by adding a couple mode dotted arguments (see appropriate items.txt and spells.txt for details) something like this:





    So it is back compatible with existing worlds, and the counts are assumed '1' if not provided.

    Generally, I resist this sort of cookie since it feels like the world developer is the one that specified this info in the first place, so they should just magically already know the answers, but to the degree they help, here they are


    this one is the only read/write one and lets you control which trophy is being considered by the rest of these cookies. If you don't set this first, you will get chaotic data.

    Once you set the trophyId, you can read the following:

  • * New HOTKEY button bar

    In addition to the popup hotkey dialog (which I always hated), I have added a more classic button bar (OPTIONAL and requires WoS width 1024 or more)

    Anyway, it works just like the hotkey popup window. press Fnn or clicn the button. Hold control to bind the current spell/item to the key of your choice.

    For items, the button has a picture of the item, and for spells it has the 'element image' (new) of the spell. Someday I could support per-spell images.

    But you really only hsve 8 bindable keys (f5-f12) (did I mention I fixed F10) ?

5/5/2007 A95 includes:

  • * New Cookies

    num.sceneMapFlags -- current Scene override
  • * New Mission Token Behaviour

    In general, in the mission description and the messages generated at accept/abandon/reward time, there will no longer be any mention of tokens. This is because token text, if present, is really not written in a form which scans well as a mission statement. You are better off using the mission text to summarize what you mean and let the tokens be a 'secret'

    But a secret hack will show the token name/description if you use a lowercase 't' instead of an uppercase 't' in the rewardGive/Take object strings.
    * Fixed Mission Bug

    It turns out if your mission used the RewardToken feature, it was actually applying the token change as soon as the mission was READ (i.e. before you completed it, and even if you never accepted it).

    RewardGive/Take did not have this problem, just RewardToken.

    The quest diary is filled with the text decriptions of tokens your character posseses (and which are actually defined in the TOKENs table). The token text is now processed in this way before being plugged into the diary display

    * cookies are expanded
    * %'s are expanded

    So you could define a token's name to be:

    You, %0, have been granted #<cookie>

    Remember that the cookie and % is re-evaluated every time you open the Quest diary, so if you subsequently change the cookie value, the contents of the book will change as well.

    First off, if you do nothing, your Quest Diary will look the same as always (from the Books menu, the thing that lists all the named tokens you have acquired).

    But if you enable chapters, then your Quest Diary will have a title page with just the chapter names, which will then hyperlink to individual pages which list the acquired named tokens that belong to that chapter.

    You're still pretty much stuck with my simplistic HTML formatting of the lists.

    To enable the feature, you add additional lines to your TOKENS table (please note, you can still spread the TOKEN definitions themselves all over the place, as before, but these chapter definitions must be inside the +TOKENS table.

    AN illustrative Example might be:

    chapter, 0, 0, 0, "Main Title", "Main intro about all this", "Main footer to speak of"

    chapter, 1, 0, 9, "Preamble", "General things I have done not in any particular quest", "Preamble Footer"
    1,"You, %2, have agreed to obey the golden rule. #{cookie1}"
    2,"Lurch The Hand has lectured you in the art of fighting."

    ; Quest 1, The Fire Boots
    chapter, 2, 10, 19, "Feet of Fire", "There are rumours", "the story continues..."
    10,"Felafel begged you to rid his kingdom of the cavern dragon."
    11,"You conquered the cavern dragon and took a scale from his hide."

    ; Quest 2, The Lost Gem
    chapter,3, 20, 29, "The Lost Gem", "There are rumours", "the story continues..."
    20,"Jett told you of her grandmother's enchanted pearl"
    21,"You confronted the witch Miranda, who told you the true story of the pearl."
    each line that starts with 'chapter' is a chapter definition. Chapters will appear in the Quest Diary in the order they are listed in the +TOKENS table (which does NOT have to match the order of the tokens themselves)

    However, a chapter contains "a contiguous range of token ID numbers which have not already been reported by a previous chapter" as opposed to "a list of arbitrary token IDs in any order you like" So, if you have not been carefully numbering your tokens in the past, you're a little screwed shoe-boxing this in without renumbering tokens (a pain). Then again, your Quest Diary must be ugly anyway if you haven't been being careful, so you suck!

    So, for each chapter, you provide these fields:

    chapter, id#, firstToken, lastToken, Title, Intro, Footer

    Then a typical chapter page looks like this:

    Chapter intro text which can ramble on for a bit and which will line wrap as needed.

    * first entry in list
    * last entry in listChapter

    footer text, if present.

    That same basic format is also used by the Table of Contents page, which gets its title/intro/footer from chapter id 0 (which should have a token range of 0-0)

    And the ToC only shows chapters for which you have accumulated at least one named token. So your chapter names are 'secret' until they trip over a token. Which is maybe a good reason to not number your chapter titles
    The second download of a published world which included read-only files would fail because the unzipper would refuse to overwrite them. It would also give a bad error message about it. Now it works, though really you shouldn't probably include read-only files in your world.
    The download progress meter now more accurately expresses your download speed in bits per second (as opposed to 'baud')
    I believe I have worked through the remaining Vista issues, so it is possible now to play the game, host a server, behind a firewall/router etc., though you may still have to run as admin on occasion.
    In the course of debugging how Vista had modified the network layer (it changed some APIs!!!!) I found a handful of other things to improve, so even without vista you might find your experience better when, for example, hosting a MIX server behind a NAT.

3/7/2007 A94 includes:

  • Fix for nasty bug which could cost you to lose your pets.

3/4/2007 A93 Includes:

  • * COMPATIBILITY: Excellent!
  • * Max PP Change in Evergreen, and training changes for all worlds

    1.) I increased the evergreen max PP from 40K to 100K

    2.) I made the PP per training click variable, so it costs 50PP a click at the lowest level and 2000PP a click at the highest

    3.) this results in it taking only 105 clicks, instead of 225 clicks to go from nothing to level 9.0 and that costs about 65K, leaving about 35K in your pocket if you were at 100K when you started

    4.) applying the full 100K to a single training slot gets you to level 9.406 in about 125 clicks.

    5.) there is no enforced wait time per click (not even I am that hardcore, apparently. Same sound effect as before, which I like and sounds ok when clicked rapidly)

    6.) Getting to 9.990 still requires an insane amount of PP, but you now invest 2000 at a time at that level, instead of 200, so it should take 10x fewer clicks. It takes multiple pocket fulls of PP though, and I like it that way as I want 9.990 to mean you are truly hardcore.


    Now, to answer the question "how much better is 9.990 than 9.406" well that's easy, the effect is linear, so it is:

    (9.990 / 9.406) = 1.06

    so it is 6% better, but it is vastly more expensive and represents a vastly huger effort to get that extra 6 percent.

  • * fixed the crazy Bring Back the Dawn Mission
  • * new GIVE command to give a mission

    Remember, in Quest they are 'jobs' so you GIVE J23 to give mission 23 to the user (pretty much means force them to take it, so you should be sure it is appropriate. It's your call.)
  • * new IF conditional to test mission (job) status

    IF Jnn @theyHaveFinishedMissionNn
    IF JQnn @theyQualifyToStartMissionNn
    IF JAnn @theyHaveAcceptedButNotFinishedMissionNn
  • * New World config.ini option.. read config.ini for details
  • * new quest command: SHUFFLE

    SHUFFLE cookieName, numCards

    which creates the following cookies

    cookieName&lt;numCards - 1&gt;


    numCards must be between 1 and 100 (100 is ok, but that is the heighest value) and you have to be the scene host and incarnated for it to work.

    After calling SHUFFLE, you can look at #&lt;cookieNameCount&gt; to remember how many cards are in your shuffled deck. It will be 0 if there was some problem (like you asked for more than 100).. ok.. ok.. I will make it 256 max.

    Remember, this just creates a bunch of cookies. It is up to you to keep track of which have been 'dealt'

    each cookie just holds a number between ZERO and Max-1

    A better Example

    ; Shuffle a normal 52 card deck

    SHUFFLE cards, 52
    COMPARE #&lt;cardsCount&gt;, 0
    IF= @something went wrong, should have been 52

    1: The index of the first card is #&lt;cards0&gt;
    1: The index of the last card is #&lt;cards51&gt;

    Of course, it doesn't have to be cards

    SHUFFLE monsterIds, 10

    SHUFFLE prizes, 15

    The shuffle command cares not how you use the cookie.

    When you return to the Well of Souls, I now default to the RESTORE panel instead of the MAP panel (showing a list of your characters instead of a list of who is playing). Also, I duplicated the NEW and INCARNATE buttons in a way which makes them more obvious to a newbie player. PlayTesting with a certain un-named newbie implied this would clear up an early sticking point for the new user.

    Small things like the Soul Brother no longer shoves your Trophy Bag in your face every time you visit him.
  • * HOTKEYS now default to OFF

    New players will no longer see the inexplicable hotkeys window on their first visit to the game, but will have to turn it on via the Book of Options. Old players will be in the same state they were.

    a normal menu entry looks like "menuText=@label" but if menuText starts with a forward slash "/menuText" then I will add a checkMark (and not include the / in the text I show).

    Hopefully no one was using /s already in their menu text...

    The script ACTOR command's first argument (the actor id number) is now a dotted arg. The first value is the actorId which has not changed. The second value (optional, and assumed to be 0) is the display 'layer' of the actor. If it is -1 then it is 'behind' all actors on layer 0. If it is +1 (aka '1') then it is 'in front of' all actors on layer 0. Within a layer, actors are sorted by their 'y' value on screen (lower on screen means more in front). If you need more layers, you should be able to use... about... oh.. 2000 I think, which should be enough. -1000 to +1000, I mean. More positive is more in front, more negative is more in back. I only tested -1, 0, and 1 though.

    This is backwards compatible (or at least it should be), so you don't have to add .0 to all your existing actors.

    This is so a 'scene actor' (say, the cave entrance) can be permanently behind all the players.. or a 'foreground object' like a tree can be in front (and you could hide behind it.)

    Though you can't REALLY hide as the nametag and chat bubbles will probably give you away.

    The Items window, the Spells window, the Current Equip window, and the SHOP dialog now all indicate if an item or spell consumes a trophy when used. The 'learn spell' dialog does not.

    So, another dotted argument:


    monster id 23, starting at x=50, y=75, and initially 'facing left' (0 is the default 'facing right'). This sets the initial facing direction, which will then change as the monster moves.

    So, you just did a FIGHT scene, it ended, and now you want to remove any remaining monsters from the scene (enemy or friendly, but not pets). Use "FIGHT 0"

    Note that if you had a friendly in the scene and the fight ended, and you use the FIGHT command to add more monsters (second wave), your pal gets to stay.

    num.hostAttack -- aggregate attack points of host
    num.hostDefense -- aggregate defense points of host

    I did this mostly for my own purposes, so when people sent in screen shots I would not have to always ask them what their serNum was, but it might be useful to you as well, who knows? :-)

    Basically I added your character name, your sernum, and how long you have been playing the game in that session (so as to track bugs that only happen after playing for a few hours, for example, but you can pretend it is so you can realize you have been playing too long and should go for a walk or something). This information updates when you enter/exit a scene.

10/23/2006 A92 includes:

  • * MIX v1.21

    This version tries to auto-detect if you have firewall/router/port forwarding issues and puts up some helpful little message with info which might (or might not) help you resolve the problem.
  • * PK Changes

    Haven't done this yet, but plan to do some fairly radical changes to make it possible for world developers and server admins to pretty brutally limit (or unlimit) PK abilities.
  • * New World Config.ini: petsCanBitePeople

    This has to be set to 1 (the default) or pets cannot bite people in your world. Ever. Evergreen sets this to zero. No more pets biting people. at all. on any map.
  • * New World Config.ini:maxUnSpentPP

    This defines how much PP a character can have 'in their pocket' Any PP earned in excess of that is lost. Evergreen defaults to 40K PP max. If you do NOT set this, it defaults to 1 million. If your world needs more (say you have a quest that requires accumulating ten million PP), you will need to add this variable to your config.ini, or your quest will be broken until you do.
  • * New world config: maxPKAttackAdvantage

    This defaults to 80 in old worlds, and is set to 10 in Evergreen. It prevents you from INITIATING a PK attack on another player more than this many levels below you. If you set it negative, then you could only INITIATE attacks on people that many levels ABOVE you. Weird, but maybe someone will like that.
  • * New World Config: worldHomeUrl

    Set this to a url which describes your world, and then a button will appear "world home" on the servername area of the main splitter bar. The idea is to advertise your world, ladders, contests, whatever.
  • * New server rule "url"

    as in: maxAFK=10, url=

    When present, this adds a "server home" button to the main splitter bar. The idea here is to have a home page for your MIX server, where you can talk about what your philosophy of servitude might be.
  • * More anti-hacking measures, as usual. In general, the punishment for getting caught hacking is increased. Sorry for any false triggers.
  • * Improved image quality for jpeg maps and scenes (especially if the source images are very small, as they are in Evergreen)
  • * More Stuff.. UNfortunately I didn't document a lot of my puttering over the last few months, so some changes might come as a surprise to both of us :)

2/19/2006 ALPHA 91 INCLUDES:

  • COMPATIBILITY: Excellent!
    - 'Dome' options should no longer be inverted
    - tweaked some of the A90 ones I added, like Halo

    Some new stuff in this table:

    C Accumulation of magic around caster, before it 'launches', and when it hits
    0 - accumulate over caster, land in body of target
    1 - accumulate within caster, land in body of target
    2 - accumulate under caster, land in body of target
    3 - in the body of the caster, but 128pixels away from target
    4 - in the body of the caster, but 128pixels towards target
    5 - in the body of the caster, but halfway between caster and target
    6 - Over the head of both caster and receiver
    7 - at the feet of both caster and receiver
  • Some new stuff in this table

    DD 'cloud' shape of magic accumulation
    00 - tight random cloud
    01 - looser random cloud
    02 - loose random cloud
    03 - single circle
    04 - two circles
    05 - single circle - vertical
    06 - two circles - vertical
    07 - Big round circle
    08 - Halo
    09 - Vertical Halo
    10 - Horizontal Line
    11 - Vertical Line
    12 - Slow Large Dome
    13 - Fast LArge Dome
    14 - Slow Small Dome
    15 - Fast Small Dome
    16 - increasing to large radius
    17 - increasing to medium radius
    18 - decreasing from large radius
    19 - decreasing from meidum radius
    20 - Spiraling Outward Circle
    21 - Spiraling inward Circle

    IF&lt;&gt; or IF!= will go to the label if the previous COMPARE operation yieled 'not equal'

    If you add an optional '1' like this

    ASK 600 1

    Then it will NOT send what you (the host) typed to the other players in the scene.

    You will still see it yourself, however. This is one of those bits of code which I am too lazy to actually test though...
  • BUGFIX - More support for 64 actors

    The ACTOR and MOVE commands were only giving access to the first 32 (of 64 max actors).
    MOVE command can now move scene host

    This is non-binding since it doesn't stop the host from moving elsewhere, but now you can move the host around like this:

    MOVE H, x, y

    Could be fun. "Hero, approach the king!"

    I did this sort of randomly, and it's possible I might have broken something, and missed other things. But basically, you can use cookies in more commands now than you used to be able to. For example the ACTOR and POSE commands let you get all the numeric values out of cookies, if you like.

    I only upgraded numeric values, since that felt like I would be less likely to prematurely evaluate a cookie.

    Hopefully you won't even notice I did this.. knock on wood.

    At long last, you can use timers to restart a script after it has ENDed. You have 10 timers (numbered 0 - 9). When a scene first starts, all the timers are turned off. You turn on a timer like this:

    TIMER 4, 7.8

    This means that timer 4 will fire in 7.8 seconds from RIGHT NOW (time starts from the moment you execute the TIMER command, NOT from a subsequent END command.)

    When the timer fires, it looks for a label like:


    (where 4 is the timer ID from this example, but could be 0 through 9)

    Like other events, timer events can only trigger while the scene is ENDed (and they wake the scene back up.)

    So, what are timers good for?

    Well, you could maybe end a fight, change the weather, play a sound effect, change the background, evaluate how long it took someone to do something, etc.

    If you wanted a periodic timer, you might try something like this

    1: I will change the weather every second
    TIMER 1, 1.0

    TIMER 1, 1.0

    So, when the timer triggers, I change the weather to a random value 0-9 and then restart the timer for another second (and then END again, of course!)

    cookie: 'num.timerLengthN' returns length of timer N in milliseconds

    cookie: 'num.timerLeftN' returns number of msec left in timer N (before it will trigger.. assuming you END again before that)

    TIMER N, 0 -- kills timer N
    TIMER -1 -- kills ALL timers

    Please don't be confused by my lazy implementation. I let you set the timer by SECONDS (like the WAIT command), but the cookie reads time left as MILLISECONDS... I only added the cookies so you could do things like praise the player if they finished some action with lots of time left.

    Sorry. And thanks to Pippin (and others) for clearly documenting the procedure.

    I think this is probably a slippery slope here, since ultimately people should be able to specify their own favorite sounds.. but for NOW, the enhancement is that the gender.ini file can optionally override the pain sound used for players when they get hurt.

    Add a line like:


    which will make it play pain10.wav when a player of that gender is hurt. I know it's weird to have "pain1.wav" on the left instead of just "pain" or "painSfx" but that's life. Gender.ini is all about 'translation'

    Turns out that a comma in a name would lead to corrupted packet handling. I'm afraid commas are not legal in these fields, and hence "Konan, The Destroyer" will now appear as "Konan The Destroyer"

    If you set the 'gold per stack' value to a negative number, then the holder of a trophy cannot 'sell' the trophy, but instead has to 'pay' the shopkeeper to be rid of it. Neither can the trophy be discarded or given away.

    Something like a 'healing fairy heart' from something you killed that shouldn't ought to have killed, and now must carry your shame with you. (and yes, Cowardly PK Kill Hearts are my intended ultimate target for this :) )

    Note that if the price is over 1 million (and the stack size is 1), they can't get rid of it. Which is probably pretty nasty since it consumes a trophy bag slot. An NPC could remove it, of course.

    This is a very simple implementation. Basically in the ITEM and SPELL tables is a new field "trophyNeeded"

    If you set this to a non-zero value, then the player cannot use that (right-hand) weapon, or cast that spell, unless they have at least one of the specified trophy (and a trophy is then removed from their bag). This does NOT affect 'use item on yourself' just right-hands and spells. (in the case of a wand, where the right-hand does a spell, it uses the ITEM trophy and not the SPELL trophy.. I think).

    For example, see the Evergreen 'Rubber Balls' DART (now consumes a green jelly pigment) and the spell GEL (which also consumes a green jelly pigment)

    Also in the ITEM and SPELL tables are new arguments for 'trophyMade' When you use a right-hand weapon, or spell, with one of these, then that trophy is added to your bag. These could be good things (the 'mining' spell resulting in 'gold nuggets' appearing) or bad things (using 'armageddon' giving you a 'cursed spark' trophy)

    For example, see the Evergreen GEL command which consumes a Green Jelly Pigment trophy, but creates a Slobber Eyeball trophy.

    And sorry, only one ammunition per thingy, so you can't use this to trivially do things like "this spell consumes 4 jellies, 5 earwigs, and 14 gondolas to create one hand of flax" You have to do that sort of thing with a script. Though with the miracle of subroutines, you should be able to make that data-driven within your quest files.

    And I extended the property editor to support these.

    Opens the trophy bag.. if you have one..

    Arg 9 of the trophy table is now a 'flags' field which includes:

    1 - no sell
    2 - no give
    4 - no discard

    This limits right-click menu functionality on the trophy bag. Scripted NPCs can disobey these settings.

    The script command to add an ACTOR to the scene now lets you specify its 'pain' sound effect as well.

    The full list is now:

    ACTOR &lt;id&gt;, &lt;nam&gt;, &lt;skin&gt;, &lt;pose&gt;, &lt;x&gt;, &lt;y&gt;, &lt;colorTable&gt;, "pain.wav"

    And without this, they should be silent. (so all old worlds will suddenly have silent-when-hit actors. Blame... um... Crusard!

    Not sure if anyone would ever really NEED these, but they let you do 'bit-wise' boolean math. They work just like the ADD instruction in that they start with a cookie, then modify it per the instruction. NOT is a bit odd since it requires no second argument.

    AND cookieName, 1 (contents of cookie 'ANDed' with 1)
    OR cookieName, 12 (contents ORed with 12)
    XOR cookieName, 8 (contents XORed with 8)
    NOT cookieName (contents ones-complemented)

    I can't believe I added this. How lazy can a world developer be, hmm? But here you go:

    IFEVEN @labelIfResultWasEven
    IFODD @labelIfResultWasOdd

    And there is no such thing as 'neither odd nor even' in my universe.

    When you get an onEventActorClick event, you can look at this cookie:


    and if it is not zero, it means they clicked on a VISIBLE (not transparent) part of the actor skin. If you don't check this, then it just means they clicked somewhere inside the actors skin rectangle.

    OK OK, this doesn't work. Sorry. It will only work if you actor uses pose 0 of its image strip, and that image looks the same when 'flipped' Sorry.

    To make up for that false alarm, I give you two more:


    These are set to the offset inside the actor rectangle where you clicked, in 'pixels' (not in screen percentags). (0,0) is the top left of the rectangle.
  • NEW CONDITIONAL TEST: J for 'Mission'

    Yeah yeah, I ran out of letters. Must mean the game is just about complete :)

    This allows you to test if the host has completed a mission (see below).

    IF J23, @hasDoneMission 23

    This is actually a pretty big deal and I hope I left it general purpose enough to be used for lots of stuff.

    Basically, with trophies we got the ability to make simple 'collection' quests (hereafter called 'missions') where your hero needs to go achieve N things and in return gets some reward. Without necessarily requiring a lot of scripting or scene work. Though, as you will see, Missions are handed out by NPCs in scenes via the new 'missions' button.

    Please read the Evergreen 'missions.ini' file for details, but the flow is something like this:

    1.) You define your missions in worldFolder/missions.ini

    2.) Each mission has a name, description, some message text, a requirements list, a needs list, and a set of rewards.

    3.) You issue missions via the new MISSIONS script command, which generally acts a lot like the OFFER command, adding a MISSION button in the scene.

    4.) Pressing the MISSIONs button opens the 'Available Missions' dialog which shows a list of all the missions offered in that scene, for which you meet the starting qualifications.

    5.) You can ACCEPT a mission, at which time it becomes OPEN/IN PROGRESS. At any time, you can ABANDON a mission to get it off of your open missions list.

    6.) You can review your OPEN MISSIONs list at any time by using the Book menu "Book of Missions" and see the progress you have made towards completing each mission.

    7.) When you have met the mission requirements, a 'collect reward' button will appear. Press that and you will collect a reward. (and the mission will be marked 'DONE' and thereafter only appear on the 'review past missions' dialog.)

    8.) Each mission specifies a "Qualifies" string which is a conditional just like that used in the quest IF command. So you could say:


    Meaning to qualify you must be Level 3 or above, have token 4, but NOT token 7, and you must have completed mission 23 (yeah yeah, 'J' Ok, call it a JOB and then it sounds like I planned it)

    9.) Each mission specifies a "Trophies" string which is a list of all the trophies you need to acquire before the mission is complete. For example:


    Meaning you need five trophy 1s, 10 trophy 23s, and 100 trophy 16s to complete the quest. When you collect your reward, these trophies will be removed from your trophy bag

    10.) each mission provides one or more of the following rewards:

    - Gold
    - Experience
    - abstract item
    - token

    By Abstract Item I mean:

    RewardObject=I23 (item23)

    which could be S15 (spell 15), etc. The same syntax as used by the GIVE command. Which can also give Gold and Tokens, so it's a little redundant and I leave it to you to best decide how you want to use it.

    11.) In the trophies table is a new field 'flags' and one of those flags is 'mission only' which means a monster will only drop it if it knows it is needed by one of your open missions.

    12.) Mission Sound Effects (which you should be able to override by world or theme, as well as any other sound)

    missionTrophy.wav -- each time you get a mission trophy

    This is a little silly, and you can test the date yourself, but there is some small advantage to this since I do things like "3rd monday in may" and "easter" calculations for you which are slightly non-trivial. You probably won't find your favorite holiday here, but hey, that just means you are some godless commie and not a member of the one true greatest country on earth! Denmark!

    Holiday ID numbers:

    #define HOLIDAY_NONE 0
    #define HOLIDAY_BIRTHDAY 1
    #define HOLIDAY_EASTER 2
    #define HOLIDAY_XMASEVE 4
    #define HOLIDAY_XMAS 5
    #define HOLIDAY_BOXING 6
    #define HOLIDAY_NYEVE 7
    #define HOLIDAY_NYEAR 8
    #define HOLIDAY_GNDHOG 9
    #define HOLIDAY_VALENTINE 10
    #define HOLIDAY_STPAT 11
    #define HOLIDAY_APRILFOOL 12
    #define HOLIDAY_EARTHDAY 13
    #define HOLIDAY_CINCOMAYO 14
    #define HOLIDAY_MOTHERS 15
    #define HOLIDAY_MEMORIAL 16
    #define HOLIDAY_FATHERS 17
    #define HOLIDAY_CANADA 18
    #define HOLIDAY_JULY4 19
    #define HOLIDAY_LABOR 20
    #define HOLIDAY_COLUMBUS 21
    #define HOLIDAY_HALLOWEEN 22
    #define HOLIDAY_VET 23
  • And the cookies are:

    num.holidayID (if this is 0, its not a holiday)
    str.holidayName (e.g. "Christmas")
    str.holidayGreeting (e.g. "Merry Christmas")

    My goal was to make it easier to have easter eggs in scenes, which only triggered on special days.

    The BIRTHDAY holiday is the annual birth day of the WoS character you are using. (It remembers the day of the year you made the character)

    All holidays last for 24 hours from local midnight.

    So, say your world has need for a lot of tabular data.. stuff that the WoS engine doesn't need to know about directly, but that you use in your scripts a lot. Say you have your own skill system, or potion making formulas or anything else which can be defined by rows of columns of data in a table.

    First the limitations. No more than 100 tables (stored in your world folder in files called "devTableNN.txt" where NN is 00-99)

    No real limit on the number of rows in a table (one line of text in your file is a row), but smaller is faster.

    each row is a bunch of comma-separated values (just like a QUEST file, only YOU decide what the columns mean.) You are limited to 30 columns and each row of text must be less that 4000 characters wide.

    You can pepper your table with comments, where anthing on the line after a 'semicolon' is ignored.

    Each column can have an arbitrary string (max length of 100 characters per string, I think.. well, same as for QUEST whatever that is MAX_PATH in computer terms.. minus a couple). It can be a number or text, but you should put text inside double-quotes.

    You can NOT use #include in a DevTable.

    You do NOT put QUEST commands in a DevTable.

    The first argument on each line is its "RowId" and should be unique. It can be a number (like I do with spells and such) or some text if you like. But each row needs a unique id (unique within that one table file). When you ask me to look for a row by its id, I am going to start with the first line of the file and keep looking until I find it or the end of the file. And the RowID starts in the first character of the line, no leading spaces, please.

    Remember, WoS will do nothing with your devTables other than fetch values from them (via cookies). And these are read-only, like the quest files. (Developer can edit them, just like quest files, but for the end player they do not change.)

    They are included in the world version, so tampering will result in a 'modified world'

    Example Table: devTable32.txt in your world folder

    ; This is my table of skins used in my mini-game
    ; ROWID, COL1=Actor#, COL2=SkinName
    Butter, 1, "Jumping Butter Can"
    Cheese, 2, "BlueCheese"
    ; Note, dan doesn't read these comments
    ; so that stuff I said about COL1 is just for me
    Then, to read the table in my SCENE script, I need to do three things:

    1.) select the current DevTable

    SET num.DevTableId, 32

    2.) select the current ROW of the table

    SET str.DevTableRowId, "Butter"

    3.) fetch one of the COLUMNS of information

    1: the skin name is #<str.DevTableCOL2>

    The end.

    str.worldName - name of current world being played (may not be capitalized in any particular way)

    item.desc - long desctiption of item
    item.ap - ability points provided by item
    item.fp - find probability of item
    event.missionId - id associated with @eventMission event
    str.actorNameNN - name of actor NN in this scene, if any.

    OK, these only work, like all 'events' if you are in a scene, are the host of the scene, and the scene is currently ENDed. They bring the scene back to life at the @label matching the event description.

    You can then ask for cookie "event.missionId" to find out which mission is being talked about.

    @eventMissionAccepted - they pushed the accept button
    @eventMissionAbandoned - they pushed the abandon button
    @eventMissionRewarded - they collected their mission reward

    Remember, they can do the Abandon or Reward anywhere they like, so don't depend on seeing these events inside of any particular scene (or even at all, since they can do these actions outside of scenes). These events are just for happy friendly NPC acknowledgements, and maybe some 'extra value' for those players who DO go all the way back to the scene which offered the mission in the first place.
  • MAP_FLAG_NO_ITEM 0x00100000 1048576
    // No using of items in the scene

10/15/2005 ALPHA 90 INCLUDES:

  • * COMPATIBILITY: Excellent!
  • * BUGFIX - Bug in CALL command
  • * BUGFIX - Crash when giving GP

    These work just like their integer counterparts, but do not truncate the result to an integer

    (and also do not limit you to a max value of 2 billion. HOwever, you should understand the trade-off between precision and accuracy. Just because you can now claim to have a trillion gold pieces, you could not add or subtract a single gold piece to that value. Internally I am using 'doubles' but there might be some digit truncation when saving to cookies. I think I can guarantee you at least ten significant digits.)


    You can now see what the current server's rules are set to:


    Note these are all read-only (like most stock cookies). and minVersion uses that same decimal version number as num.wosVersion (described below)

    I feel a little bad about this one, since I originally omitted it intentionally, wanting the game to encourage partying and avoid being exclusive.

    But people DO grief you by joining your party without permission, go afk, etc. So every other game has a BOOT command, so now WoS does too.

    Each trophy can be assigned to up to 10 RANGES of monster IDs. For example, an argument like this:


    means the trophy can be dropped by:

    Monster 1
    Monster 2
    Monsters 3 through 6
    Monster 15
    Monster 18
    Monsters 20-100

    PLEASE tell me that is ENOUGH already! :)

    I didn't really TEST this, so who knows if it actually works or not. But it didn't break evergreen, so I am happy.

    Basically, if you add a .ttf (TrueType Font) file to your World's root folder (the same folder that has quest.txt in it), then I will try to tell windows that it exists, at least for the duration of time that WoS is running.

    This SHOULD make it available to your Scrolling World Story and/or html pages. Maybe. Good luck!

    The TERRAINS table now has an *optional* arg3 which lets you specify a tokenID which allows crossing that terrain (without requiring boots). This was a great suggestion, Hesacon. (learn to 'swim,' get token, be able to cross water.)

    By clicking on a column header. This one's for you, World's End!
  • * NEW COOKIE -- Gives WoS Version


    You will probably need to experiment a little to understand the value. When you see 'A90' it is actually a hexadecimal number. This cookie will give you the decimal version of that number.

    A90 = 2704, for example. (But A89 is *NOT* 2703)

    As opposed to just standing out of view, ready to attack you again as soon as you reincarnate.

    There is a chance some worlds depended on the old behaviour (but I only ever heard complaints about the behaviour, so I hope it was OK to fix it.)

    I didn't actually TEST this, of course, but in theory if you are wearing level 100 equipment you you de-level to 99, you will just end up with that equipment removed.

    [CODE];DD 'cloud' shape of magic accumulation
    ;00 - tight random cloud
    ;01 - looser random cloud
    ;02 - loose random cloud
    ;03 - single circle
    ;04 - two circles
    ;05 - single circle - vertical
    ;06 - two circles - vertical
    ;07 - Big round circle
    ;08 - Halo
    ;09 - Vertical Halo
    ;10 - Horizontal Line
    ;11 - Vertical Line
    ;12 - Slow Large Dome
    ;13 - Fast LArge Dome
    ;14 - Slow Small Dome
    ;15 - Fast Small Dome[/CODE]And those same options should work for the 'attack' cloud shape (cloud over target)

    Please do not believe that cookies are 100% secure now. And if a cookie is violated (in the opinion of the code, which could easily be wrong) the only punishment is that I count how many times it happens, and let the world dev read that count with a new cookie:


    Take that with a grain of salt. Cookie protection defaults to being turned OFF, but world developers can enable via their config.ini file with this setting:

    cookieProtection = 1

    There are three possible values:

    0 - no protection at all (the default)
    1 - only cookies whose name starts with 'secure' are protected
    2 - all developer-created cookies are secure.

    It should be reasonably safe to turn cookie protection ON, but once on, you should (your world should) never turn it off (or reduce its level). To do so will probably end up getting all existing characters 'marked')

    Anyway, this is, I hope, a gentle introduction to cookie security which, while probably not being very secure, should not actually screw anybody up.

    It is a little known fact that monsters in a scene 'rest' when they are not hitting you, and the more rested they are, the harder they hit you (all else being equal). As of A90 they no longer appear in scene fully rested. They start with a random restedness. This means the first hit by each monster in the scene will no longer always be their max hit.

10/08/2005 ALPHA88 INCLUDES:

  • * COMPATIBILITY: Excellent! - But you will only be able to play with other A89 users.

    It works a bit like giving gold. First you open your trophy bag and right-click on a slot containing something you would like to give away.

    The popup menu now includes a GIVE option.

    After selecting that, the cursor will change to the new 'trophy' cursor and you can left click on someone in the scene to give them ONE of the selected trophy.

    Sorry, I lack the ability to give them the entire stack at once, isn't that stupid?

    But to make it slightly easier, I leave the cursor active so you can give one after another.

    To clear the cursor, you can: close the trophy bag, select some other cursor, or empty out the slot in question.

    The item given event will have an itemId of -1, and a new cookie 'trophyGiven' with the trophy id.

    If you hold the SHIFT key down while dragging trophies from one slot to another, it will move only ONE, and not the full stack. You can only use this to drag to an empty slot, or a slot which already contains the same sort of thing. Amongst other things, this is how you pull a few off the stack to sell less than the full amount.

    The dialog with the list of MIX servers on it, now has a little activity meter that lights up when you select a server (before you connect to it). This shows you how many people are on the server NOW (redundant), how many have visited in the last 20 minutes, the last hour, and the last day.

    The idea here is to let you see that even though a server may be empty RIGHT THIS SECOND, that it is actually a pretty active place and maybe it would be worth your time chilling in it for a minute, rather than just jumping to the server with too many people in it :)

    Honestly, I put this in more for Arcadia (which shares the same code), but I think it has some usefulness in WoS as well.
  • * New TNL METER.

    I added a little horizontal meter just under the chat splitter bar. (It shows only if you have the splitter pulled up enough to show the server name bar, which I notice a lot of peopler don't seem to do. In fact, screen shots NEVER seem to include the server name, which troubles me for some reason. Do people even know about the splitter? Do people ever resize the window?)

    ANYWAY, it's a meter showing how far along you are in the XP to your next level. And, just to be COOL, I made the newly-earned XP glow for a second or two.

    I merged the Arcadia unzipper into WoS, so that most players no longer will need to install WinZip to download and install new worlds.

    World Developers will STILL need to install winZIP to use the /publish command which I HIGHLY RECOMMEND USING. Plus the world patching is easiest with winzip as well, IMHO.

    Anyway, I tried all the existing worlds and didn't find any problems, so hopefully my unzipper doesn't have any serious flaws in it.

    I won't ruin the surprise. But it will be an unpleasant one, I am pleased to announce. It's not too late to get your act together when playing online.
  • * NEW CONFIG.INI ENTRY - configNoGivingGP

    World Dev's can optionally make GP ungivable in their world (I mean player to player GP giving), see evergreen config.ini for details
  • * NEW COOKIE - #&lt;num.hostTotalPP&gt;

    This shows the total PP earned by the scene host for the life of that character. Hopefully this will be used for complimenting hard-working players and not some sort of "I caught you auto-clicking your way to PP" hack detector.

    I have mixed feelings about this, since the concept of trying to charm an opponent's pet away from them, has a certain.. charm. But it didn't work really anyway and it led to oddness like charming your own pet in battle.

    To be clear, you can still (occasionally) charm MONSTERS... just not monsters who have already been tamed into being someone's PET.

    A89 allows you to have up to 10 monsters drop the same trophy (but all with the same probability).

    So in the column where you used to put the single monster ID, you can now use the dotted arguments, as in:


    Meaning this trophy can be dropped by monsters 12, 76, 23, or 199

    In A89:

    ; C Accumulation of magic around caster, before it 'launches'
    ; 0 - accumulate over caster
    ; 1 - accumulate within caster
    ; 2 - accumulate under caster
    ; 3 - at level of caster, but 128pixels towards target
    ; 4 - at level of caster, but 128pixels away from target
    ; 5 - at level of caster, but halfway between caster and target

    Sorry I missed that before. It will not say what you have in your config.ini file

    *** Hesacon is now a level 100 Pundit ***
    Your HP rose by 29 points.
    Your MP rose by 20 points.
  • * SERVER VARIABLES (at last)

    Note that I am not calling these server cookies any more. I appreciate how everyone thinks this is simple stuff, but it's not :) However, I think I give you a PRETTY good illusion of simplicity.

    Here is how it works from the point of view of a world developer:

    1.) New Quest Command: SET_SERVER_VAR used like this:

    SET_SERVER_VAR categoryName, variableName, value

    This then stores the value, on the current MIX server, in a file just for the current world, in a section of that categoryName, with a variable Name as shown.

    If you were to look on the MIX server itself, you would see a file added like this:


    And inside that file you would see:


    2.) New Quest Command: GET_SERVER_VAR

    You use this one like this:

    GET_SERVER_VAR cookieName, categoryName, variableName

    (note: this is like the SET command where the cookie name is NOT wrapped in #&lt;&gt; unless you are using some form of cookie indirection.

    You need the cookie to 'hold' the value once it is fetched from the server. After it is fetched, you use the cookie itself as normal. But the cookie is NOT the server variable, it is just the last fetched copy of the server variable. You need to use the GET_SERVER_VAR command again if you want to see what the current variable value is.

    Now, the MIX server is probably running on a distant PC, so the GET_SERVER_VAR command is not instantaneous. It is a bit like the WAIT command in that the script will jam up at that point, waiting for the value to be fetched. In fact, it will time out after a few seconds and just return a value of "" so that the script is not jammed forever.

    3.) Changes are published to all players on the server.

    What this means is that if I do a SET_SERVER_VAR on my PC (that is to say, I host a scene who does that as part of its script), not only does it set the variable on the server itself, but it informs all other players on that server that the value in question has changed.

    This allows them to keep their own local copy of the variable up to date, since:

    4.) Variables are cached on each client.

    What this means is that after you do a GET_SERVER_VAR to pick up a variable, its value is cached locally. If you then ask again, it doesn't really ask the server, it just gives you your locally cached copy of the value.

    This would normally suck, except the miracle of step 3 is that your cache is updated if someone else (or even yourself, of course) modifies that particular variable.

    Barring disaster, I think this keeps everyone roughly synced up with as little packet traffic as possible. Of course, stupid World Developers who call SET_SERVER_VAR constantly will result in laggy crappy gameplay. Then again, stupid developers can already do that. Don't be stupid. Think about it: "This command will result in remote users seeing something change, therefore it sends a packet, therefore I should do it as little as possible."

    5.) As cool as this is, it's still no guarantee

    For example, if two players simultaneously execute SET_SERVER_VAR, there is no guarantee which one will win the race. And if you are trying to, say, increment a variable, it may not increment the amount you expected.

    6.) The Mix Admin can 'opt out'

    While the server variables are probably not going to eat up much disk space, and there should not be any security issues (they are limited to the 'sandbox' of the mixVariableCache folder), you may not trust me, and/or you just may not want your server acting as a public disk space (btw, we're talking short text 'values' here, not MP3 files).

    If not, there is a new checkbox on MIX called "Allow Server Variables." Just uncheck that and any players on your server will be unable to set variables, and if they ask for a variable's value, they will be told it is blank.

    7.) The MIX Admin can set variables which can only be READ (not written) by the players. To do this you will have to manually open mixVariableCache/worldName.ini and edit the file with a text editor.

    You can add new sections and variables as you like. Any section whose name starts with "admin" can not be overwritten by players


    um, 'section' and 'category' are the same thing, sorry I switched terms in the middle.

    Because of the way windows works, you have to restart your MIX server after manually editing an .ini file before it will take effect.

    8.) EVENTUALLY, I will probably add an event like:


    and that should enable some fairly ambitious multiplayer gamelets. I don't want to do that yet since there are enough other unknowns to be worked out first. You should still be able to do some multiplayer stuff with the above. One thing to think about though is that while server variables can be limited to worlds and sections, they cannot be expressly limited by 'room' or 'scene' (and if you wrote a poker game, you would PROBABLY want to have multiple tables on the server... but maybe not.) You could simulate this by using the host sernum as the (or part of the) section name. BUt then you will accumulate never-deleting cruft in the cache.

    9.) What will hackers do?

    I guess I won't help out by suggesting snerty things you could do. At the end of the day, the scripting language already allows them to snert a bit, and this doesn't add TOO much variety to that. The MIX log will show who did what, so manual action can be taken.

    10.) THings to be done someday

    That event notification to wake your script back up when in incoming variable change is seen.

    Something to discourage nuisance scripts, if needed.

    Someway to let you modify admin sections if you are on the right sernum, from the right IP, or something.

    11.) limitations

    variable names, category names, and (to some degree) values must NOT use any weird characters. Try to keep things alphanumeric. The following characters will probably screw you up: [ ] = ,

    It's really the variable and category names which mainly have to be limited. values can probably get away with including some odder characters.

    I will endeavor to not crash if you disobey this, but I will not guarantee your world will work.

    [CODE]IF>= @label
    IF<= @label[/CODE]Silly me to not have those from day one.

    the eventActorClick event now sets two new cookies


    which, I hope, are the deltax,y values from the mouse to the actor's origin point. Expressed, I hope, in screen coords (100 = full width). Possibly of use in detecting accurace of center click, but probably requires all sorts of adjustments since the actor origin probably is not where you expect it to be

    Now this was a long time coming. Basically a FUNCTION in this context is a @label you can GOTO, but that can then RETURN back to line after you CALLed it. With arguments passed both at the CALL and at the RETURN.

    Note that RETURN only works with CALL, and any CALL should be to a label which always (eventually) executes a RETURN.

    The CALL command looks a lot like GOTO at first glance. Except that you can include a scene number before the @.

    For example:

    [CODE] SCENE 100

    ; This scene CALLs the function foo

    N: This is the first thing you see typed
    CALL 200@foo
    N: This is the THIRD thing you see typed



    SCENE 200

    ; This scene contains the function "foo"

    N: This is the SECOND thing you see typed
    N: You never see THIS get typed

    END[/CODE]You can pass arguments (up to 10) as part of the CALL command. Inside the function you can access them as cookies "arg0" - "arg9"

    Like this:

    [CODE] SCENE 100
    CALL 200@foo Hello, There


    SCENE 200

    N: OK, I say: #<arg0>, #<arg1>
    N: You should have just seen me say "Hello, There"
    END[/CODE]And you can return results to the caller the same way (note that the argN cookies are basically overwritten every time you use them, so don't put anything too valuable in them.

    [CODE] SCENE 100

    CALL 200@whatIsYourName
    N: I believe its name is #<arg0>


    SCENE 200

    RETURN Dan
    END[/CODE]As with CALL, you can return up to 10 args, like

    RETURN Name, #&lt;host.age&gt;, something, 23, ...

    And upon return those values will be in cookies arg0, arg1, arg3, ...

    You can put functions inside any scene you like (of course if you actually execute the scene itself someday you might accidently run them without meaning to.)

    You will have slightly better performance if you put your functions inside a low-numbered scene. Actually that is a lie, you get the performance by putting them in a scene near the front of your quest file.

    You might want to put them in a file by themselves and #include that file as the very first part of your quest file, even before all the tables.
  • * NEW LABEL FORMAT: sceneNumber@label

    Most, if not all, commands which use labels should be able to take advantage of the new format. This allows you to jump into the middle of some other scene, but you are not going to automatically inherit the scenes background etc. You will just be executing code in the scene starting at the label you GOTO.

    And there will be no possibility of RETURN.

    If you really wanted to switch scenes, you probably want GOTO SCENE n, but you might occasionally find a good use for this. As a programming practice, I thing it would be considered very poor form to ever do this.

    So I don't want to be encouraging bad habits in you budding programmer types. This is just a side effect of adding the CALL command and it seemed more interesting to include it than to prevent it. Of course, thinking like that gave us perl

    If you are unfamiliar with the term 'stack' in the computer sense, the usual visual metaphor is a stack of plates.

    As you add (push) plates to the pile the newest one is always on top. Then when you pick them up one by one (pop) they come back out in the opposite order to how they were put in. This is also referred to as FILO (First In Last Out).

    Now that we have functions, we have the ability for a function you CALL to blow away a cookie that you really wanted to keep. The data stack is a mechanism to help you protect yourself from that, by pushing cookies to the stack, calling the function, and then popping them back off.

    Two handle this, we get two new commands:

    PUSH cookieName
    POP cookieName

    Note that you can only push and pop cookies, not arbitrary values.

    PUSH temp (pushes the contents of the cookie 'temp')
    PUSH #&lt;temp&gt; (uses the contents of temp as the name of the actual cookie to be pushed)

    Only the cookies VALUE is pushed. Later when you pop it off the stack, you could actually pop it into a different cookie than where it lived originally.

    Say you had three cookies: a, b, and c.

    You could simply preserve them, like this

    [CODE]; Save a copy of the cookies on the stack
    PUSH a
    PUSH b
    PUSH c

    ; do something that damages them
    SET a "Badness!"
    SET b "evil!"
    SET c "clueless!"

    ; restore their original values
    POP c
    POP b
    POP a[/CODE]Note that we have to pop in the opposite order in which we pushed, if we want to get them back in order.

    But you can do stupid stack tricks like this:

    [CODE]; swap the contents of cookies a and b
    PUSH a
    PUSH b
    POP a <-- puts into a what was in b
    POP b <-- puts into b what was in a[/CODE]The Quest Cookie Data Stack is SEPARATE FROM the Quest CALL return stack. So you don't have to worry about the stacks interfering with each other.

    Both stacks, however, are cleared when your SCENE 'ends' or starts. So you can't PUSH a value in one scene and then hope to POP it off in a new scene. If you wanted to do that you would just save the value.. in a cookie!

    People will have a natural inclination to push values, like

    PUSH "Bill is a silly head!"

    But that won't work. It will look for a cookie whose name is "Bill is a silly head" (which won't exist) and then will push its value (which will be "")

    The other thing about the cookie data stack is that it can't hold super long cookies (well, depending on your definition of super long. I have a max of about 200 characters per cookie pushed on the stack. If you cookie starts out longer than that, it will get truncated.

    This is really intended for use inside functions, so that you can protect scratchpad values

    PUSH temp
    SET temp, #<arg0>
    ADD temp, 3
    DIV temp, #<arg1>
    MUL temp, #<arg2>
    SUB temp, #<arg0>
    SET arg0, #<temp>
    POP temp ; restore original value of temp
    RETURN #<arg0>[/CODE]And we don't care about blowing away 'argN' since they get re-used on every function call/return anyway (well, potentially. In fact they only get blown away when you include arguments with the CALL or RETURN commands.)

    ANYWAY, you may never need the data stack. And you can easily shoot yourself in the foot.


    * it's temporary (cookies are non-volatile, but the stack evaporates)
    * it is cleared when scenes start/end
    * your cookie might be too long to fit
    * if you call PUSH, you better call POP the same number of times, or your stack will over or underflow.

9/10/2005 ALPHA 88 INCLUDES:

  • Fix for A87 world versioning bug (ergo the release)
  • Paralysis now wears off after awhile
  • new Monster FLag "Will not flee" for super brave monsters
  • Trophies can now have "tokenNeeded" entries (so you only find them while quest is in progress)

9/4/2005 ALPHA 87 INCLUDES:

  • COMPATIBILITY: Excellent!

    I added the buddy hat to the diary page (no, you can't sort by them). Also I added a 'last encountered' field which tracks the last time you met up with that character. Eventually I will use that field to prune/auto-prune using some rule like "keep the 4000 most important entries" where 'important' is something like "recently encountered, or has a buddy hat, or you have written personal notes about.."

    1.) nothing happens automatically (other than the hard-wired maximum of 8000 entries)

    2.) a new menu option exists:

    "Delete all but newest pages..."

    3.) It gives you PLENTY of warning

    4.) And then prunes you down to no more than 4,000 entries. Throwing away entries which:

    * have no buddy hat
    * have no written notes (your personal notes)
    * you haven't seen in world for a long time

    where long time means "only the 4000 most recent"


    NOW, I only added the 'last seen' info in A84 or so, so most of your old entries don't have that. They are then all treated as equally old, so it is up to the filesystem to control what order they are preserved in (and no, the file system does NOT pump them out in strictly chronological format, so it's a crap shoot)

    SO, be sure to 'buddy' people whose pages are important to you.

    And, bear in mind, that unlike Arcadia (where you automatically get a page for everyone you meet), WoS still only makes a page when you show curiousity about someone.


    And I fixed the individual delete button as well.


    By the way, I thought it would be cooler to show you each entry as I delete it. It makes the whole thing take a bit longer, but it's more interesting than looking at a white screen.

    It's a little terrifying (I just pruned 2500 of my own pages), but it seems to work as designed.

    Now, that bit about "if you have written a personal comment about them" probably deserves some explanation... Way Back When (The diary is what, ten years old?) I stored those notes differently. If you, like me, have some notes stored in that old format, then those pages will not be automatically protected.

    If you are at all concerned, making any trivial change to the notes will get them recorded in the new format.

    NOTE: You might want to make a backup copy of your original wos/bio folder before running this command. I mean, it's new code. Could be broken..

    ; TROPHIES are carried in the Trophy Bag
    ; They are basically only used for quests. You can, for example, define specific trophies
    ; to be dropped by individual monsters. "Wolf Ear" "Bear Fang" etc. and then use
    ; cookies to check if the user has collected what you asked for.
    ; At any given time, the player has exactly one trophy bag, and it has a width and a height (measured in 'slots')
    ; Players start out with no bag at all, and you must script a scene to give them a bag when you feel they deserve
    ; one (probably an NPC bag-maker will give or sell them a bag, and possibly upgrade it over time.
    ; Bags look like this, for example: (width=4, height=3, 12 slots total)
    ; +----+----+----+----+
    ; | | | | |
    ; +----+----+----+----+
    ; | | | | |
    ; +----+----+----+----+
    ; | | | | |
    ; +----+----+----+----+
    ; Each slot can hold only one sort of trophy at a time, for example a fang in one slot, and a claw
    ; in another.
    ; But most trophies (per following table) 'stack' in the sense that you can hold up to.. say.. 10 fangs
    ; in the same slot, and only when you get your 11th fang do you need another slot.
    ; The user can drag the contents of slots around, or right-click on them to sell or discard a slot's
    ; contents. They can only sell when in a shop scene. The game will automatically pick the 'best slot'
    ; to use when a new trophy is given to the player (unless you use a slot-specific cookie commands).
    ; But, should the player end up with two slots holding less than a full stack of the same trophy, they
    ; can 'drag one into the other' to merge them.
    ; If you want to completely remove the bag from the player, set both its width and height to 0. Note
    ; that if you make the total number of slots smaller than it was, items will be lost if they cannot all
    ; fit in the remaining number of slots. You might want to think about which dimension you want to
    ; change first, if that will make a difference.
    ; It is the user's responsibility to keep some empty slots available, or they might not be able
    ; to get an important trophy. The world developer can measure how much room is in the bag and
    ; warn the player if they have not got room for a mission-critical trophy.
    ; Trophies can NOT be shared between players. Trophies are not ITEMs and fulfill no purpose
    ; other than as named-quest maguffins.
    ; The world developer has the following commands and cookie controls over the player's Trophy Bag
    ;// COMMANDS (running out of letters, so 'Z' means trophy only because.. um.. I have no idea :-)
    ;// %Znn - name of trophy nn (e.g. "Hello, %1, that's a nice %Z23 you have there!")
    ;// GIVE - give cc of trophy nn (e.g. HOST_GIVE Z23.11)
    ;// TAKE - take cc of trophy nn
    ;// Conditional - go to label if host has cc or more of trophy NN (e.g. IF Z23.10 @hasTenOrMore)
    ;// COOKIES
    ;// num.TrophyBagOpen - (r/w) 0 if bag closed, 1 if open (cannot open 0 - slot bag)
    ;// num.TrophyBagWidth - (r/w) width of bag
    ;// num.TrophyBagHeight - (r/w) height of bag
    ;// num.TrophyBagSlots - (r) total slots in bag
    ;// num.TrophyBagSlotsInUse - (r/w) non-empty slots in bag (WRITING any value, empties bag completely)
    ;// num.TrophyBagEmptySlots - (r) empty slots in bag
    ;// num.TrophyNNN - (r) how many trophyId=NNN hero has, in total, in bag
    ;// num.TrophyBagRoomNNN - (r) how many MORE trophyId=NNN hero could take (filling all stacks and slots)
    ;// num.TrophyIdInSlotNNN - (r/w) id (or 0) of trophy in slot NNN. (write REPLACEs slot with a SINGLE trophy)
    ;// num.TrophyCountInSlotNNN - (r/w) qty (or 0) of trophy in slot NNN. (write REPLACEs count, without changing id)
    ;// (cannot set count if id=0, cannot set count above 'stackHeight' for id)
    ; Each Possible Trophy is defined by one line in this table, with the following 8 arguments per trophy. Note that
    ; Trophy images are 32x32 'icons' stored in "filmstrip" files in the ART folder of your world. These must be
    ; prepared like any other WoS BMP file, and use the official WoS 256 color palette. There are assumed to be
    ; guidelines in the file, so only 31x31 pixels are available for art. The upper left pixel of the file defines
    ; the 'transparent' color for the icon.
    ; // arg 0 ID# (1-4095)
    ; // arg 1 trophy name (31 char max)
    ; // arg 2 ImageFileName, (in ART folder, assumed to have .bmp extension)
    ; // arg 3 ImageIndex, (0 for first frame of 'filmstrip' in ImageFile)
    ; // arg 4 stack size (how many of these fit in a single Trophy Bag Slot) (0-99)
    ; // arg 5 gpForStack (How much a shop will pay for a FULL STACK of these)
    ; // arg 6 demonId (Which monster 'drops' these when killed) (use 0 if not to be found on monsters)
    ; // arg 7 probability, (percentage chance 0-100 you will get one for killing that monster)
    ; Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Arg6 Arg7
    ; ID Name ImageFileName ImgIndx StackSz StackGP DemonID findProb
    ; 1234 1234567890123456789012345678901 123456789012345
    1, "Green Jelly Pigment", "trophy", 0, 20, 5, 1, 80[/CODE]
    FIGHT/FIGHT2 opcode allows you to specify starting monster location.

    I think this is like the oldest un-fulfilled request.

    [CODE] FIGHT 1.50.50

    makes monster id 1 appear at location (50,50)
    (where screen coords are 0-100). You cannot
    use (0,0).[/CODE]* Can no longer flee scene while paralysed (if disease has a 'cannot move' effect, that also prevents fleeing.

    If a monster sees a human player in the scene who is 20 levels or more above it, it will grow fearful and may flee the scene in mid-battle.

    The degree of fear increases with the level difference.

    Monsters with wisdom &gt; 100 will also consider their own remaining hit points and grow even MORE fearful as they get closer to death.

    Now, this COULD be a big change... especially for people who depend on being able to wack green jellies all night with an auto-clicker to get PP. Hopefully this won't destroy the game.
    NEW CONFIG.INI values

    [CODE]; these affect PK damage in your world. Basically the same computation is made when a player
    ; attacks another player, but at the last moment it is multiplied by these percentages,
    ; hence you can make PK battles last longer or shorter times in your world.
    ; Does NOT affect healing.
    ;pkHandPercent = 100
    ;pkMagicPercent = 100
    ; this is used to increase (>100) or decrease (<100) the percentage of successful spell casts
    spellSuccessPercent = 100[/CODE]

    More or less. They aren't smart enough in a PK battle to fight some humans but not others. They either consider ALL humans to be allies, or ALL humans to be enemies.

    What's new is they no longer always think humans are enemies. If the monster who summoned them is a pet, or was summoned by a human, then they will think ALL humans are their pals.

    the "DEFAULT_SKIN" command lets you specify the skin to be seen by players who do not have the REAL skin selected by a player. If you do not use this feature, the default will come from the genders.ini file (as before).

    Evergreen has been updated to use an assortment of Josh Skins for this purpose.

    You know how if you say:

    FIGHT -34

    It brings in a monster 34 who then fights FOR the humans.

    You can now also say:

    FIGHT +34

    This brings in a monster who still hates humans, but is unable to actually attack them. Instead it will attack human-friendly monsters (like that -34)

    So this allows a scene to have a 'monster on monster' battle while the humans watch in safety (or call out pets to help).

    This does NOT affect whether humans can pound the monsters (and thus influence the fight).. would need some sort of scene directive if you wanted to prevent that.

    Also, the FIGHT won't END until all the '+' monsters are dead... since the living humans in the scene can be thought of a extra '-' monsters.

    I think I will need some sort of MFIGHT command which factors humans out of the equation.

    That is to say, you can now dump some training and get some PP back. You get back only half what you put in (this isn't a FREE redistribution system!). It's probably mainly of use only to people like me who like to make interesting shapes on the element training diagram. But hey, it might help out in an emergency where you have to sacrifice three levels of fire to get one level of water that you need RIGHT NOW.

    But only if you do it MY WAY (heh heh). I will have to document this more clearly but. Wholly under control of the publisher, with no daily involvement from me, a publisher can add 'patch' information to their world's INFO file. Then when a player clicks on the world in 'check on line for new worlds' Not only do I tell them what I used to tell them (new world available, you should get it), I also give them a button to install Just The Patch which you feel a person still running their version should get.

    From the player's perspective, the patch is then automatic and easy, with no ZIP skillz required. It's just like the download button, but faster.

    Of course, if they are several versions behind, and you didn't provide a patch to take them directly to the latest version.. well, then they have to push the patch button again... and again..

    But what is a patch file, you ask? It's NOT a 'real' patch file with compressed diffs. That would be 'too dangerous' (Uncle WoS won't run an EXE file!)

    It's just another .ZIP file, just like your world's .ZIP file, but from which you have removed all the files which didn't change between those versions.

    I have a test world up "PatchWorld" (won't work for you until you have A87) which gives version 1.1 as the DOWNLOAD and offers 1.1--&gt;1.2 as the PATCH (and possibly more flavors by the time you try it).

    I made one of these just by using /version + PUBLISH to make version 1.2, then opening the ZIP file itself, and deleting all files older than the date I made 1.1

    It was actually kinda easy, since WinZip will sort by date.

    Then I renamed it: and put on my site, along with an extra line in the INFO file claiming that users with version 1.1 should run this patch.

    Anyway, it's easier than it sounds... for everybody.

    Thanks to Flamelord for insisting (and being correct) that I had crammed in an arbitrary limit for the number of usable poses in an actor filmstrip.

    The new arbitrary number is 255 (which is less arbitrary since the packets in question impose this limit)

    But I remain on record as thinking it's a bad idea to have hugely-wide image files. Still, this should be YOUR choice, not mine :)

    If, like me, you have 50 or so installed worlds, you probably find it tedious to step through my 'cool' scrolling menu.

    I have changed it to show (and step) five worlds at a time, and to do so with an animation speed 2 or 3 times faster as before.

    I also reduced the amount of "wobble" in the selected menu item.

    World Developers may now (blame f'nok!) include a 'status' field in their INFO file. Which will then be displayed in the new "Status" column on the CheckOnline dialog. If you do not provide a status, your status is "Old"

    F'nok suggests you use status with worlds like "Demo", "Beta", and "Released" etc. But in fact you can put any (short) string you like. Yes, I will ban publishers who put profanity in their status line.

    I plead that you do NOT use this line for ADVERTISING. Note that to see this line, a user must click on your world name, and when they do that, your world's HOME PAGE displays. Do your ADVERTISING on your world's HOME PAGE, please! And by advertising, I mean advertising for your world. I trust all world developers to do their best to minimize popups on their world's home page.

    So, since I don't actually KNOW the status and version info for the world until after you click on it, I now cache the 'last known values' for those fields. In your new "c|wos\save\worldCache.ini" file where maybe someday I will let you record your own personal little factoids about each world... like how much time YOU have spent playing it, etc. Private info, not public. Maybe. Anyway, an interesting place for me to stick stuff, even about worlds you have never played, but are somehow aware of.

    I will automatically dub your world 'Broken' if it does not have a functional INFO file. It's important that you host an up to date INFO file for your world, so if you see yourself as 'broken' (Like Aerianell is), then feel free to fix your INFO file and let me know if it has a new url.

    I will automatically dub your world 'Old' if it is otherwise functional, but lacks the new 'status' field in its INI file. I am not completely happy with 'Old' and am open to a better word. I sort of like "Legacy" but maybe that sounds TOO cool, and people will intentionally set their status to that just to be cool. I need a word which is both not insulting to the world AND yet something a world developer would just as soon update to something nicer.

    Since otherwise, it was going to overwrite whatever you had manually added to your world.ini file, I went ahead and made it so you can manage these fields directly in the dialog itself.

    I want no excuses for people NOT using the /version and PUBLISH features of WoS :)

    Turns out it would go blank if your world was over 20 megs or so (making it slightly less than useless). I also added bandwidth tracking and give an estimate of how long until download completes.

    I also detect 'bad downloads' and cache the result of your last download attempt "Failed DL" Publishers should consider moving to a different host if players regularly complain about 'failed download.'

    I think the only player-unfriendly thing left is worlds which advertise they are version 1.5, but actually deliver version 1.0 That's pretty evil (KOC), since it encourages the user to download the old version over and over again.

    Oh, and I wish I had a popup detctor. Some worlds (I'm lookin' at YOU WoSInstantMessenger) really have an unacceptable number of popup windows. I might have to just manually un-publish worlds when I see that. I mean, 4 copies of the *same* ad popped up in 1 second? Whose purpose does THAT serve?

    These are for controlling what generates War Points... hopefully there are more coming, but it's a start.

    [CODE]; set this to a positive value to enable the posting of normal PK 'karma points' as 'war points' to the War Ladder
    ; otherwise, comment it out, or set it to 0. The value 'scales' the points (bigger value, fewer points)
    ; These war points are applied only to the specific war(s) between you and the guy you killed.
    ; set this to non-zero to enable "XP Earned from Monster Kills" to drive 'war points' on the war ladder
    ; If you set this to 1000, for example, you will earn one war point per 1000 monster XP points
    ; These points are awarded to your guild for ALL its open wars at once.
    monsterXPAreAlsoWarPoints=1000[/CODE]* WAR GUILDS AND WAR GUILD LADDER

    I can't believe this is the first I mentioned this in this topic. I talked about it plenty elsewhere.

    With A87 pre-release, we get the first cut of this feature. It's all new code and does not prevent you from doing what you did before. It's new.

    You access the feature through the new GUILD WARS menu in the game's GUILD menu.

    You have to be incarnated and wearing the uniform of a WAR GUILD to take part. If you are the guildmeister, you just set the 'is war guild' checkbox on the guild's web page.

    You might want to be in the habit of selecting GUILDS/GUILD WARS/DECLARE WAR after incarnating to make sure you are all hooked up.

    That panel is where you can declar war, but mainly it just shows you the people immediately above you on the ladder, and the status of any wars you have going with them.

    For the full ladder, and your full list of wars, there are other menu options.

    World developers control what earns war points in the war. For evergreemn (in pre-release A87 at least), you earn two ways: 1.) the XP you earn from killing monsters (divided by a 1000) generates WP for ALL the wars you are in (that your current uniform is in, I should say). 1.) normal PK activities. And I mean totally normal PK activities. I have not yet done the promised 'fair fight' stuff..

    Anyway, I hope it will make sense. The ladder will probably get cleared frequently.

    This is like /villagers (and uses the exact same code), only it lets you browse 'filmstrip' files in the ART folder. Not everything in that folder is a filmstrip, but this is useful for browsing things like your 'trophy' image files. I include 4 such files with WoS now, containing various torn off bits and pieces of Josh's monsters. It's invaluable when you need to know the frame number in a 'square frame' film strip.

    It's presumably all wrong in a non-square frame film strip, so I guess I should point that out (like, for example, shields.bmp and swords.bmp and armor.bmp)

    This was more work than it sounds, but it is hard to type about it in a way which takes up very many words.

    How were people supposed to know about the /props editor again? The Property Editor is your pal. As is /tile and a huge monitor.

5/14/2005 ALPHA 86 INCLUDES:

  • Fix for a nasty bug which prevented you from saving your character

4/16/2005 ALPHA 85 INCLUDES:

  • * COMPATIBILITY: Excellent! Well, except: you can only play with other A85ers, and you will no longer be able to use some pets. Specifically, if you caught some pet in an earlier release when it was legal to do so, but now it isn't... well, you can't use that pet anymore. I'm sorry.

    Also, you are advised to destroy all hacked characters (delete them directly from the SavedHeroes folder, if you try to delete them from inside the game you will probably trigger something you don't want to have triggered). This includes characters that: 'a friend made for me, I didn't hack, I don't know how to hack!'

    Pretend it is the airport, and your character is a piece of luggage. If you didn't pack it yourself, back away from it slowly...

    And do this BEFORE you upgrade to A85. If you didn't read this warning in time... well... why did you have a hacked character in the first place?

    Yeah, sucks to be me. As you know, use of trainers is not allowed/encouraged/tolerated (balance that against my fundamental inability to catch you at it, or do anything about it.)

    But be warned that I will *try* to do something about it, so you might actually end up being one of the poor schmoes who can't play any more. And for the junior lawyers in the audience, the word 'trainer' encompasses all forms of illicit game activity, whether it was called a trainer, a memory editor, a hack, etc.

    If the game doesn't give you a button to do something, it probably doesn't want you doing that thing.

    Just ask yourself: would YOU want to play against someone with a OneHitKill button? Of course not, and I know your answer to calm whatever conscience you have left is "I don't care," but if you really don't care, well, move along please!

    Anyway, I know a lot of trainer users have been losing game privileges lately, and I have received some lovely apology emails, but you see it's too late once you reach that point.

    I think it's been a long time since I added an actual new feature! And this one is only very peripherally associated with hacking.

    In the BOOKS menu is a new option which opens a text window that logs all your battles (in this session). It just records everything that happens "X enters, Y hits Z, Z loses N hit points, Z is dead" etc.

    Yes yes, the reason I added it initially was to give people something to argue about "Hey, you hit me 3 times in a row" or "hey, it says it was only a 3 hp damage, but it killed me!" etc.

    But it's actually fun in its own right, and something I can spiffy up over the next few releases. And if I am industrious (not), I will add an option to log them to disk as well.

    Something like this:

    Tue Mar 22 01:40:16 2005

    Server: Uncle Dan's WoS Server

    A battle begins, hosted by Samsyn
    * Samsyn (SOUL 1) is here. (Level: 83, A:390, D:785, HP: 2749)
    * Green Jelly threatens you. (Level: 1)
    Green Jelly attacks Samsyn
    Samsyn loses 1 hit points
    Green Jelly attacks Samsyn
    The attack misses Samsyn
    Samsyn attacks Green Jelly
    Green Jelly loses 1021 hit points
    *** Green Jelly has been killed.
    You earn 3 GP and 4 exp. points.
    The battle is over[/CODE]
  • * 'OR' operator added to conditionals.

    The single vertical pipe character '|' is now supported in Quest script conditional testing. Remember you still cannot use parentheses to make anything truly complicated, but now you can say:

    IF T23+T44|T67-T87|T15, @label

    which will go to @label if the user:

    1.) has Tokens 23 AND 44
    2.) has token 67 but NOT 87
    3.) has token 15

    Evaluation is done left to right and stops at the first true clause.

    This one's for you, Silver. :)
For older release notes, click here.
  Copyright 1998-2014, Synthetic Reality Co. All Rights Reserved