Well of Souls:
Home Page
Contact Us
Download It!
DonateCommunity:
Guild Hall
About Guilds
WoS Ladders
Bulletin Board
Hall of Heroes
Josh
Developers:
Custom Skins
Other Worlds
Author's_Guidelines
Art_Submission
Cheat Codes
Beta Testers Page
Development_Notes
Synthetic Reality
|
| Wanna
Be a Tester? It's EASY! Just pop
me an email at wosBeta2@synthetic-reality.com 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 95 INSTALLER and PATCH A95
are now on line.
|
| |
RELEASE NOTES: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.
- * QUEST
DIARY EXPANDS COOKIES (IN TOKENS)
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.
- * QUEST
DIARY SUPPORTS CHAPTERS
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:
+TOKENS
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 TITLE
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
- * UNZIPPER
HANDLES READ-ONLY FILES
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.
- * IMPORTANT
FLAMELORD FIX
The download progress meter now more
accurately expresses your download speed
in bits per second (as opposed to 'baud')
- * VISTA
SUPPORT
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.
- * MANY
MIX/NETWORKING CHANGES
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
cookieName0
cookieName1
..
cookieName<numCards - 1>
cookieNameCount
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
#<cookieNameCount> 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 #<cardsCount>, 0
IF= @something went wrong, should have
been 52
1: The index of the first card is
#<cards0>
1: The index of the last card is
#<cards51>
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.
- * REWORKED
WELL INTERFACE
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.
- * MINOR
SCENE CHANGES
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.
- * MENU
COMMAND SUPPORTS CHECKED ITEMS
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...
- * ACTORS
CAN NOW BE LAYERED
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.
- * TROPHY
AMMUNITION REQUIREMENTS SHOWN
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.
- * FIGHT
COMMAND MAY NOW INCLUDE STARING 'FACE'
DIRECTION OF MONSTERS
So, another dotted argument:
FIGHT 23.50.75.1
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.
- * FIGHT 0
REMOVES MONSTERS FROM SCENE
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.
- * NEW HOST
COOKIES
num.hostAttack -- aggregate attack points
of host
num.hostDefense -- aggregate defense
points of host
- * TITLE BAR
CHANGES
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=http://mypage.com
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!
- SPELL
ANIMATION CHANGES
- '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
- * NEW
IF CONDITIONAL
IF<> or IF!= will go to the
label if the previous COMPARE operation
yieled 'not equal'
- ASK
OPCODE CAN BE SECRET TO ALL
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!"
- COOKIE
SUPPORT ADDED TO MORE COMMANDS
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.
- TIMER
EVENTS!!
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
END
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:
@eventTimer4
(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
END
@timerEvent1
WEATHER %R9
TIMER 1, 1.0
END
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!)
- SPECIAL
TIMER TRICKS
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.
- BUGFIX
- NO MORE CAMP DRAGGING
Sorry. And thanks to Pippin (and others)
for clearly documenting the procedure.
- GENDER-SPECIFIC
PAIN SOUND
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:
pain1.wav=pain10.wav
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'
- COMMAS
IN MONSTER NAMES AND SKIN NAMES ARE
REMOVED
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"
- CURSED
TROPHIES
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.
- AMMUNITION
TROPHIES
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)
- RESIDUE
TROPHIES
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.
- NEW
SLASH COMMAND: /Trophy
Opens the trophy bag.. if you have one..
- NEW
TROPHY TABLE COLUMN: Flags
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.
- NEW
ACTOR ARGUMENT: Pain Sound
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 <id>,
<nam>,
<skin>,
<pose>, <x>,
<y>,
<colorTable>,
"pain.wav"
And without this, they should be silent.
(so all old worlds will suddenly have
silent-when-hit actors. Blame... um...
Crusard!
- NEW
QUEST BOOLEAN COMMANDS: AND/OR/NOT/XOR
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)
- NEW IF
CONDITIONS: EVEN AND ODD
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.
- ACTOR
CLICK EVENT INCLUDES TRANSPARENCY CHECK
When you get an onEventActorClick event,
you can look at this cookie:
event.actorVisible
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:
event.inActorX
event.inActorY
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
- MISSIONS
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:
Qualifies=L3+T4-T7+J23
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:
Trophies=5x1,10x23,100x16
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)
missionAccepted.wav
missionAbandoned.wav
missionComplete.wav
missionTrophy.wav -- each time you get a
mission trophy
- HOLIDAY
COOKIES
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_THANKSGIV 3
#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.
- GENERIC
WORLD TABLES
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.
- EVEN
MORE COOKIES
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.
- MISSION
EVENTS
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.
- NEW MAP
FLAG - NO_ITEM
- 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
- * NEW
FLOATING POINT MATH FUNCTIONS
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.)
F_ADD
F_SUB
F_MUL
F_DIV
F_MOD
* NEW RULE COOKIES
You can now see what the current server's
rules are set to:
#<num.ruleMaxPlayers>
#<num.ruleMaxAFK>
#<num.ruleMinVersion>
#<num.ruleLadder>
#<num.ruleNoCheat>
#<num.ruleNoMod>
#<num.ruleNoMigrate>
#<num.ruleNoPK>
#<num.ruleAllPK>
#<num.ruleNoBleep>
#<num.ruleNoEavesdrop>
#<num.ruleNoPets>
#<num.ruleArenaPK>
Note these are all read-only (like most
stock cookies). and minVersion uses that
same decimal version number as
num.wosVersion (described below)
- * PARTY
LEADER CAN MANUALLY BOOT MEMBERS
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.
- * EVEN
MORE TROPHY FLEXIBILITY
Each trophy can be assigned to up to 10
RANGES of monster IDs. For example, an
argument like this:
1.2.3-6.15.18.20-100
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! :)
- *
WORLDS CAN PROVIDE THEIR OWN FONTS
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!
- *
TERRAIN CAN BE CROSSED BY TOKEN, AS WELL
AS BOOT
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.)
- * WORLD
DOWNLOAD LIST CAN NOW BE SORTED
By clicking on a column header. This
one's for you, World's End!
- * NEW
COOKIE -- Gives WoS Version
#<num.wosVersion>
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)
- *
MONSTER LEAVE SCENE AFTER KILLING YOU
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.)
- *
DE-LEVELLING FROM 100 to 99 NO LONGER
CRASHES
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.
- * NEW
SPELL PATHS
[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)
- *
COOKIE PROTECTION
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:
#<num.hostCookieFaults>
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.
- *
MONSTER FIRST HIT NOT ALWAYS HUGE
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.
- *
TROPHIES CAN BE GIVEN
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.
- * NEW
TROPHY BAG BEHAVIOUR
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.
- * NEW
MIX RECENT ACTIVITY METER
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.
- *
INTEGRATED UNZIPPER
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.
- *
SPECIAL SURPRISE FOR PREVIOUSLY BANNED
PLAYERS
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 - #<num.hostTotalPP>
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.
- * CAN
NO LONGER CHARM PETS
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.
- *
MULTIPLE MONSTERS CAN DROP THE SAME
TROPHY
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:
"12.76.23.199"
Meaning this trophy can be dropped by
monsters 12, 76, 23, or 199
- * NEW
PATH POSSIBILITIES FOR SPELL CASTING
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
- *
TROPHY 'SELL' MENU NOW USES LOCAL WORD
FOR 'GP'
Sorry I missed that before. It will not
say what you have in your config.ini file
- * LEVEL
UP MESSAGES INCLUDE NOTE OF HP/MP GAINS
*** 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:
directoryMixIsIn\mixVariableCache\Evergreen.ini
And inside that file you would see:
[categoryName]
variableName=value
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
#<> 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
[adminConfig]
season=spring
quest_of_the_day=23
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:
onEventServerVariableChanged
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.
- * NEW
COMPARISON COMMANDS
[CODE]IF>= @label
IF<= @label[/CODE]Silly me to not have
those from day one.
- * NEW
EVENT ARGUMENT
the eventActorClick event now sets two
new cookies
event.dx
event.dy
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
- * QUEST
LANGUAGE SUPPORTS FUNCTIONS
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
END
------------
SCENE 200
; This scene contains the function
"foo"
@foo
N: This is the SECOND thing you see typed
RETURN
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
END
----
SCENE 200
@foo
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>
END
----
SCENE 200
@whatIsYourName
RETURN Dan
END[/CODE]As with CALL, you can return up
to 10 args, like
RETURN Name, #<host.age>,
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
- * NEW
COOKIE 'STACK'
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 #<temp> (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
[CODE]@MyFunction
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.
Remember:
* 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 th
| |