Text RPG Design Thread [1 new, on: Screenshot, working cmd]

Advanced game related topics
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Text RPG Design Thread [1 new, on: Screenshot, working cmd]

Post by Zach »


Newest Posts by me on:
3/29/2014
http://www.purebasic.fr/english/viewtop ... 60#p441540

-------------------------------

Small Intro:
As some of you may know by now I'm slowly in the process of building a Single Player Text RPG.
I intend for this threads to be a general repository for discussions relating to my development process and my progresss itself. I would like to ask a lot of questions, many of them probably n00bish or just me needing reassurance, but also may start some general discussions as well..

Instead of littering the forum with multiple posts, I want to try and keep it all in one thread.. Hopefully people won't forget its multiple topics inside when they see new posts :mrgreen:

The two primary goals I have are:
A)Deep, Rich Story Telling (As a proficient writer I have this more than covered. I have previous years worth of source material already written)
B)Creating a very unique, immersive atmosphere with lots of interaction. I want to try and obtain the level of interaction you would typically find in most MUDs (Multi User Dungeon). Those who have played MUDs before know that they can be extremely addictive and interactive with the right combination of staff and a good player base.

However, I have never worked on a MUD before, let alone a Text Game (or any game).. So I have to approach everything from scratch.
My Text Coloring & Font parsing code is almost done, which means soon I will be able to start developing other systems. While one of my goals as a developer is to obtain speed and efficiency (Text worlds like this can take large amounts of CPU and RAM), I am also willing to sacrifice a little, to allow for an easier time coding, and producing more easily maintained code that I can actually read (although I do comment heavily).

So here are some of my thoughts on how I'd like to approach some of the stuff I'll have to do. I'm interested in feedback mostly on what is/isn't a good idea.. Optimized code examples are welcome if you have an alternate idea for one of mine, but keep in mind I may not use it if I deem it too tough to read/remember how it works. It's not unappreciated, just might not be for me.. If you want to say "Well this is a better way to do it", that is your right.. but unless it is orders of magnitude faster than my version, I may be hard to convince.. A lot of my ideas are firmly committed to my mind, but I am always willing to listen to others, and perhaps incorporate some changes where it makes sense for me.
-----------------------------

Asset Management:
In this case I decided a long time ago that I will be using a database to store a lot of my stuff. This covers a lot of things from basic Rooms in the game, to items, monsters, quests & all the associated properties that might go with them. I will most likely use SQLite as I have experience with using it from when I prototyped this idea in Python.. I'm sure Purebasic usage will present some differences but I'm firmly committed to SQLite at this point. It's small, portable (embedded in App) and fast. Perfect for what I need to use it for.

In-Memory management of stuff on the other hand (it has to go somewhere after you load it!).. I am considering using a combination of Maps and Linked Lists where appropriate in each individual case. I have my own addressing system that I want to use for my rooms.. It looks like a Hex number, but it really isn't used "as Hex". I also intend to use Structures, to manage different pieces of data for individual elements..

My only concern is that in all the examples of Lists/Map I've seen in help.. Either I don't understand them completely, or they possibly can't be used in the way I want? I want to make sure...
For Rooms in particular, I need to access any given room by its element name (instead of iterating the entire Map looking for a property matching a search term)..

Code: Select all

Structure Room_Struct
  ID.s  ("1x1A" allowed as an ID under this type?)
  Title.s
  Description.s
  Contents.s  (what's in the room?  Static objects that can be interacted with)
  Contents2.s  (dynamic stuff,  dropped treasure or other items, monsters, NPC's etc)
  Exits.s
EndStructure

NewMap  WorldMap.Room_Struct()

; So lets populate the map
; Do I absolutely NEED to do it like the example?  
WorldMap("1x1A")\ID = "1x1A"     <--- (I want this to be two separate lines/commands)
WorldMap()\Title = "Some Title"
WorldMap()\Description = "A long boring Room Description"
WorldMap()\Contents = "If anything, populate this"
WorldMap()\Contents2 = "Same as Contents"
WorldMap()\Exits =  "Insert concatenated string variable listing all Exits in a nice format"
 
(Please keep in mind this is an example, my actual Structure for instance, has MANY more attribute variables, such as a variable to indicate which room is linked to the current room, if you were to walk East, or go Up / Down, etc (if available as a valid Exit) )
Do I need to implicitly use the AddMapElement keyword when populating a map? Or can I just set it up to build on the fly like above, changing the relevent Key name as it populates? This is the impression I have, so I just wanted to be sure.. Although I don't like having to append the assigning of the first structure variable onto the creation of the map Key..

Idea! :I don't mind building a function that first creates empty elements for all rooms in the game, and then goes back and populates them, however.. Actually it might be a good idea and would save memory because I could institute a "Bubble Loader" around the Player and only load Rooms / generate dynamic content within a certain radius of say... 50, 75, 100 rooms or so ? I think this will ultimately depend on resource testing I do when I get the engines skeleton (room navigation and basic command parsing) up and running. I could do something insane like generate 10,000 rooms of gibberish just to look at the memory footprint.. Although I am sure someone here might have a formula or something for multiplying average room size [bytes] by number of rooms, as well..

-----------------

Command Parser
This one... really troubles me to no end. I do not understand parsers, despite hours of research and reading. I honestly don't. I have read about topics such as BNF, heard about terms like top-down, bottom-up, recursive descent parsers, etc... Programs like "Lex" scare me.. I honestly just don't have the skillset or capacity to learn about proper parsers and how to build one.

In Python, I used an IF / ENDIF tree and Regular Expression matching.. To some marginal success (I have issues with the order words appeared in the match-list, etc).. For a handful of commands I think IF/ENDIF works fine and such.. But I don't know what the long-term complication woulds be if I my command set grew to something large, like 100+ commands??

I would like to be able to tokenize and parse complex phrases such as "put my sword in my green pack", or "polish the mirror with the rag".. especially in combat, stuff like "attack third orc" (out of a group of orcs).. I know a lot of it is about tokenizing and then tossing irrelevant words out.. ([put] my [sword] (in) my [green pack], etc).. But the whole concept of implementing a parser, a REAL parser that is good, is lightyears beyond me... A really complex phrase example which would be neat to handle, might be something like this... "put my sword in the green sheath that is on the stool, on the red table"... lol? (probably two or three ways to interpret that)

I know parsers have gone through a lot of evolution, especially among the big name Interactive Fiction companies of the past (Infocom, etc).. I think I read somewhere one idea for a parser was to assign keywords numerical values and somehow when tokenized and parsed out they would add up to the proper value to trigger the correct command.. That idea intrigues me, but I wouldn't know where to start with THAT, either...

I was wondering about using a LinkedList in the process somehow...or should I just stick with an IF / ENDIF or perhaps CASE / SELECT ??


Well those are my main thoughts / questions for now.. Hope it wasn't too boring.
Last edited by Zach on Sat Mar 29, 2014 8:28 am, edited 12 times in total.
Image
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4326
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Rook Zimbabwe »

I wrote a text RPG in college back in the 80's. Sounds like a fun task. I hope you enjoy it!
[DATE: 17 MARCH 2011]
My comment is multiple:

The forum only allows a maximum of 60,000 characters a post so you might need to DATECODE you posts if you keep posting same thread but updated

You intend to load the ENTIRE LEVEL on program startup? Of course it is text and ASCII isn't that stressful in terms of modern memory but...

The first thing you need to do is develop the engine that will power your game. I can see you are well into that idea by your first post! Buy a lot of POST-IT notes and a notebook to assist with the organization.

Have you settled asset / area management in a concrete form yet? What about random treasures / encounters? How will you pull that data out of your database?

:D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Text RPG Design.. (General thread for various questions)

Post by Demivec »

Do I need to implicitly use the AddMapElement keyword when populating a map? Or can I just set it up to build on the fly like above, changing the relevent Key name as it populates? This is the impression I have, so I just wanted to be sure.. Although I don't like having to append the assigning of the first structure variable onto the creation of the map Key..
You do not need to use AddMapElement() and you can add map elements as you have done in your example. You may find using AddMapElement() might be helpful in understanding the code later. It think you could get away with loading room data from a database on demand without any noticeable delays, so a Bubble-Loader should be fine.

You can use maps for parsing as well. An example of this can be found in the PureBasic code example of RCRPG on Rosetta Stone. Neither text parsing nor the loading of room data should be much of a burden from a speed standpoint. It shouldn't make a difference which method you used, If/ENDIF, SELECT/CASE/ENDIF or anything else, as long as it works correctly.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

Thanks for your feedback Demivec. I agree loading from disk on the fly does not seem very burdensome, as this is what I did with Python and SQLite, querying the database for each room description as the player moved. So a bubble loader, if I decided to use it would probably be even less of a burden.


Rook, some of your questions are answered by the ongoing discussion..

However this is always what I have envisioned.

Point 1 There will not be "levels" to load, like I think you are referring to. If the engine pans out, the World will be one continuous stream of data. At run-time a map will be created and at a bare minimum, an Element Key will be created for every single room in the game. Whether or not I decide to use a bubble loader, depends on how well test systems are able to cope with the loading. If using a bubble loader, than detailed room data will only be fetched for a small number of rooms, covering a radius from the players position. So if the player is standing in the center of a town for instance, then all rooms within a radius of 1 or 2 miles, up to N number of Rooms will be loaded. Something like that probably.. I haven't really fleshed out any ideas on how I would implement a bubble loader as I don't see that I need one yet.

As for the rest of the data, most of it will be dynamically generated at run-time.. I will have database entries that contain "Base class" definitions that will be used to generate unique Items, etc.. I'll likely hard code special ultra rare unique stuff as well.

For monsters it will be the same principle. I will define Monster "classes" that setup the basis for different types of mobs, and from there I will derive monsters of various strengths and difficulty. I am planning to use a Linked List for this, with element variables to help the mob do various actions.. So if a monster moves from one room to another, it will change the variable that holds its current location, and also update the list for that room to show it is in the room. So only if a Player is in ROOM A, and the monster is in ROOM A, and it is listed in the ROOM A description text, will the player be allowed to engage the mob in combat. But that is just a rough idea, subject to change.

NPCs and Mobs will have AI capabilities (I hope) that allow them to roam between rooms within the game, as well as interact with the player to some basic scripted degree.. There will also be checks running so that an NPC doesn't leave town unless its supposed to, a Monster can't enter town unless it is supposed to, checks to control Monster spawn rates based on the players position (why spawn monsters on the other side of the world if the player isn't there?) and to control the Monster population over all..

Item inventory for Shops and the Player themself should be pretty easy to manage with Linked Lists or Maps as well.

It does all sound like fun, but I am prepared for some real serious work ahead of me, and a lot of headaches I am sure I won't expect.. From my understanding, most novices are cautioned away from Text Games like this, because of the sheer complexity involved in properly executing the idea.. But I just didn't want to waste my time making yet another Pac-Man/Space Invaders/Asteroids etc clone like most people start out with... :twisted:

I will post the design of my Rooms based Game Map later on. It's actually pretty simple.
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

Design of The Game Map
This posts outlines the basic idea and theories of implementation for my Game Map. The underlying structure is Room based, with the game world consisting not of Levels, but Rooms instead. This is how all modern MUDs work also, to the best of my knowledge. Game-play is centered around interactions based upon which Room the Player currently occupies. Only one Room at a time will be shown to the Player, as with most Text games. However, unlike most Text games and more similar to MUDs, the game data is not restricted to one screen at a time only. The text area of the GUI will consist of a word-wrapped vertically scrolling text box. This will allow the player the see the most current updates while offering a chance to scroll back up and read something they may have missed, if they wish to do so.
-------------------

Basic Room Structure
All data for Rooms is stored on-disk in a database, which is used to populate a Structured Map() object in memory during run-time. Rooms can have various properties associated with them in addition to some of the most basic required data. Rooms are laid out in a grid structure, and referenced by an ID generated from their position on the grid/map. In past implementations I was planning on using an 2D or 3D Array however this is inherently flawed because with such a grid layout you don't necessarily occupy every element of the array (wasted space). I did at one point plan on using a 1D Array with Darkbasic in conjunction with a user created Key/Value "Map" that allowed for string-based element names. Since moving to PureBasic I have found that the Structured Map suits my needs perfectly as it doesn't matter what order elements are added, you can use Strings for the Map Keys, and they can also be Structured.

The Room ID's are formatted as follows: "1x1a". For a standard room in the 2D grid the first digit denotes the Area number (each region of the game will have a unique ID), the "x" is a simple delimeter, and "1a" signifies the (2-Dimensional) Room location within the Map grid. I am also considering using a 3D system to make references to Rooms below ground or above ground-level, easier to manage. That might look something like this: "1x1b" (or c, d, e, f with different letters representing different Z-depths). Of course I may change the addressing system at any time if I come up with something I like better.

Room Structure:
The structure of the game Rooms actually involves several different structures, in order to try and keep things a little more tidy. It is broken down in this way to keep from having a single Room structure in one long list, and minimize "hunting" over such a huge list for the correct variable if something ever needs to be changed. I often have problems with overlooking/missing things I am looking for in extremely long lists, so I think this way makes a lot of sense for me personally and I can't see it having much, if any, effect on performance.

Code: Select all

Structure Effects_Structure
 ;reserved to hold values which have special impacts on the player by simulating environmental conditions.
 ;This may be things such as a dark room which requires a torch, or simulating difficult terrain navigation,
 ;like adding round time for moving through a muddy swamp,  or declaring the room as  non-combat completely
 ;(no combat commands can be executed no matter what).  I will flesh it out later, but I will probably use some
 ;sort of  flag/bit-field checking system to indicate an ON/OFF state.
EndStructure

Structure Special_Exits_Structure
 1_exit.s    ;Special or Auxiliary Room Exits that cannot be handled by the main Exit List parsing Procedure.
 1_title.s    ;For instance,  several doors accessible from the same room (like in a Hallway) or several
 2_exit.s    ;buildings accessible from an outside street.   Staircases, Ladders/Ropes, Climbing will all
 2_title.s    ;likely fall under the jurisdiction of this structure.   There are 5 Aux elements, comprised of
 3_exit.s    ;two values each.  xx_exit  holds the RoomID of the destination if you were to use such an 
 3_title.s    ;Exit, while xx_title holds the actual Exit Direction to display in the "Obvious Exits:" list.  This
 4_exit.s    ;special case is needed because unlike checking for  general directions, and adding them to
 4_title.s    ;the Exits list  (If North then Exits + "North" ) special Exits could be associated with any number
 5_exit.s    ;of items: A Door of any given color, A Wagon, A Tent Flap, An embankment that needs climbing, etc.
 6_title.s
EndStructure

Structure Exits_Structure
 northwest.s      ;These
 north.s            ;Are
 northeast.s      ;Pretty
 east.s             ;Self
 southeast.s      ;Explanatory
 south.s            ;I
 southwest.s      ;Would
 west.s             ;Think
 up.s                ;So
 down.s            ;Yeah?
 out.s              ;Generic  "out" Exit that can be used almost anywhere.  Inside buildings, Caves, special places, etc.
 special.Special_Exits_Structure    ;Special Exits topic covered in Structure definition above.
EndStructure


Structure Room_Structure
 title
 description
 contents  (interactive items)
 mobs   (NPC's or monsters)
 exits.Exit_Structure
 effects.Effects_Structure
EndStructure

I kept dozing off while typing this, so my apologies if it looks like I left anything out, or haven't thought of something. It's kind of a rough idea all around but in general it is what I plan to do.. A lot of this will also be made easier by virtue of two things.

1) When I am far enough in progress to start building Rooms and other Items I will program some "Asset Creation Tools" which will help simplify things on the back end with code. For the most part it will be a simple Forms based GUI with string gadgets to allow for input of specific structure fields. I am thinking that instead of coding tags by hand I might also implement functionality to define formating choices as I go along... Maybe even with real-time preview (copying the parser code should be trivial ). It will speed things up tremendously either way no matter how sparse the Creation Tools are, though.

2): One thing I have always done since my prototyping days in Python, was use MS Office Visio to draw my game maps, laid out in the grid addressing format. This actually helps a lot as even the Map()'s remove the burden of needing a strictly ordered list, it still helps to have a visual reference as to the size of the area you are building, and how all the rooms fit together within the grid. You know exactly where every room goes and what is connected to it, so all you have to do is worry about coming up with creative text in your room descriptions :)
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

What are peoples thoughts on Sound Effects and Music?


Personally, I have always felt sound effects feel slightly out of place within a text game.. They just seem unnatural to me, however many MUD clients (even official ones for specific games) have supported sound effects in the past.. Usually they work like a text highlight system, so that certain text triggers the sound effect. I had a friend who played the same MUD as I did (he introduced me to it) and he had all kinds of sounds set up, like battle sounds for combat, being wounded, stuff like that. The game also supported music (and even had some graphic artwork that would display in a pictures window at certain locations), not a lot but a few different songs. One that always played on login, and a few location based songs like for a specific town, a chapel, etc.


But again I feel that is out of place for a Text game... What do you guys think? I was thinking that having minimal environmental sound effects might potentially work out, but I won't really know until I try.. I'd like to experiment with it. For instance let's say you pull a lever in some cave, and the game updates you that "you hear the faint sound of gears turning in the distance". Well, would it be neat to also experience a (low-volume) sound that sounds like gears turning / a large stone door or something opening? Maybe some very basic sounds that are triggered by specific events.. I think it might be neat to have a soft recording of rain and thunder, during an in-game thunderstorm ?

It could get old after a while though.. Something I really would like to do is include music in the game, however I am at a loss as to what level of quality I want to use.. I own Orion 7.6 (http://www.synapse-audio.com/) which gives me great access to a lot of high quality sounding stuff.. However I can also hunt around for low-fi type generators or Soundfonts / Samples.. I would like the music to sound like something on par with General MIDI however it presents a problem because not everyone uses the same MIDI chip in their soundcards and the banks all sound a little different.

My absolute favorite is MPU-401 from back in the day. My first sound card (Sound Blaster clone) used this and it had a lot of unique sounding stuff, although it could also function in other modes such as Adlib, SB, SB Pro, etc.. Using MP3 or even AAC would still mean having a bloated game download, although I would feel it to be worth it if the music really went well with the game.. The other choice would be to use Modules for music (.Mod, S3M, XM, etc) however I know very little about them and have no experience with Tracker software, much less any good free ones.. Plus I'm sure I'd have a hell of a time finding samples that I could reduce the quality on and minimize filesize..

Kind of puts me between a rock and a hard place???

Modules are extremely efficient but can also become just as bloated depending on how many samples you use, and what quality you require.
MP3/AAC Suffers from the same bloat problem (although I'm sure I could find ways to shrink the size and keep the music decent)
MIDI has guaranteed small size, but you can't guarantee it will sound like intended on every users computer...
Image
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Re: Text RPG Design.. (General thread for various questions)

Post by utopiomania »

One of the best computer games I have ever played was a Text adventure game on a home-computer with a black screen and green text.

No sound effects, nothing, it was like an interactive book, and the descriptions on the screen
was enough to imagine a different world in another age.

The text said i was standing in a vast field with small pine trees, it was cold and nearly dark, and
snowflakes was silently falling to the ground..

To the far north, there was an old house with a lantern flickering in the wind..

Then I typed in 'GO N', and the adventure began. Pure Magic. :)
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

Going back to the subject of parsers.. I'm just really wracking my brain and can't seem to understand the subject..

Idle has been trying to teach me with relatively simple examples, but even those I can't seem to grasp and, even Google is not much help. In the past two days I have looked through search results that are either:

A) discussions about parsers in general
B) articles on parsing and parsing concepts that at some point I get lost in
C) code samples that I just don't understand, which sometimes refer to Lex /yacc which are also way beyond me...

The only idea I have had, that I have a 90% chance of developing and understanding (but is probably very inefficient) is a really simple parser that works in steps..
I don't think I'm going to get anywhere until I try to implement it, despite all my efforts.

The way I am thinking of doing it is like this...

Keep a master list of commands, and when a command is found at the start of the string, move on to some kind of secondary parser, probably with rules written on a per-command basis. This more than likely rules out complex string containing several commands, but that kind of handling was never my goal in the first place..

So let's say "take the ball". The input is passed to the parser which initially tests the first word of the string against the command list, and it matches "take", strips out "the" and then moves on to running the "take" command, which is a procedure that does some further parsing and condition testing before modifying the game state (if necesarry).

The "Take" command would be passed the "Ball" token, and then it would do a test to see if there is a ball in the room, or in an open (but not closed) container in the room, or on something in the room, etc..

A slight sidetrack for a moment: I am concerned with stripping certain words from strings. Stuff like "the" and other words which link to a noun.. But also what if there are two balls, red and blue? I don't really have any ideas on how to parse with such distinction.. Although I am hoping the way in which I implement the parser would help with it somewhat (grammar rules defined per command) but I'm not sure how to decide what words are relevant and what words should be kept, in which situation.. You can't just reduce the string to "take ball" because then which ball did the player want?

I was reading the TADS (The Adventure Development System, pay-ware for creating Text Adventures) documentation and saw some neat ideas there, that might help solve the problem somewhat..
Naturally any object in the game which can be interacted with, or functions as an Item in some form, you have to create/define. So why not have some data fields attached to these objects?

i.e (very basic example)

Code: Select all

Structure  Item()

 short.s     ;short description  (description as it appears in a room's item list)
 long.s      ;long description  (looking at the item, etc)
 noun.s     ;noun which refers to the item
 adj.s       ;adjective which describes the item  ("big", or "red" etc)
EndStructure

NewList SomeItems.Item()

AddElement(SomeItems())
with SomeItems()
\short = "a red ball"
\long = "You see a worn out red ball.  The surface is covered with pot marks but it is otherwise in good shape"
\noun = "ball"
\adj = "red"
EndWith

So the "take" command would be built in such a manner as that it matches tokens to predefined types. Perhaps it searches the contents of the room, looking for any tokens that match any items in the room as well.. So, with "take red ball" the steps might be..

Parser tokenizes each word
Parser recognizes TAKE as a command, calls a Procedure() that executes the TAKE command, passing it the remaining tokens as arguments (how do you pass "optional" arguments anyway?)
The Procedure sees it has at least two tokens, so it attempts to match both tokens to any NOUNS from *accessible* objects in the room, getting a hit for ball.
Still having one token left, the Procedure searches for the value in the ADJ property of ball, and decides it needs to operate on the "red ball" and not any other balls that may be in the room..

I still haven't worked out the actual code for those steps, but I have a rough idea, which I will probably attempt tomorrow. But the idea being, even if you were in a room with a single ball that happened to be red, whether or not you said "take ball" or "take red ball" it would take the ball appropriately.

Beyond that, one thing I am totally unclear as to how to accomplish, is to make sure update messages display the correct grammar..
Like if you picked up 1 coin on the ground versus picking up 5 coins..

"You pick up the coin" / "You pick up a coin" / "You pick up a single coin" etc.
vs
"You pick up 5 coins"
vs
"You drop a single coin"
.
.
"You pick up a red ball"
vs
"You drop the red ball"

etc... I don't remember what the name for that problem is called.. But hopefully you get the idea.

Do my ideas make any sense? This is all I could come up with for ideas in the 2 days I've been struggling to come up with how I want to write my parser..
I may be inefficient or overly complicated for what it does, but at this point its all I can remotely grasp as a concept.. Does it have merits?
:oops:
Image
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Text RPG Design.. (General thread for various questions)

Post by TomS »

I would use a fuzzy logic instead of a complicated parser.
I've seen some code that search strings out of many, even if they don't really match. Like you entered a word that isn't in the string, but the rest fits. Let me see, if I can find that for you (yes, it was PB code ;) )

EDIT: Ok. I was talking about this: http://purebasic.fr/german/viewtopic.php?f=16&t=14536
But it's not good with my example below and needs refining.
Maybe just a quick search if one of the words associated with an object are found in the command is a better approach.



"You see two balls in this room. One's directly on your feet the other one lays in a corner beneat the cupboard."

Objects:
1, Ball feet first
2, Ball cupboard corner second

Commands:
Take ball in corner! -> 2
Take ball nearby cupboard! -> 2
Take ball at my feet! -> 1
Take second ball! -> 2
Take ball near table -> "There's no ball near a table" (no need to tell the player that there isn't even a table^^ )

So you only need the command which is easy, because this is just Left(string, FindString(" "))

As for grammar. You have to store any derivations from the noun in a list.
I had this problem when I wrote a /give command in a chat.
Let me explain with german words, because we also have different articles (der, die, das instead of jsut "the") depending on the gender of the subject.
Note that a coin doesn't have a "gender" but's ist still "female" -> Die Muenze (you can see this phenomenon in french, italian etc, too).
So we have
coin - muenze (female); the coin -> die muenze; a coin -> eine muenze; coins -> muenzen;
ball - ball (male); the ball -> der ball; a ball -> ein ball; balls; baelle;

So my list looked like:

Code: Select all

Structure
    nouns.s
    article.s
    plural.s
EndStructure

list(1)\noun = "muenze"
list(1)\article= "die"
list(1)\plural= "muenzen"

list(2)\noun = "ball"
list(2)\article= "der"
list(2)\plural= "baelle"
I also had an array to replace "the" with "a"
der -> ein
die -> eine
das -> ein

Now you can say:
There's a coin -> There's replace("a", map( list(1)\article )) list(1)\noun
There are several coins -> There are several list(1)\plural
You take the coin -> You take list(1)\article list(1)\noun
You take 5 coins -> You take 5 list(1)\plural
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Re: Text RPG Design.. (General thread for various questions)

Post by utopiomania »

Going back to the subject of parsers..
Of course, the text adventure game I was referring to was 48k worth of Basic, written
by a guy that knew how to both keep it simple, and tell a fascinating story at the same time.

i have the source for that adventure game somewhere. No parser inside though, so I'm shure
you're project will be something different.
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Text RPG Design.. (General thread for various questions)

Post by TomS »

So I never really fully read your first post.
Here is my opinion:
I need to access any given room by its element name (instead of iterating the entire Map looking for a property matching a search term)..
You can do this with maps.
Iterating through a Linked List of 10.000 rooms will probably still be fast enough.
Also it can be done while still in the room. For example you have 3 exits then you search the roomlist for the three rooms behind each door upon entering the room.
If you use the mainloop for this instead of a dedicated ForEach-Loop you won't experience any lag. It's just background stuff.

I wouldn't store the objects in a room in a string but in a LinkedList.
You'd have to parse the string two times, if you want to add, delete or change an object.

Code: Select all

Structure room
    description.s
    List objects.objectProperty()
    List exits.exitProperty()
EndStructure

NewMap rooms.room()
With rooms("1x1")
    \description = "You're standing in a small room with no windows. "
    AddElement(\objects())
        \objects()\name = "candle"
    AddElement(\exits())
        exits()\direction = "south"
EndWith


Parser, again: All commands are imperative and follow the following structure:

VERB (((adjective) SUBJECT) (adjective) SUBJECT)

You have to know your verbs. You have to know what the player could possible type.
You need a list of those verbs. (I never played a game like this, but maybe you have list of commands in the manual. So someting like "polish the mirror" would never occur, but only "clean" for example...)
It can't work when you only have "walk" on the list and the player types "Go north!"

Then you have a list of everything in the inventory and everything in the room (that's why those objects need to be stored in a list rather than a string).

Now you create a command-chain for every command.

PUT What? Where?

You'll need to check the list for of objects for nouns.
Again: The player can't use "backpack" when you use "bag". Except if they have the same ID.

"put my sword in my green pack"

We get: "PUT SWORD PACK"

Now it could be that there are two swords. Either in the room. Or one is in the room and one is already in the inventory/pack or you're holding it.

If there are two swords in the room you'll move one of them to the pack -> "You took 1 sword (One remains on the wall over the fireplace)"


If there's one in the room and you are holding one we have to look for an adjective. In this case "My". It's not an adjective but a pronomen, but it has the same purpose. It further describes our object.

So my put the sword, we're holding in our hand into our pack.

If there's no adjective we do nothing and just say: "I'm confused..."
Same goes for "my sword" and we don't have a sword. Then the player is confused.

So we put a sword determined by the adjectives into our pack. "My" and "Green" are ignored unless there are more than one.

Polish:
POLISH What? Using_What?/How?

There are two possibilities.

Polish the mirror with the rag (obviuos command, if you have a rag. If not, simply: "I don't have a rag")
Polish the mirror thouroughly (may result in: "I don't have a cloth" or "You polished the mirror with a rag that lay on th floor/that you had in your inventory".)

As for the attack. Why would anyone write "attack the third monster" unless you imply it in the room description "A third monster appears".
The command-chain for attack would be:
ATTACK Who?/What?
In this case: Attack Monster. "third" is ignored.
Or you could add a list of cardinal numbers if it makes sense. In this case it doesn't, imho. But you're the one who played games like these, not me.

>>"put my sword in the green sheath that is on the stool, on the red table"... lol? (probably two or three ways to interpret that)

No only one way. PUT what? where?

Put my Sword in the sheath. Everything else is ignored.
You ignore everything but the basic command-chain (I'm sorry, I keep saying this word. It's not really a command-chain. I mean the very basics needed to form an understandable command. Verb + Object (+Object......))
Only if the basics are not enough (that's only the case if you have more than one object) you go looking for additional information.

>>I think I read somewhere one idea for a parser was to assign keywords numerical values

That's called bytecode.

>>and somehow when tokenized and parsed out they would add up to the proper value to trigger the correct command...

That's possible but if you have 20 commands like put, go, attack and 100 objects like sword, pack, that's commands * objects^2 = 200.000 unique command IDs.
Take 200 objects and 30 commands and you're facing 1.2 millions.
And now imagine you need to refer to the sword, by "sword", weapon", "double handed sword", "master sword"... Suddenly you're on the billions.

I don't think that's the way to go for your game.

>>I was wondering about using a LinkedList in the process somehow...or should I just stick with an IF / ENDIF or perhaps CASE / SELECT ??

You need to store the verbs, objects and descripting words like "my", "red", "on the floor" in a list or an array. You can't get those from the string everytime. It's too complicated and messy.
The comparison still needs to use If or Select.
Imho Select is cleaner in code, but it really makes no difference speed-wise.
Afaik it's the same in ASM.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

I think we're on the same page, Tom, for the most part..

I wasn't intending to store objects in the room "in a string" so to speak. I was thinking more of using a Linkedlist attached to that Rooms structure, or something like that. Any string containing the objects all together would just be for descriptive printing purposes as part of the room description, but any actions on those items would be referenced and checked against the list.

Agree on the needing some kind of list to hold command verbs, adjectives etc. I think our ideas are very similar in comparison, although I'm not sure I know any way to (in code) set up and parse command structures other than how I outlined above.

I don't know what (if anything) I'll come up with today, but hopefully something that works.. It may come out more "complex" than simple "fuzzy logic" (I've heard the term but don't really know what it means, other than "half-assed" :p ) but I think that is just baggage I may have to deal with because I am designing parser to work more like a MUD parser than a simple adventure game with a simple, terse, and restricted command set/syntax.

The one thing I don't want to have to deal with is workarounds for ambiguities as in my view the parser is the player's primary interface with the game almost more so than the GUI would be. I want to avoid "guess the verb" situations. Incidentally a situation where there are two swords in the room, I may leave for the player to figure out that they are supposed to use "my" when they intend to manipulate an items specifically attached to their character, although I would certainly outline such things in whatever short Manual I come up with (it's up to them to read it though).

I do want to solve the synonym problem (get = take = grab) but I'm not sure how to do it so that things are stored and matched efficiently.

I think the simplest solution would just be to have multiple entries in the main list, and then during my case/select would simply test for those multiple words (If verb = blah|bleh|meh Run this Proc())
Image
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Text RPG Design.. (General thread for various questions)

Post by TomS »

>> I wasn't intending to store objects in the room "in a string" so to speak.

Ok. I was put off by this code of yours:

Code: Select all

 Structure Room_Struct
  ID.s  ("1x1A" allowed as an ID under this type?)
  Title.s
  Description.s
  Contents.s  (what's in the room?  Static objects that can be interacted with)
  Contents2.s  (dynamic stuff,  dropped treasure or other items, monsters, NPC's etc)
  Exits.s
EndStructure
Fuzzy logic was an idea. but with the code I linked it doesn't work as a command parser.
"Put my sword in the pack" and put my long sword in the red pack lying on a stool near the table" is the same command but you'll get maybe 20% for the first line and less than 10 percent for the second line.
Fuzzy Logic doesn't mean "half-assed".
It considers a certain error-range. Like when talking to someone who doesn't speak the language perfectly, you'll still understand what he's saying although he might mix up positions of words in a sentence of use adverbs instead of adjectives...
Another use for it is face/image-recognition. If you compare pixel by pixel you'll certainly get "#false", but with a certain error margin the computer is able to return True just like you'd expect when you look at the pictures yourself.

So it may not be the best choice for a parser but it still can be useful, when dealing with typos.
You don't need to put the sword back when the player types "put swodr back". But you can reply google-like: Did you mean "sword"? etc.

>>I want to avoid "guess the verb" situations.

Then you have to create huge list of actions and their synonyms.
I like that idea.
I once played a clone of Zak McCracken and as a point and click game the command list was very limited (there were some buttons with "put" "look" "take" "talk" etc).
There was a scene where you had to shoot a monkey with a blowgun. "Use" didn't work. After some time I learned that I was supposed to use "talk".
Pretty stupid, if you ask me.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

Yeah, that code you quoted is just the display text that would be sent through a printing function, the Contents string would be compiled from a List which I'll probably attach to the Room structure as well. In fact I could probably forego the String and just convert the list to a formatted string during Print output (I'd do the same with the Exit list but that's just too many objects to cycle check and would make for one hell of a messy code section)
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Text RPG Design.. (General thread for various questions)

Post by Zach »

Hi guys,

Well... I don't have a working parser yet, in fact I haven't even started trying to code it because I got caught up in something else!
I have been very busy the past two days. I started out intending to write a test program to see if I could come up with some sort of working parser, but then I realized that I couldn't do this until I at least got some basic data structures built! So I have been banging away, writing Structures for Class Prototypes, reviewing, making changes, and adding comments 8)

I'm actually not sure when I am going to start writing the parser, because these data structures are really integral to a lot of the checks that my commands will be running when they are called. I prefer to have complete and functioning commands to test with so that I don't have to go back and figure out any possible bugs later :P

However I have a question or two.. All of my Objects in the game will have a unique ID associated with them, this means Rooms, Items, Containers, Weapons, Armor, Monsters and even the Player will have a unique ID that can identify them.. I've though about it in the past and wasn't quite sure how I would get the Engine to handle them and recognize them or even differentiate between two exact same items, but I have an idea and with some of the data structure fields (nouns, adjectives, etc) I think I got that covered..

What I haven't given much thought to, is how I will generate the unique ID's.. Not a problem for the small test I will be building, but when I get around to developing my Asset Creation Tool (Which will allow me to do everything from 1 app, build rooms and link them together, create all types of items, monsters, etc) I need a Method to automatically generate the Unique ID's without messing things up. So what is the best way to do it?

I need a universal format.
It can't generate duplicate ID's
It should remember the last ID created and continue from there..


Should I bother with an RNG (Random Number Generator)? Is there a way to ensure it follows the 3 needs I outlined above, maybe using the same Seed every time? Or should I just use an incremental counter, store the last ID generated in a variable that can be saved to disk, etc.. Also, I need to generate ID's in real-time while the game is running, since Monsters will spawn and despawn, random loot items need to be created... I know I can probably just use a different UID generator for run-time stuff, but I will also be saving the game-state to the Database periodically (sucks to lose progress) and also on demand when the player wants to Save/Quit and come back later.. I'm concerned with two UID formats clashing with each other (possibly generating a duplicate ID ?) but that should be easy enough to fix I think..

In fact I just thought of the solution... :oops: I should use several different UID formats, for different "Types" of game objects:
I want to avoid funny issues with memory addresses and such (I've had this problem in Python, and I think DarkBasic too, for some reason)
so I will store all ID's as Strings$ and not Integers, then I can do simple String Comparisons when I need to check something (right?).
All UID's will have a Prefix for their object "type", just like my Rooms will have a prefix for the general Area they belong to.

Player: A static 16 digit number should suffice (0x000000000000000)
Items: (1x000000000000000)
Armor: (2x000000000000000)
Weapons: (3x000000000000000)

I could probably keep track of the UID generation by storing the highest values for each type in the Database as well, I guess.. Since both the Asset Creation Tool and the Game would be reading and writing to the same Database file, this seems to be the most practical solution.

Unless someone has other ideas they think I might like?
Image
Post Reply