Welcome Guest ( Log In | Register )

Furcadia - The Second Dreaming!!
2 Pages V   1 2 >  
Reply to this topicStart new topic
> Adventure game project., Thoughts & suggestions much appreciated.
Farrier
post Jan 26 2003, 04:42 AM
Post #1
Group: DEP Admins

Farrier

[I should point out that reading this thread may be a big turnoff if you like DS as a nice simple scripting tool. Don't read unless you like techy stuff. Also long ramblings about the internals of how I'm going to do this. But I do really, really want feedback on it at every stage, to keep my motivation going.]

I've decided to create a large multidream adventure game, to test DS to (at least some of) its limits in a realistic stretching of its muscles.

I've decided to make my project a one-player game. Until we get phoenixspeak, there's just not the ability to track things like conversation flags, quest flags, etc, on a per-person level in the DS.

I could do it with bots, but I'm trying to keep bot usage to a minimum here: they should ONLY control information transfer between maps.

I could do it by tracking them with a specific floortype for each player, but I just cannot be doing with that.

Being singleplayer also means that I can use "when somebody moves" code to always know exactly where the furre is, even when he's not the triggering furre (say, from a timer or bot-triggered event).

Phoenixspeak will also (I hope) allow things like quest flags, conversation flags, inventory etc to be carried from map to map. At the moment, that's something that MUST be done with a bot.

To make it one-person, I intend to have it so that when someone enters a dream, a flag is set that auto-ejects any other people arriving, with a polite apology and explanation. Bots (well, anyone shared or owner) can reset that flag. If a bot detects someone leaving, then each bot checks to see if he arrived at their map (ctrl-B is EVIL!) and if he isn't found anywhere in the network of dreams, the flag is reset.
====
4-hour disconnects.
All my bots will be disconnected at least once every 4 hours (there are NO better uptimes available for dialup ISPs in the UK, unless you pay $160/month or more). They need to be able to recover, return to the dreams, and find out about all the state changes that were made in their absense.

That last bit sounds really tricky, so I think instead, I'll have a room in each map for the DS to teleport the player to when the bot leaves the dream. There will be an emit sent to the player, something like: "The bot has been disconnected by the ISP and so cannot track state changes. The dream has been frozen until the bot returns, which should be within about two minutes. In the meantime, would you like to [some time-wasting exercise]?"

Trouble is, I can't guarantee that the DS will detect a disconnect.
====
Setting up:
So the "chief" bot (probably actually an active alt) will upload the dream and enter it, then summon the subordinate alts. Each of them will load their dreams, and enter them.

Each of the dreams will have "if they are the owner" and "if their name is..." code to move the bots to the right place to load their dream as fast as possible. If the dreams are already loaded, this should allow the bots to return to their correct maps in as short a time as possible. Though I will probably, once the dreams have all been properly loaded, have them all `quit, so that their dream and their coordinates within it are stored on the server in case of a disconnection.
====
Bandwidth:
I'm limited to dialup, so bot commands and informational emits to the bots will be very short and minimalist, to limit the traffic. I still expect to see round-trip times up to half a second.
====
Moving people from map to map:

There was a largish thread about that a while back: it's possible, if you have one bot in each dream (as much as you would need to keep each dream up anyway).

You just have the DS report to the bot in a dream whenever someone enters a portal to the next level of dream (or a "back" portal). Then, when they arrive in the other dream, the bot in that dream sends commands to the DS to teleport the arriving furre to the correct point on the map.

Tricky, and probably breaks if large parties move from map to map at the same time, but doable for a single-player game.

But I have a better way. The bots will constantly update the array of quest flags and inventory list in each dream simultaneously, so that a whole bunch of information doesn't need to be sent through at once when they change maps. It will also constantly update the "arrival point" variable, so that the "when a furre arrives in the dream" code will always send the furre to the right place.

Basically, the bots are just acting as information-pipes between the dreams.
====
Repetition of DS, strings and graphics between levels may come to be a significant part of the download size of each level, and of the DS-lines in each level. Time will tell.
====
Verbs:
I'll be removing the sitting/lying patches so people can only stand, and use sit/lie as verbs for other stuff - at the moment I'm leaning towards using these for inventory management.

At least now we can have typed commands, so I'll also be able to have "eat", "talk", "look", "throw", "fight", etc, coming off that.
====
So far, the most important line missing is one to change the item missing in someone's paws. You can't change the colour of paint on your paintbrush, eat food, use a once-off key, or craft something out of something else, while it is in your hands. Things you hold cannot break, be used up, or be fixed. They are immutable, and cannot change.

I intend to have it that something like a burger could be eaten only once, then a flag will be set to indicate that they have done so, and a message will be emitted {You cannot eat the same item twice.}  If they drop it after eating it, it will be replaced on the floor by an empty burger wrapper. The same would be the case with any other one-shot (or even N-shot) items.
====
And stuff-in-hands is causing me more grief. This time, it's them leaving the map that I'm concerned about.

When a furre leaves the map, they will drop their item. If they left by walking into a portal, then the item will be placed RANDOMLY in the map.

Only way to clean THAT mess up, that I can see, is for the bot, when the player leaves, to issue a command to clear all of that kind of item from the map, then to emit commands to place all those of that object that SHOULD be there back onto the map.

With DS reporting to the bot, I can track the position of every object and furre in the dream, detect when they pick up or drop items, etc, so I can know where all the other ites of that type are located.

Messy.

Then, in the map they arrive at, their hands will be empty. I will have to either place an item similar to the one they were holding at their feet, or in their inventory. I think I'll go for "at their feet" - that way, if it's a weapon, they only need to ctrl-G when they arrive in the dream, and they are able to defend themselves. I'll have to have emits like "You stumble down the stairs, dropping whatever you were carrying" so that they know they've dropped it, though.

Messy, very messy.
====
I'm wondering how to do inventory. I was initially considering doing it by having a command to show the inventory, which would then place an "open bag" floor tile where the player is standing, then F3 or something would cycle through the items in it. Moving off the floortile would close the bag and remove any item on that floor.

That's pretty easy to do in DS, is visual and tactile. But then I thought a text based solution might be better:

#inventory command will emit:
"[+] Your inventory contains the following:
[+] rail gun
[+] box of ammo
[+] box of ammo
[+] bag
[+] chest
[+] titanium wok
[+] flak vest
[+] Type "#drop" and a number to take something out of your inventory."

#drop 6 will emit "you drop item 6" (or, if there are enough strings to have a separate "you drop" line for each item, "you drop item 6, the titanium wok") or "there is no item in slot 6."
I guess I could also do it as two lines, to save on strings:
[+] You drop item 6:
[+] titanium wok

#armour command will emit: "Your current armour is: 1=Flak vest. 2=kevlar leggings 3=cheap plastic helmet. Type "#remove" and a number to remove the armour, #wear to wear an item held in your hands."

#remove will emit stuff like "You remove the cheap plastic helmet and place it in your inventory." (or you drop it if inventory is full), possibly as multiple lines, or as item numbers.

#wear command will do an automatic remove if that item is worn on a slot that is full, then emit stuff like "You wear the titanium wok on your head. You feel well protected, but know you look stupid." - at least, if there are enough strings!

#open will open a bag or chest that you are standing on (or possibly only those in your hands? Not sure), and list the contents as it would an inventory. Each bag in the world is a unique item with its own array to store the contents. I suspect I shall use a floor array in each dream to store these, and keep the actual items there, rather than do the more complicated real-array thing.

...Which is all very nice.

But one other idea I was thinking of is to store their position, then put them by a great big bag graphic, with all the items in slots. They can then walk about to their heart's content, organise their inventory, and then walk off the bag to be teleported back to where they were in the game.

Completely intuitive, and doesn't take up any string lines.

====
Close Combat:
I've decided that walking into a creature will cause you to attack it. That means you might get into some fights you might rather have avoided, but tough.

Also, firing a missile at it will probably be taken as a sign of aggression, too.

Algorithm I'm thinking of using is that it subtracts your armour number (updated whenever you #wear or #remove) from their attack skill, and their armour number from your attack skill (updated whenever you pick something up - held items are counted as weilded).

A random roll is added to both, then the higher number has hit.

Damage is then done as either a fixed number, or possibly something more complex like a random roll plus the hitting person's damage rating (depends on weapon you are holding).

I'm not going to bother with skill levels for the time being. I'll wait for phoenixspeak for that kindof thing.
====
Ranged combat:
I'm thinking of doing it much the same as above, only they don't get a chance to attack back.
So you get their armour subtracted from your attack skill, plus a random number. If the result is positive, or over a certain arbitrary number or something, then you hit, doing whatever damage.

Of course, they can maybe shoot back, which is going to be fun to progr... script.
====
Conversations.
The first part of this question is a user-interface one. How do I want to initiate a conversation with an NPC?
That depends, I think, on whether I want NPCs to move around, and whether I want them to be fightable.

I *do* want them to amble around randomly, which means that I don't want them to be fightable: if you walk into them, they should just move away from you, in case they are blocking your path.

I intend to use fallout/ultima style conversations, so you'll get a spiel of text from them, then a list of options that you can say back. So you'll see something like:

[x] Mechanic: "Y'know, I could fix this car up for ya, but it's gonna cost!"
[x] #say 1: Go on then, how much?
[x] #say 2: I could offer you this fine parrot?
[x] #say 3: If you won't do it as a favour, forget it.

Then you'd say the relevant thing.
This will rely on one or two variables as conversation flags, indicating who you are talking to and where you are in their conversation tree.

Of course, unlike in Fallout/Ultima, you can walk away in the middle of a conversation, so conversation trees CANNOT assume you have read a whole branch, even if you started out on it.

Next question is how best to store these trees? DS might have suddenly become considerably more advanced, but it's still not able to store really complex data structures, so it'll need to be simple.

I don't know what the limit on the number of strings is, but I suspect it's not huge. Strings will also be used to give every item type a name so either conversations will have to be very short, or very few.

What I think I'll need is a whole bunch of clauses like "if they say "#say 3" and the person they are talking to is set to 4, and the conversation flag is set to 47, set the conversation flag to 93."
====
The bots:
I'm thinking of having this as a single multithreaded perl script, that fires off one thread per bot, each of which loads in its information from a mysql database. Since all they need to do is keep track of the user position, dream items, inventory, and bag contents, and occasionally clean up a dream when a user leaves, I think this can be made to be a quite thin bot.
====
DS limit:
Along with the unknown string limit, this is my biggest concern. But that's why I'm doing this - to see just how much can be accomplished in 6000 lines. By keeping the number of NPCs to a minimum, as also the number of items that can be held in inventory, I can minimise the damage.
====
Ideas:
I'd love to hear people's ideas on this. Few things are as disheartening than embarking on a big, fun project, only to find that nobody else in the world is at all interested.



This post has been edited by Farrier: Jan 28 2003, 10:55 AM
Go to the top of the page
 
+Quote Post
DarkHorse Pterid
post Jan 26 2003, 05:40 AM
Post #2
Group: Furres

DarkHorse Pterid

OK. I'll start with: "This sounds frggin' fantastic!"


Not being a (real) programmer I have little to no idea how the bots will work, but in the unlikely event I can help with the DS (or in other ideas, e.g. producing a .MID 'soundtrack') I'd love to.

A couple of small thoughts that occurred to me while reading through the plan:

"Trouble is, I can't guarantee that the DS will detect a disconnect." - Feel free to use me as a guineapig (NTL dialup: cut off every two hours.)

"Of course, unlike in Fallout/Ultima, you can walk away in the middle of a conversation, so conversation trees CANNOT assume you have read a whole branch, even if you started out on it." - What you could do potentially is stop the player moving once they've initiated conversation (either by surrounding them with item 254, or turning on a DS flag to move them immediately back where they came from.) By making sure all conversations are started and finished, you can simplify the routine for checking what people have and haven't said, if that makes any sense.

...and that's about it for now.
Go to the top of the page
 
+Quote Post
Farrier
post Jan 26 2003, 06:28 AM
Post #3
Group: DEP Admins

Farrier

Heh :)

Good idea on the speech thing - though I don't like restricting the player, so I'll probably only do it for those "important" conversations with major plotpoints.

I've had a thought about disconnects, too. The bot may well never "leave" the dream until it reconnects, which may be 2 minutes or more. I've been disconnected and come back on to furc with a different alt, and my disconnected self was still lying there, still clickable and able to see the desc, for several minutes.

So then what I should do is have the DS maintain a timer - say, 15 seconds. Have the bot send a message every, say, 5 seconds to reset the timer.

If the counter ever reaches zero, then the bot has disconnected.

Sure, there'll possibly be some inconsistency if the player uses or picks up or drops something in those 10-15 seconds it takes the DS to realise. I can't help that, I don't think. But at least it keeps the effects to a minimum. 15 seconds of inconsistency in four hours, I can cope with.

After all, if a major plot item gets lost somehow, I can always go on as an alt and magic it into their inventory. :)

I think so long as I resynch their inventory and bag contents between the dreams, I'll be fine, anyway.

I shalldefinitely take you up on your offer for a midi thingummy, I think, but I'll wait and see how far I get before I ask you to do any work on a project that may never get "finished".
Go to the top of the page
 
+Quote Post
Tucow Darkspirit
post Jan 26 2003, 01:47 PM
Post #4
Group: Furres

Tucow Darkspirit

Alright! I've been waiting for someone to take a run at this; I was planning much the same thing, but eventually decided to wait for PS. However, there's no good reason why it can't be done (although to a slightly simpler degree) with the DS we currently have at our disposal. Interaction with NPCs would be a good system, but I would suggest using the Everquest system- NPCs speak based on what you say to them. I'll explain why this is a good system in a second. When you get the NPCs to say their first line (by saying hi or bumping into them), the EQ system displays lines of text, then things you may wish to ask the NPC about in brackets. Eg. "Sigh... it's been a tough living since the [fish famine]" You may reply, "What fish famine?" and the words 'fish famine' would trigger more lines in reply. Why is this a good system? Because in your travels you may find things that give you an idea of what to ask an NPC about... things that they normally wouldn't talk about offhandedly. Now say you hear some legend of an "all-powerful fish god" (again, just an example)... you might think back to that one guy who seemed to know a thing or two about fish... so you go to him, say something along the lines of "Do you know anything about a fish god?" and the words "fish god" would trigger more text... perhaps sending you off on an interesting quest.
   Anyway, one of the reasons I never went ahead with a project like this myself is I thought I would be doing it alone. PS would be out before I ever finished. However, now that a few other people seem interested, I would be happy to help out in any way I can. Map design or long, repetitive coding... I'm willing to do whatever you may wish.
Go to the top of the page
 
+Quote Post
Ehvo Lu Shynn
post Jan 27 2003, 11:54 AM
Post #5
Group: Furres

Ehvo Lu Shynn

.

Farrier!

{I'm fairly certain I mentioned this before, but in case you're senile...} ;) : Anytime that I'm online that you need a paw to test anything in any dream that you are developing or troubleshooting or whatever - please (please) feel free to poke me or summon me; I love dream projects. {And I like your company :}

:angel:

One of the terrific things about the new text DS is the ability to do adventure games... I explored a dream last week that was a real joy - I could tell the dream builder was a neophyte at dream making, but! the dream included a fun little treasure-seek adventure game using the text emits, and it was like a "proof" of how powerful the text emit commands are for bringing a dream alive.

I really like these kind of games too, so I am very gung-ho on your project.

Now I do have some comments/suggestions/ideas/feedback
about adventure games and DS and multi-player capability...

In reading your statements about differentiating between players... I had some ideas I'd like to share (on a philosophical note, as these might or might not be ideas you'd want to use)... I think it would be possible to create a multi-player game for up to six players... tho it's a tad klunky, it would work --- by allowing one of each species into the dream.

To expand on your "polite eject" idea:

CODE
(0:0) When everything is starting up,
// Do whatever else you do for dream startup and
(5:300) set variable %rodent_in_dream to the value 0.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(5:302) take variable %rodent_in_dream and add 1 to it.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 2.
(5:200) emit message {Thanks for visiting my game dream. Unfortunately there are no player slots available for your player-type at this time, please visit again at a later time #SA} to whoever set off the trigger.
(5:78) eject the triggering furre.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 1.
(5:15) move the triggering furre to (#,#), or to someplace nearby if it's occupied.

(0:10) When a furre leaves the dream,
(1:20) and the triggering furre is a rodent,
(5:304) take variable %rodent_in_dream and subtract 1 from it.


And, while it is not really possible to track dynamic player statistics from dream to dream without a bot, or from session to session without PhoenixSpeak, it should be possible inside a dream to use dynamic statistics for a single session using variables:

CODE
(0:0) When everything is starting up,
// Do whatever else you do for dream startup and
(5:300) set variable %rodent_in_dream to the value 0.
(5:300) set variable %rodent_strength to the value 0.
(5:300) set variable %rodent_agility to the value 0.
(5:300) set variable %rodent_dexterity to the value 0.
(5:300) set variable %rodent_wisdom to the value 0.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(5:302) take variable %rodent_in_dream and add 1 to it.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 2.
(5:200) emit message {Thanks for visiting my game dream. Unfortunately there are no player slots available for your player-type at this time, please visit again at a later time #SA} to whoever set off the trigger.
(5:78) eject the triggering furre.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 1.
(5:15) move the triggering furre to (#,#), or to someplace nearby if it's occupied.
(5:300) set variable %rodent_strength to the value 4.
(5:300) set variable %rodent_agility to the value 8.
(5:300) set variable %rodent_dexterity to the value 10.
(5:312) set variable %rodent_wisdom to the total of rolling 2 dice with 4 sides plus 2.

(0:10) When a furre leaves the dream,
(1:20) and the triggering furre is a rodent,
(5:304) take variable %rodent_in_dream and subtract 1 from it.


I suppose an array could be used for the
above stats, but I don't see the point ;)

The same thing could be done on a slightly more ponderous scale between dream uploads, to carry between player sessions by "hard coding" skills according to a player's name. The easiest rendition of that would be for the popular static arena type combat, but I'm not going to elaborate on that.

:D

I would do inventory tracking by variables, too... possibly something like:


CODE
(0:0) When everything is starting up,
// Do whatever else you do for dream startup and
(5:300) set variable %rodent_in_dream to the value 0.
(5:300) set variable %rodent_strength to the value 0.
(5:300) set variable %rodent_agility to the value 0.
(5:300) set variable %rodent_dexterity to the value 0.
(5:300) set variable %rodent_wisdom to the value 0.
(5:300) set variable %rodent_available_INV_num to the value 1.
(5:300) set variable %rodent_INV_item_one to the value 0.
(5:300) set variable %rodent_INV_item_two to the value 0.
(5:300) set variable %rodent_INV_item_three to the value 0.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(5:302) take variable %rodent_in_dream and add 1 to it.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 2.
(5:200) emit message {Thanks for visiting my game dream. Unfortunately there are no player slots available for your player-type at this time, please visit again at a later time #SA} to whoever set off the trigger.
(5:78) eject the triggering furre.

(0:9) When a furre arrives in the dream,
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_in_dream is equal to 1.
(5:15) move the triggering furre to (#,#), or to someplace nearby if it's occupied.
(5:300) set variable %rodent_strength to the value 4.
(5:300) set variable %rodent_agility to the value 8.
(5:300) set variable %rodent_dexterity to the value 10.
(5:312) set variable %rodent_wisdom to the total of rolling 2 dice with 4 sides plus 2.
(5:300) set variable %rodent_available_INV_num to the value 0.
(5:300) set variable %rodent_INV_item_one to the value 0.
(5:300) set variable %rodent_INV_item_two to the value 0.
(5:300) set variable %rodent_INV_item_three to the value 0.
* (etc. - to the number of inventory slots you want to allow)

(0:10) When a furre leaves the dream,
(1:20) and the triggering furre is a rodent,
(5:304) take variable %rodent_in_dream and subtract 1 from it.


...and here's an example of how I would manipulate inventory:

CODE
(0:17) When somebody picks up object type 35 (ticket),
(1:20) and the triggering furre is a rodent,
(5:302) take variable %rodent_available_INV_num and add 1 to it.

(0:17) When somebody picks up object type 35 (ticket),
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_available_INV_num is equal to 1.
(1:202) and variable %rodent_available_INV_num is less than #. // the total number of slots plus one.
(5:300) set variable %rodent_INV_item_one to the value 35.
(5:302) take variable %rodent_available_INV_num and add 1 to it.
(5:200) emit message {The certificate has been added to your inventory, you may now drop the object. For assistance on using your inventory, type the words: !help inventory} to whoever set off the trigger.

* You need to add a (0:31) When a furre says {!help inventory}, block for instructions.

(0:17) When somebody picks up object type 35 (ticket),
(1:20) and the triggering furre is a rodent,
(1:200) and variable %rodent_available_INV_num is equal to #. // the total number of slots plus one
(5:200) emit message {Your inventory is now full. To make a space available you must use an object from your inventory and drop it. For information about the inventroy, type the words: !help inventory} to whoever set off the trigger.


Of course, some might prefer to di such an inventory as an array?

In addition to the above, there'd need to be scripting to erase dropped objects and of course the scripting for when they use objects to also shuffle objects in the inventory when one is used, and reassign the %rodent_available_INV_num ---- and that's just all for one "player" species.

Anywho, dunno if any of those ideas would be of use to you, but I thought I'd share some of the ideas I had on multi-player possibilities.

:)

(Sorry if I rambled on, I just love the new DragonSpeak, and I love your ideas for the project! )
Go to the top of the page
 
+Quote Post
Farrier
post Jan 27 2003, 12:03 PM
Post #6
Group: DEP Admins

Farrier

I should probably come clean - this is a project I have been looking forward to working on for some time. I, too, was looking forward to phoenixspeak, but I think that DS is at an advanced enough stage that I can get almost all of it done now.

And the DS needs its wings testing, and I'm hoping that this project will show up some things that PS will really need, and possibly some weaknesses in DS (like not being able to change what you're holding... argh-grrr!).

Maps, quests, plot, etc are all completely designed on paper, and I've been playing with making the maps in fshed.

Portraits are completed as bmp.

Basic items are completed as bmp, but need to be imported to fsh and have their properties set. Their DSable abilities for object interaction have also been designed (like, you can use a repair kit on a broken sentrygun to make a regular sentrygun, or you can smash it to get a gun. You can use a burger to get health, or you can feed it to things... and so on).

I'll also need some more complex items for illusions like steps and bridges, but those will only come to light as the maps are developed. The floor heights do change quite a bit in some maps.

Floor/wall textures are drawn as bmp, but have not been rotated/scaled/sheared yet.

Midi music has been written and farmed out to DarkHorse Pterid for final tweaking.

I'm looking for someone willing to do the artwork on the furre patches: I have colour drawings of each character and what they should look like from each side. But converting that to a 30-degree-up angle fsh is so far beyond my ability, that I'm looking to farm it out to someone else.

The biggest bit that's left is the DS. I've written an inventory system on paper on the train in this morning, and am about to make a sample dream to test it out - more info on that later.

Conversations are all designed, though I like your system of allowing spontaneous conversations as well.

Downside of it is that it's very hard to DIRECT the conversations, and I really do need that.

But I've always thought that games with menu-based conversations like Fallout and the Ultimas really needed a "raw text entry" field, where you could ask for information on a person, place, object, etc, by saying the name. Different people would know different stuff. Like, a fallout mechanic would know precious little about a piece of meat, and have no interest, giving you the default answer everyone else gives: "It's meat, retard." But a cook might say "It's fresh rock-hyrax meat. I'll give you two coins for it."

I'm vaguely considering having something like that, and probably will, if text-lines and DS lines allow. At the vary least have them tell you the "common knowledge" about where a person is and a bit of background on the person if you give a name. People in the same village will obviously know more about him than people in the next villiage, and his family will know even more, so need a way of ranking what people know on each topic, and making a "knowledge matrix". I think I'm going to leave that for PhoenixSpeak.

On the other hand, I personally HATE AND DESPISE those games that require you to pick up on a specific term in someone's speech, in order to get the vital clue. I think some of the earlier ultimas had this (the "name/job/bye" ultimas. You ended up spending more time throwing nouns at the people in the hope of getting something useful, than you spent playing the game.

So all important plot points will always be off menued text.

I currently have almost 32,000 lines of text: mostly conversation and item names). The original design presupposed using bots for the text, you see, so number of lines wasn't a limitation. I reckon I can cut that down a LOT, to maybe a tenth, but still, it's going to be heavy going.

And not knowing what the text limit is, will hurt. I think it's mentioned somewhere in the "long DS thread", so I'll have to dig through that.

Anyway, I'm off to make a sample map for the inventory system now. I'll upload when it's done, so people can play.
Go to the top of the page
 
+Quote Post
Lysanda
post Jan 27 2003, 12:07 PM
Post #7
Group: Furres

Lysanda

I started playing with something similar, but I couldn't figure out how to handle issues of inventory.  Hopefully this will be implemented within the next few years.  I don't have ANY bot experience, so for now, I just designed it to work by passwords.  So in essence, you "summon" your tools.  The big problem with this is that it will lead to "cheating" with other people telling furres the commands to summon certain items, so hopefully I can make it more puzzle based.

It wasn't as indepth as something like "Everquest,"  more like "The Legend of Zelda."
Go to the top of the page
 
+Quote Post
Farrier
post Jan 27 2003, 12:11 PM
Post #8
Group: DEP Admins

Farrier

No I won't, I'll reply to Ehvo's post first :)

QUOTE
Anytime that I'm online that you need a paw to test anything in any dream


One inventory-dream, coming right up!

QUOTE
I think it would be possible to create a multi-player game for up to six players... tho it's a tad klunky, it would work --- by allowing one of each species into the dream.


DARN good idea! Though it would mean doubling up (hextupling up) at least SOME of the DS. Might well be possible. But I've just designed a one-man inventory system. Hrm. More on that later, maybe you can think of a way of multiplayering it.

Actually, I can think of a way, but it might take up an infeasible amount of map space...

Hrm. "Maybe", is all I'll comitt to.

Anyway, working on test dream.



This post has been edited by Farrier: Jan 27 2003, 11:13 AM
Go to the top of the page
 
+Quote Post
Farrier
post Jan 28 2003, 06:22 AM
Post #9
Group: DEP Admins

Farrier

Well, I had an awful lot of fun on the inventory thing, and made a test dream for it that worked rather well.

I've used pillows to represent bags in the dream.

The way it works is that each bag, when you open it (by typing "=open"), is represented by a room, with objects in. This could be patched to look like the contents of a bag. You can move around in the "bag" room, move the objects around, and most importantly, carry objects into and out of it.

One of the objects you can take into or out of a bag is another bag.

You can't take a bag into itself, since you can only open a bag that is at your feet.

If you open a bag-within-a-bag, the room is cleared, filled with new items, and you are tepeported to the "start point" of the bag to make you realise that you have entered a new bag.

It might be worth giving a bag number by the bag, too, or possibly an indication of the recursion level.

When you exit from a bag, you are moved to the coordinates you were at before you entered it, which may well be within a previous level of bagging.

It definitely needs patching in order to be more intuitive, though. At the moment, I have a "room" to represent the bags, and it isn't too obvious that you have to follow the wooden arrow to go out of the bag, or that pillows are bags.

In the demo dream, I've also included a "wearing armour" screen (just an area with a badly-drawn stickman on the floor, with patches on head, body, feet, and hands where you can place armour and weaponry). This area needs to be patched in order to be more intuitive: it's hard to tell that floor pattern is meant to be a stickman.

You can get to that area by typing "=armour". Importantly, you can get to this area even if you are deeply nested in bags.

There's also a kindof "puzzle" - you have to arm yourself, then find a key, and go through the door. The key is rather well-hidden in the bags!

If people can give comments on how to make it more intuitive, how to shorten the code, or how to generally improve it, I would be very grateful.

I know that you can see the floor array for the bag contents, and the bag and armour areas, when you "shouldn't" - that's just so you can see how it works. It would, though, be more intuitive if you COULDN'T see them, I think.

At the moment this dream only works for a single person - you can mess it up REALLY badly (losing items, people unable to leave the bags, etc) if you have multiple people going in and out of bags.

Ehvo's idea could be implemented for multiple people, one per species, without having to repeat all the code six times. You just have six "bag" rooms in a line (say, vertically on the map), and have an offset that you add to the coordinates in each reference to the bag coordinates, depending on the species of the triggering furre. It would add a few lines, but certainly wouldn't even double it.

Anyway, that's the talk over with, here's the link to the dream to download:
http://www.geocities.com/dewi_morgan/furc/

This direct link may or may not work. (4k zip download)
http://www.geocities.com/dewi_morgan/furc/inventory.zip?

The DS involved is about 300 lines (125 lines for the inventory, and the rest for surrounding frippery), so I'll not be pasting it here.

If people just want to see the raw DS, I can put that up as a txt file, but it seems pointless, since it only makes sense in the context of the dream.



This post has been edited by Farrier: Jan 28 2003, 05:38 AM
Go to the top of the page
 
+Quote Post
Farrier
post Jan 28 2003, 11:50 AM
Post #10
Group: DEP Admins

Farrier

I should point out that reading this thread may be a big turnoff if you like DS as a nice simple scripting language. Don't read unless you like techy stuff.

Heh, this thread is kindof like a blog of my progress on this project :) I'm using writing here to crystallise the thoughts I have at the train stations (I can't write DS there as my laptop battery is dead, and I keep forgetting to print out the list of DS commands!)

So anyway, now I have inventory prettymuch nailed (though I think I want to fiddle with it a little more to implement Ehvo's idea, and I really, really want people's comments on it), today I'm working on the conversation code.

Now, there's a few things about this.

When you first talk to someone, the things they say will be different depending on previous events and current conditions - the game states. Each of these needs a flag. Here's some flags that might be set for Jim:

Have_met_jim: If not set, Jim will say "Hi, who're you?", and player gets options like "Who are you?", etc.

Have_asked_jim_for_quest: if not set, allows options like "Do you have any cool quests for me?". If set, Jim might ask "How're you doing with the quest?".

Completed_Jim's_quest: If set, gives the option "I've completed the quest!"

Holding_Jim's_Calculator: If set, gives the option "Would you like your calculator back?"

So as you can see, flags can be both once-off (once you've completed the quest or met Jim, you can't unmeet him), or togglable (you can drop the calculator again).

Flags can affect both what Jim says, and what options you are given to say.

So conversation trees are dynamic. They can change even during the course of the conversation: you might return to the same point in the conversation tree, but be given different options. It's quite common to have a kindof "root menu" of subjects in a conversation tree, and each one disappears as you finish discussing it, until all that's left is "Bye."

I intend that when you talk to someone, they will say something (even if just "Hi."), and you will be given possible responses. Your conversations will be composed of repetitions of that pattern, "NPS spiel->PC response" until either the character terminates the conversation, or you do.

I think this means that my data structure has to be able to:

1) Tie a person to a conversation.

2) Then tie the conversation to a list of possible first spiels from the NPC.

3) Then tie those NPC spiels to a list of flags, in order to choose which one to say.

3) Then tie each NPC spiel to a list of possible responses.

4) Then tie each response to another lise of flags, in order to choose which ones to make available.

5) Then tie each response to another list of NPC spiels, looping back to point 2.

So:

NPC spiel flags->NPS spiels->response flags->responses->(repeat)

To me, this looks best implemented as an array of strings (responses and spiels), each string linked to an array of flags, and an array of pointers to other strings in the same array.

Way I'd do that is have a vertical line in the map, containing items with item numbers indicating string numbers.
Then to one side of that, a horizontal line of items indicating the vertical position in the line of other strings that the string is linked to.
And to the other side of it, a horizontal line of flags that must be met if the string is to be displayed.

Cool thing about using the map rather than real arrays is that you save a HECK of a lot of lines of DS that would be required to set those up as arrays, and you save a lot on DS lines, too.

More importantly, you can use area-effect commands to affect the entire floor-array in a single command!

So you'll have a chunk of the map with item values like (where F=flag, S=string, and R=response):

FFFSRRRR
FFFSRRRR
FFFSRRRR
FFFSRRRR
FFFSRRRR
...

This does mean you only get about 200 possible lines of text.

If you split responses and spiels into two separate map colums, though, you get 200 of each. Which, for a map with about 15 characters in it, works out to about 13 different things they can each say and that you can say to them. If that's not enough, you can always have TWO columns of spiels (or responses, or both), giving you about 27 items each.

I'd limit the maximum number of responses to four. And the max number of flags to about two or three. So each column takes off 8 from the width of the game map.

I'm not expecting the playable area of any of my maps to be bigger than about a 100x100 diamond, though, or about 140 columns, so that should fit in, particularly since the maps with large numbers of characters and speech are going to be smaller - maybe about 90 columns wide.

If I use floor types to store the values, and cover over the floors with that black item, they can even be within sight of the map and nobody will notice.

That just leaves the task of the initial tying of the NPC to the initial list of possible spiels. I can either do that as another short floor array linking NPC numbers with text lines, or I can do it in DS - there are only at most about 15 characters per map, so it won't add too many lines. Since I'll have the DS for map arrays, though, I might as well try to reuse it if possible.

Well, that's how I *plan* to implement it, but we'll see how I go. Be interested to hear if anyone has any better ideas on implementing conversation trees in DS.

While I'm doing that, why dontcha check out that inventory stuff. I'm proud of it, apart from the fact that it's unintuitive because it's not patched. And I want comments!
Go to the top of the page
 
+Quote Post
Farrier
post Jan 28 2003, 12:27 PM
Post #11
Group: DEP Admins

Farrier

Hey, something just struck me about the inventory code.

I often need to move stuff from the virtual bag room to the bag's floor array, or back. I currently do this by doing six area-select-and-moves, or 12 DS lines.

But if each floor array had its own floor type, and that floor type was unque in the map, I could do it much more easily.

Just set the bag to be the same floor type, then swap with an arbitrary, known-empty position seven times!

(within the diamond (%bag_top)-(%bag_bottom),
set the floor type to %bag_floor_type
everywhere there's a floor of type %bag_floor_type
swap the object there with the object at 0,0
swap the object there with the object at 0,0
swap the object there with the object at 0,0
swap the object there with the object at 0,0
swap the object there with the object at 0,0
swap the object there with the object at 0,0
swap the object there with the object at 0,0

Now, I know that looks like it's just as bad, maybe only two lines shorter. The gain becomes bigger for larger bags, though: breakeven is a 4-square bag, and after that, you make a saving of one line per square, everywhere I use that code.

But that's not why it's so much better. The reason is that I don't need to store or calculate the positions of the bags, and I only need to know the two limits of the bag room dimensions rather than all six coordinate pairs (saving me a further 8 lines).

In fact, the bag arrays can be scattered around the map wherever I feel like, and don't even need to be straight lines, or even be connected. So long as there are six (or whatever I decide the bag size is) squares somewhere on the map with that floor type, then it will work.

Also, it becomes the same code for getting the stuff into the bag as getting it out to the virtual bag room :)

I think this is a more elegant solution, and will probably implement it when I implement Ehvo's suggestion of having multiple furres.

[Edit: of course, since diamond area selects are broken, and furre-type-detection is broken, I'll have to be careful how I do these. At least we're AWARE of the bugs, so we can code around them.]



This post has been edited by Farrier: Jan 28 2003, 11:33 AM
Go to the top of the page
 
+Quote Post
Lygeia
post Jan 28 2003, 09:44 PM
Post #12
Group: Furres

Lygeia

One note on your comment when trying to emulate "when someone drops any object" - which I assume means you'd like a single inclusive trigger for all drops? In general, you could use:

QUOTE

(0:17) When somebody picks up object type 0,
 (1:118) and they (didn't move from/aren't standing at) object type 0,   //  Have actually dropped an item
   [do stuff]


In the specific case of your inventory bag, you could mark each equip slot in armoury with a unique tile from a patch, i.e. head slot = floor type 500, and body slot = floor type 501, etc. Then, make a unique item from a patch that will match appropriate tile for equip slots using the a step value = to number of items legal for that slot, i.e. helms = item 2400 & 2401, body armor = item 2402 and 2403, etc., such that the same triggers work for all equip slots:

QUOTE

(0:17) When somebody picks up object type 0,
 (1:118) and they (didn't move from/aren't standing at) object type 0,   // Have actually dropped an item
 (1:117) and they (didn't move from/aren't standing at) floor type 180,  // not on open red tile
   (5:350) set variable %CurPos to the X,Y position the triggering furre (moved from/is standing at).
   (5:380) set variable %CurFloor to the floor type at (%CurPos).
   (5:304) take variable %CurFloor and subtract 500 from it.
   (5:381) set variable %WorkVar to the object type at (%CurPos).
   (5:304) take variable %WorkVar and subtract 2400 from it.
   (5:308) divide variable %WorkVar by 2 and put the remainder in variable %CurObj.

(0:17) When somebody picks up object type 0,
 (1:118) and they (didn't move from/aren't standing at) object type 0,   // Have actually dropped an item
 (1:117) and they (didn't move from/aren't standing at) floor type 180,  // not on open red tile
 (1:206) and variable %CurFloor is not equal to %CurObj.
   (5:200) emit message {You can't wear that there. I would make you pick it up again if I could.} to whoever set off the trigger.

(0:17) When somebody picks up object type 0,
 (1:118) and they (didn't move from/aren't standing at) object type 0,   // Have actually dropped an item
 (1:117) and they (didn't move from/aren't standing at) floor type 180,  // not on open red tile
 (1:203) and variable %CurFloor is equal to variable %CurObj.
   (5:200) emit message {It fits. Good.} to whoever set off the trigger.
*// Now, if you're careful about your var defs, you can use Felorin's bytecode hack
*// to turn on your equip flags... with the equip slot flags as the first vars defined
*// and their order corresponding to the order of the floor tiles:
   (5:302) take variable %CurFloor and add 1 to it.  // Above is zero based, but vars begin at 1, so inc it
   (5:300) set variable @%CurFloor to the value 1.   //  Set flag for active equip slot


Unfortunately, neither that nor your triggers as you have them will run if the user is swapping, i.e. if the user has already, say, mistakenly dropped %weapon_1 on the head slot and left it there, and subsequently tried to equip the head slot with obj %head_1, then the equipped flag will not be set even though the user has his helmet on. Likewise, you don't have a trigger for turning off the equip flags if the user changes his mind and takes an item out of its equip slot. I suspect that's simply because the script isn't finished, but I mention it since nastiness occurs if cases like that are unaccounted for.

You can run inverse triggers for when a user picks up item from an occupied slot:

QUOTE

(0:18) When somebody drops object type 0,
 (1:1004) and they're not holding item 0 in paws,    *// have picked up an obj
   [do stuff]


Dealing user swapping is more of a pain because you have to know what obj they picked up, which usually means keeping track of what obj is at their feet before they pickup. I usually just avoid the issue by making it an impossible circumstance by duping the gettable items with non-gettable items and swapping them on pickups/drops:

QUOTE

*// Swap in ungettable items when user picks something up
(0:18) When somebody drops object type 0,
 (1:1004) and they're not holding item 0 in paws,    *// have picked up an obj
*//  Make existing items ungettable
   (3:4) within the rectangle (#,#) - (#,#),     *// inside the armoury (or wherever)
     (4:2) only where the floor is not type #,   *// Whatever filters you need to exclude objects you don't want changed
       (5:26) add # to the object number.        *// assumes corresponding items are in same order in .fsh file

*// Swap in gettable items when user drops item
(0:17) When somebody picks up object type 0,
 (1:118) and they (didn't move from/aren't standing at) object type 0,   *// Has dropped item
*// More checks to limit trigger to being in armoury (or whatever)
*//  Make dropped item ungettable so it's not messed up by second swap
   (3:7) where the triggering furre is currently at,
       (5:26) add # to the object number.
   (4:0) clear all filtering,
*//  Make existing items gettable
   (3:4) within the rectangle (#,#) - (#,#),
     (4:2) only where the floor is not type #,
       (5:27) subtract # from the object number.
   (4:0) clear all filtering,


Whether you add or subtract is arbitrary, depending on whether the gettable items occur first or second in the .fsh file. Above assumes gettable items occur first. Not especially elegant when you have several items, but hey *shrug*
Go to the top of the page
 
+Quote Post
Farrier
post Jan 29 2003, 02:09 AM
Post #13
Group: DEP Admins

Farrier

Good idea on reusing the code for different equipment slots - I'll do that, it was silly of me to have it duplicating anyway.

QUOTE
CODE
(1:118) and they (didn't move from/aren't standing at) object type 0,   //  Have actually dropped an item
Yup. I forgot about the case of empty floor+empty hands. Thanks :) Though that's all moot now anyway - see below!

QUOTE
Unfortunately, neither that nor your triggers as you have them will run if the user is swapping,
I know :( I didn't know how to make it do a TRUE "when someone gets/drops any object". Not without writing a separate clause for every single gettable object, at least.

But now I can! Thank you, thank you for your suggestion about tracking stuff!
QUOTE
Dealing user swapping is more of a pain because you have to know what obj they picked up, which usually means keeping track of what obj is at their feet before they pickup.
So, if I have, near the top of my code:
CODE
When a furre moves, and they don't have share (so the bots won't break it!), save the object they moved onto in %floor_object.

When someone picks up any %floor_object, swap values of %floor_object and %held_object.
Then I can use the lines:
CODE
When someone picks up any %floor_object...
When someone drops a %held_object...
anywhere below that  in my code! :)

YAY!

I'm so happy about that :) :) Short, sweet, simple. Wouldn't work in the normal run of things where you could have any number of furres in the dream, but will work fine for mine!

QUOTE
Likewise, you don't have a trigger for turning off the equip flags if the user changes his mind and takes an item out of its equip slot. I suspect that's simply because the script isn't finished,
No, that was me being slack - thanks for pointing it out :)


Um, I probably shouldn't say this, but I woke up at 5:30am thinking about this project, and couldn't get back to sleep :)

First time in months I've been up before the alarm clock, let alone THREE hours before it!

Thank you once again for your great feedback. This is going to be some sexy inventory code, now :)

Though... I wonder if thre's a way to make it work for an arbitrary number of furres. At least, for as many furres as you have "bag-rooms". I'll bet there is, and I'll think more on that once I've got this conversation stuff done.

It's got a little more complex in the planning stage, since I realised that each thing you or the NPC said also needed to be able to set quest flags, and to run arbitrary DS lines too (like "drop a key at the furre's feet", "unlock a door", etc).

Now conversations take up one or more 10-wide vertical strips of the map. 3 for object-flags checked against floor-values, one for object-flags set to floor-values, one for arbitrary code run(floor) with a parameter (item), one for the text number to emit (and the item as a marker to say whether to emit it or not), and four for floors that indicate offsets to the next bits of text (not using any items in these squares yet).

I still think it's going to be surprisingly short in DS.

But the number of strings needed for a full conversation looks scary. At a minimum, it looks like about 10 for a simple greeting and introduction.
QUOTE
Hi, who're you.
 I'm Farrier.
 Mind your own business.
 Bye.
That's nice. I'm Vlady-bot. Pleased to meet you, Farrier.
Very well, if you'll be like that, goodbye.
Hello again.
 Hello.
 I'm sorry I was impolite earlier. My name is Farrier.
 Bye.
That's 9, plus one duplicate, for about the simplest possible conversation tree, with just one fork.



This post has been edited by Farrier: Jan 29 2003, 01:10 AM
Go to the top of the page
 
+Quote Post
Lygeia
post Jan 29 2003, 01:49 PM
Post #14
Group: Furres

Lygeia

QUOTE
Though... I wonder if thre's a way to make it work for an arbitrary number of furres. At least, for as many furres as you have "bag-rooms". I'll bet there is, and I'll think more on that once I've got this conversation stuff done.


I'm not sure about an arbitrary number, but certainly for a limited number. The most obvious way is for the active player(s) to drag around an identifying floor tile which would tell you which bag to go to, enable you to filter out any non-player (bots or whoever), etc. That looks kinda funky when the marker floor type isn't identical to the floor type they move into; and making it invisible can be tedious if there are more than a couple possible floor types that can be entered.

This situation is one of the reasons I asked for a command that'd save a furre's name in a string var, which would make the (1:70) and their name is {...}, condition mighty useful. You could, conceivable, still use this condition if you ran your dream on a "by appointment only" basis, which would allow you to go into the DS and edit the furre's name for all those conditions before you uploaded it. Alternatively, you could hand out PlayerCharacter .ini files with preset names for those going on the quest. Yeah, I know, pain in the butt. *shrug*

As far as conversation trees... You are running the user replies off a keyword parse from the sentence, retriggering, or having the user say a number for the choice? If the latter, the same menu can work universally if you require a user command word followed by the number of the choice for menu navigation.

This is where you have to get tricky and careful with how the text strings are set up in mydream.txt, but say there are always a max 5 replies (including Bye) that the user can make and they're grouped in order in sets of 5 (even if that means dummy text in mydream.txt) so you can do generic math on it. In mydream.txt, the strings are:

0:Master Socket kidnapped my kiwi!
1:[1]
2:[2]
3:[3]
4:[4]
5:[5]
6:whatever1
7:whatever2
8:whatever3
9:whatever4
10:Converstion Group 1 NPC Reply text
11:Menu option 1 text for Group 1
12:Menu option 2 text for Group 1
13:Menu option 3 text for Group 1
14:Menu option 4 text for Group 1
15:Converstion Group 2 NPC Reply text
11:Menu option 1 text for Group 2
12:Menu option 2 text for Group 2
13:Menu option 3 text for Group 2
14:Menu option 4 text for Group 2
... (you get the idea)
n:Bye

String 0 is always the kiwi message, so things would get trashed if started with a group 0. Also, remember that any identical strings are all put at one string index, which will wreck the numbering unless you make sure they are all unique (including place holder strings like the "whatevers").

CODE

(0:0) When everything is starting up,
   (5:300) set variable %MenuOpt_1 to the value 1.
   (5:300) set variable %MenuOpt_2 to the value 2.
   (5:300) set variable %MenuOpt_3 to the value 3.
   (5:300) set variable %MenuOpt_4 to the value 4.
   (5:300) set variable %ByeText to the value #.
   [ect., etc.]

(0:x) When a furre triggers the conversation,
   (5:300) set variable %ConvGroup to the value #.   *// i.e. 10 for Group 1, 15 for Group 2, etc.
   (5:301) copy the value of variable %ConvGroup into variable %NPCReply.
*// Set number of menu options (including Bye reply) player will have for initial branch
   (5:300) set variable %MainMenu to the value #.
*// Activate Menu trigger
   (5:50) set countdown timer 1 to go off in 1 seconds.
*// Seperate timer for menu options so you can delay in case text length
*// would scroll more lines than the text window will hold. You could use a
*// variable if you want.
   (5:50) set countdown timer 2 to go off in 3 seconds.


(0:32) When a furre says something with {=reply} in it,
*// Something to abort if they don't say a number - haven't played with this enough to
*// know exactly what happens
   (5:314) set variable %PlayerReply to the number the triggering furre just said.

(0:32) When a furre says something with {=reply} in it,
 (1:200) and variable %PlayerReply is equal to %MainMenu.
   (5:300) set variable %MainMenu to the value 0.
   (5:300) set variable %PlayerReply to the value 0.
   [later, dude]

(0:32) When a furre says something with {=reply} in it,
 (1:202) and variable %PlayerReply is less than %MainMenu.
   (5:50) set countdown timer 1 to go off in 1 seconds.
   (5:50) set countdown timer 2 to go off in 3 seconds.


(0:50) When countdown timer 1 goes off,
 (1:201) and variable &MainMenu is greater than 0.
*// Set values for current emits to be displayed
   (5:301) copy the value of variable %PlayerReply into variable %NPCReply.
   (5:303) take variable %NPCReply and add variable %ConvGroup to it.
   (5:301) copy the value of variable %ConvGroup into variable %MenuText_1.
   (5:301) copy the value of variable %ConvGroup into variable %MenuText_2.
   (5:301) copy the value of variable %ConvGroup into variable %MenuText_3.
   (5:301) copy the value of variable %ConvGroup into variable %MenuText_4.
   (5:302) take variable %MenuText_1 and add 1 to it.
   (5:302) take variable %MenuText_2 and add 2 to it.
   (5:302) take variable %MenuText_3 and add 3 to it.
   (5:302) take variable %MenuText_4 and add 4 to it.
*// Set value for next conversation branch based on current user choice
*// Again, you'd have to arrange mydream.txt carefully such that the conversation
*// branching is ordered in line with replies
   (5:306) multiply variable %PlayerReply by 5.    *// Step value of groups
   (5:303) take variable %ConvGroup and add variable %PlayerReply to it.

*// Emits for Main Menu
(0:50) When countdown timer 1 goes off,
 (1:201) and variable &MainMenu is greater than 0.
   (5:200) emit message {%NPCReply} to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 1.
   (5:200) emit message {%MenuOpt_1 %MenuText_1} to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 2.
   (5:200) emit message {%MenuOpt_2 %MenuText_2} to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 3.
   (5:200) emit message {%MenuOpt_3 %MenuText_3} to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 4.
   (5:200) emit message {%MenuOpt_4 %MenuText_4} to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
   (5:200) emit message {%MainMenu %ByeText} to whoever set off the trigger.
   (5:50) set countdown timer %NPCReply to go off in 1 seconds.


*// Unique timers for setting vars and doing special case script (like handing out keys, etc.)
*// # of timer is a constant corresponding to value set with %NPCReply above
(0:50) When countdown timer # goes off,
   (5:300) set variable %MainMenu to the value #.  *// number of menu options player will have for next branch
   [other stuff]

*// Catchall timers for generic and common routines funnelled to from the unique timers
*// above if it would save space or for whatever other reasons. For example:
(0:50) When countdown timer %NPCReply goes off,
 (1:206) and variable %CloneObj is not equal to 0.
   (5:41) place object type %CloneObj at (%PlayerPos).
*// Or:
(0:50) When countdown timer %NPCReply goes off,
 [clean up the mess]


Anyhow, that's obviously not entirely complete; but that or something like could serve as the core of it. I'm not sure how much code it actually saves, but it does make some of the var handling automatic (eliminating the need for at least some of that floor/obj business). I think the big bonus, though, with doing the conversations in a manner like the above is that all the unique script and branch controlling is isolated in the unique timers where it's easilly identified and edited - rather than having it all embedded in the trees themselves where you'd have a nightmare of conditions you need to check and whatnot that would easilly fall prey to typos, etc., and be a real debugging hell.
Go to the top of the page
 
+Quote Post
Lygeia
post Jan 29 2003, 04:10 PM
Post #15
Group: Furres

Lygeia

Ack! I walked away and then realized that I'd totally flubbed those emits... toss all the %MenuOpt_n stuff (include the "[option no.]" in the string for that menu text, and say the bye message is something like [99]) so you have:

CODE

*// Emits for Main Menu
(0:50) When countdown timer 1 goes off,
 (1:201) and variable &MainMenu is greater than 0.
   (5:200) emit message %NPCReply to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 1.
   (5:200) emit message %MenuText_1 to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 2.
   (5:200) emit message %MenuText_2 to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 3.
   (5:200) emit message %MenuText_3 to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
 (1:201) and variable &MainMenu is greater than 4.
   (5:200) emit message %MenuText_4 to whoever set off the trigger.
(0:50) When countdown timer 2 goes off,
   (5:200) emit message %ByeText to whoever set off the trigger.
   (5:50) set countdown timer %NPCReply to go off in 1 seconds.


The only thing you really lose is the dynamic numbering of the bye option (and gain a little bit larger filesize for mydream.txt)
Go to the top of the page
 
+Quote Post
Resputan
post Jan 29 2003, 10:01 PM
Post #16
Group: Furres

Resputan

Ok, I didnt have enough time to read through everything or even part of what was said in all the posts in this thread :p hopefully I will tomorrow.

Anyhow, I dunno if this was said, implemented, suggested whatever, but I have a dream where there is one monster and instead of expiramenting with one furre I use three.

The only problem with this is every time a new adventure starts the dream owner would need to go through the ds and add in the furres names... (I think ill cry of joy when phoenixspeak is here....) This can be time consuming and it even for just one battle.

This also complicates inventory, so now I had to give each character a variable for items that they have a p***bility of getting.

Each furre has an array and each one of those variables from the array are set to zero automatically and if they acquire the item the item will have a set number of one through eight and it will increase that number of the array by one and then the furre will be able to recognize himself as having that item when he types inventory.

I know im not explaining this very well at the moment lol I havent messed with my ds in awhile but hey im trying to explain.

Anyhow moving along, each furre has their own hp variable as well and anytime a furre says attack the monster automatically attacks them back (if he penetrates their armor(I have implemented t hat in yet...*sigh*)) and it will take hp out of that certain furres variable.

From there its pretty basic, after the monster dies he disappears, an item appears in its place, the one that pics it up gets the item added to their iventory and can then take it back to town and get a reward.

I started added levels and im almost done with that (deffinately not perfect, after a succesful first battle you gain a level, then after two more battle gain a level then three so on and that can differ depending on monster I guess) basically what happens at level up is their hp goes up by 1d8 and their attack goes up from 1d6 to 1d8.

I really wanted to try added two differant classes but that would be too insanely long to do without a database available to me (I also chose not to use bots even though it would make it sooo much easier).


I think what im going to do is split my current progress with this dream in two, one preparing it as best I can for when phoenixspeak gets here so I only need to implement the database however it will be implemented and one so that it will work with only the current ds.

Right now the estimated time to prepare for an adventure (copy pasting names through the ds...) is about five minutes. Not really too long for a different expierience in furc.

Farrier, lol you probably want to smack me for not readinge verything before I posted, I just skimmed it, but like I said I will read it through tomorrow and edit my post accordingly.

I cant wait to see your finished product either, next time im on furc find me and ill show you mine if im not in the middle of working on it :)
Go to the top of the page
 
+Quote Post
Farrier
post Jan 30 2003, 10:27 AM
Post #17
Group: DEP Admins

Farrier

Your project sounds great, Resputan - I'd love to see it!

I've wanted to steer clear of your system of hardcoding in names, though (what Lygeia calls "invitation-only" code).

Ehvo suggested a nice alternative - allow only one of each species into the dream. Of course silver sponsors could screw that up royally, by changing species in mid-fight or something. And people with dragons/gryffes/phoes could break it, too, though you could code it to eject them if they used them :). Then there's the bug with people with triwings/butterflys detecting as the wrong thing...

But at least it doesn't mean hardcoding in the names.

=====

Lygeia:

I've designed the convo code on paper now, but not written it in the DS editor, so it can still change.

I am having them say numbers: basically, something like "=say 3" will say the third option they are given.

On the train home yesterday, I decided that what I was doing, for these conversation trees, was writing a limited programming language. Or state machine. Or something.

So I decided to do it properly.

Each possible line that the NPC says, and each option that the PC gets to say, is only met if a set of conditions is true. If either the PC or NPC says a line, then that line should be able to set flags, and/or cause arbitrary DS code to be run.

So I basically want to make a way to encode a command like:

CODE
If the PC is in a conversation, they says the second option from the last list of options they were in, and their conversation has reached point X in the conversation tree,

then if ((A>5) AND (B>4) AND (C=0)) OR ((B=3) AND (C=1)))
Then have the NPC emit {line1},
set B=4,
set C=1,
call DS function D with parameter 45.
give the PC a list of options to say, each of which will depend on its own set of conditions.

Otherwise,
set A=14,
set B=3,
call DS function E with parameter 0.
give the PC a different list of options to say, each of which will also depend on its own set of conditions.


And I want a way to fit all that into a few floorsquares of information.

My current system can fit that into two lines of 10 floorspaces! Well, actually three rows, because of that OR clause (Like DS, I only implemented AND conditions). Plus one line for each of the PC's options and all the conditions and flags that it sets, so up to 11 lines, really.

I like your idea of using the strings to determine the conversation tree, but I get the feeling that in my project, the number of duplicate strings would be prohibitive, and maybe take me over the stringtable-size limit of 128k (yes, I know :)

But it's a good idea, and I think I prefer it to my own, so if I *do* have the stringtable space, then I'll do it. That will save me 4 floorsquares per line, meaning I could get the above code into just 3 lines of 6 squares. Plus one line for each of the PC's options, so 15 lines, really, since each NPC line would need to be followed by the max number lines the PC could say. And no NPC line could share another's PC-lines.

Hmm, if I used another square per line to specify how many options followed, that would make it smaller, though. 7 squares per line, and more flexible than my own system.

Might do that, then.

I *think* you're wrong, by the way - if you manually edit the text file, you should be able to have as many duplicate strings at different string indexes as you want.
Go to the top of the page
 
+Quote Post
Farrier
post Jan 30 2003, 11:04 AM
Post #18
Group: DEP Admins

Farrier

Conversation code is almost done, and I'm thinking about item interaction.

I'm having a huge number of them, and each item can be used in various combinations.

Felorin's
[url=http://www.meovanni.com/cgi-bin/forums/ikonboard.cgi?act=ST;f=3;t=7413;st=37]post to the arrays thread[/url about loops, combined with my "being able to get the x,y position in a selected area" made me think...

Three columns of items on a map (yes, I know - but I like map lookups, and it works particularly well for this idea).

First column represents "item the furre is holding".
Second column represents "item at the furre's feet".
(Either column can be 0, of course.)
Third column is the resulting item that you place at their feet, as a result of them using these two items together.

So, to represent the code "when they hit F3/Ctrl-U when a toolkit is in their hand, and a damaged sentry bot is at their feet, place a repaired sentry bot at their feet", you would have:

Hands: Hammer.
Feet: Damaged bot.
Result: Repaired bot.

This would allowe the dreamer to create a VAST number of object interactions:
Hands: Matches.
Feet: Unlit fire.
Result: Lit fire.

You could also have it copy/check the floor, if the floor wasn't type 0:

Hands: Pickaxe.
Feet: Rock floortype.
Result: Rubble item, Crater floortype.

Hands: Fishing rod object.
Feet: Water floortype.
Result: Fish object.

That would be an incredibly intuitive and powerful tool, that would allow people to visually design hundreds of object interactions, at the cost of very few lines of DS.

Except... we don't have any way of doing this lookup, at the moment. With Felorin's loops, and some way of getting coordinates of a selected area, we could.

But for the time being, it will have to be done in hundreds and hundreds of duplicate lines of DS.

Unless anyone can think of a way of doing that lookup? Without checking each individual line, that is, which would currently take more DS than to do each interaction separately.

Of course, sometimes you use things together and both the items you use are destroyed:

Hands: Replacement board
Feet: Broken computer
Result: Working computer

In that case, you could maybe use the "Hands" square's floortype, in order to determine whether it should be destroyed or not.

Though that would only work if you can change what people are holding!
Go to the top of the page
 
+Quote Post
Farrier
post Jan 30 2003, 12:05 PM
Post #19
Group: DEP Admins

Farrier

Actually, one way would be to have all usable item types be consecutively numbered (so you could look them up), then have a series of lines containing a list of item pairs:
item (and floor) you use it on, item (and floor) that results.

That way, if you can guarantee that no item will have more than, say, ten possible interactions, then you only have ten code duplicates (and of course, you don't need to duplicate ALL the code).

But that takes up a LOT of map space. If the largest number of interactions is ten, then you have to reserve a bunch of lines (the same number of lines as you have items), and it has to be 2 x 10 wide (20). Basically, a 20-wide strip out of your map.

You could improve on that a bit, by having a single additional square with the floor set to a value to indicate the number of possible interactions for an item. That way you could group those items which only have a single interaction so that part of the list would take up less...

HEY!

Better idea. Maybe.

Same as above, but two rows per item. The bottom row is the resulting items and floortypes, and the the top row is the items that the current item can be used with, each on a floor that indicates the offset of that item. Select that row, and then filter it by the item type at their feet, then copy the FLOOR to a known x,y position, that is known to have floortype 0.

Then, if that floor isn't 0 afterwards, you know you can use that item on that other item, and you know the offset to look up the result.

Downside is that you can't have it check the floortype :(

However, odds are that most objects can only ever be used on a single floortype (water, rock, grass...), so I guess the first square in the first row could be the floortype that it can be used with.

One floortype could be reserved for "interpret all the "results" for this item as DS function calls (by result item type), and parameters (floor type)". That way you can have scripted effects off using items, too.

Maybe have if if that floortype is used in the result, call the relevant DS function, without any arguments. That way, you can have only certain things you use something on be scripted.

By DS function here, I really mean fire off that numbered timer, or something.

Cool, that's my object interaction code designed, too.

What's left?


1) Fog of war,

This one's going to be either easy or nasty.
I don't think it's worth making a lookup table for, and it would be difficult to anyway.
So I plan to have just a whole bunch of DS lines like:
"when someone walks into square X, replace the fog-of-war item at X,Y with 0".

Then have maybe half a dozen or a dozen big black object types, each able to black out from one to several squares of an area.
Can have plenty of these: being flat monochrome things, they'll compress well in the FSH, so they're "cheap" in download size terms.


2) Hand to hand Combat,

Not worked out yet. Ideas?

Basically just thinking of "if you walk into a hostile creature, count that as an attack." But then, you could (because of lag) accidentally attack a monster 50 times by accidentally walking into him, and end up dead. Hrm.

I don't want the math for this to be too complex - just very simple, maybe slightly random attack stuff.


3) Missiles (including targeted magic/psionics effects),

Not worked out yet. Ideas?

Best I can think of is "move something in a direction until it hits something, or reaches N squares".
That restricts you to firing in one of the four ordinal directions, though. I don't think that's really a terrible limitation, and people can live with it if so. Most of the corridors are going to be vertical or horizontal anyway - very few combats will take place in diagonal corridors.


4) Area effect weapons/spells,

Not worked out yet. Ideas?

I'm guessing some kindof diamond/rectangle effect, with filters and stuff. We have the DS, so we can do it :)


5) Special/Magic items,

Not worked out yet. Ideas?

Some of them can use the above item interaction stuff, to call a DS effect with an argument, which in turn would make a spell effect happen..


6) Looking at stuff

Not worked out yet. Ideas?

I'm thinking a floor-array (yes, another one!) of item type against string number.


7) Miscellaneous Magic/psionics effects.

I'm going to have these speechbased, off a "magic word" (or phrase). So if someone says "mindblast", then you get a mindblast effect.

To begin with at least, I intend to have it so that you can say every single effect already. Later, I might work in skill levels, and a power reservoir, but for the moment I want people to be able to play with it and see all the cool effects straight away! :)

Item summonning:
 Tf they say the spell, and there is nothing at their feet, place the item there.

Creature summonning:
 If they say the spell, and there is nothing in front of them, place the creature there.

Healing, stat recovery:
 Increase the current value of the relevant stat by the relevant amount.

Permanent powerup:
 Increase the max and current values of the relevant stat by the relevant amount.

Temporary stat boost:
 Increase the "temp bonus" value for that stat, which will be added to the stat when using it.
 Set the timer for that skill, to zero the temp bonus.
 Yes, I know that resets the timer on any previous castings: I don't mind.

Flying/levitation/jumping:
 Not possible, that I can see.

Targeted effects:
 See above.

Area effects:
 See above.

Teleporting:
 I *would* have this as a targeted effect, except that would be pointless.
 I guess a random teleport could work (place an unwalkable item where they are, then move them to that position "or somewhere nearby"? :)
 That'll cause ghosting problems, though.
 Or else a "teleport them forward N spaces" would work.
 Or else a "teleport them to a specific location".
 I can't do "teleport them to a specific item", unless I track items.

Mirror self:
 This is actually possible, though only by using a bug which they might fix. Place an unwalkable object where you want the mirror image of themselves, then move them onto it, then remove the unwalkable object.
 This will disappear if they walk off the screen and come back, though.
 Failing that, just place a greyscale "statue" of their species, adn pretend.

Can anyone think of any other cool spell effects?
Go to the top of the page
 
+Quote Post
Farrier
post Jan 30 2003, 12:17 PM
Post #20
Group: DEP Admins

Farrier

Resputan:

You might be able to cut down the time you spend editing the names, if you have a bunch of lines at the top like:

CODE

When someone walks,
and their name is {farrier}
set the variable %triggering_user to 1

When someone says something,
and their name is {farrier}
set the variable %triggering_user to 1

... (and so on for all the other triggers that your dream uses)

When someone walks,
and their name is {Jimbo}
set the variable %triggering_user to 2

When someone says something,
and their name is {Jimbo}
set the variable %triggering_user to 2

... (and so on for all the other triggers that your dream uses)


Then everywhere in your code, just check against %triggering_user instead. That assumes, of course, that you only use a few trigger types. If you use a lot (there ARE 45 possible triggers, after all! And many of them need to be set for each possible value, too), then this will not be efficient.
Go to the top of the page
 
+Quote Post

2 Pages V   1 2 >
Reply to this topicStart new topic

 



Lo-Fi Version Time is now: 13th June 2026 - 05:21 AM