An in-game interactive journal (SOLVED)

Started by KingMick, Wed 19/04/2006 13:41:44

Previous topic - Next topic

KingMick

One of the features I want to implement in my game is an in-game journal that the player can add new text to and edit existing text in.  I am having trouble figuring out how to do this.  I want the journal to work similar to a word processor, so that clicking somewhere within the text field positions a cursor there and the player can then delete text already written, insert new text, etc.  The following features I want to include, but am not sure how to do so:

(1) Player can enter an entire "page" of text.  In other words, the current max string length (unless it is changed in v2.71 which I have yet to download) is too short.  I need a way to have longer strings, or else have one string merge seemlessly with another somehow, or something.

(2) Player can click anywhere on a current journal page and edit the text already there, delete it, or add new text, just as if they were using a word-processor.

(3) Player can add as many new pages as they want to, possibly via a "add page" button on the journal.

(4) (MOST IMPORTANT) Journal can be accessed from more than one AGS game, since this game utilizes more than one file with continuing downloadable expansions.  I want the player to be able to take the same journal with them from one expansion to another.  I am guessing this means the journal will need to output to some kind of external file somehow.

(5) Strings / words / sentences do not have to necessarily have to wrap from page to page, but if there is an easy way to do this it'd be nice to implement it.  In other words, if the player could just keep typing at the end of a page and have the text automatically continue onto the next page, that would be a nice convenient feature (but not worth it if it would take a ton of effort to make it happen).

GarageGothic

#1
The string length isn't a problem anymore since we now have Strings of unlimited length. However, that may not be the best solution of managing the text. The easiest way I can see is to have every page consist of a listbox, this is the way the conversation log in my game works. That should also make the positioning of the cursor trivial (height coordinate handled by the listbox itself, width calculated with GetTextWidth)

However, creating a random-access system with multiple pages will be difficult. The easiest way would be to output every page to it's own text file, then read that page back in, edit it, and output it, overwriting the old file for that page. This means that could can't add to a page and let it wrap existing text onto the next page though. Every  page will be a self contained unit with a limited amount of space.

The only way these files could be accessed by another AGS game is if they're in the same folder. So you must either ask the player to move the files to the expansion's folder or place the .exe files in a common folder.

Edit: You could use HeirOfNorton's encryption module (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=23109.0) to avoid players reading/messing with the external files.

Edit 2: I think this topic is advanced enough to be moved into the real Tech forum instead of Beginner's Tech

KingMick

Quote from: GarageGothic on Wed 19/04/2006 14:23:42
Edit 2: I think this topic is advanced enough to be moved into the real Tech forum instead of Beginner's Tech

Wow, really?  I feel important now :).  I think that would be my first-ever thread in that forum.

A few questions about your other advice.  First off, could you explain a bit more about the height and width coordinates via listbox and GetTextWidth?  Using a listbox hadn't even occurred to me, I'm ashamed to say.  I was thinking Labels, but I bet this would work better.  To clarify my own needs: I want the player to be able to click anywhere in the listbox and have a typing-cursor appear there.  Using the up, down, left, and right keys should also move the cursor.  Then if they enter text, it appears where the cursor is, moving over any text that is next to it, and if they hit DEL or BACKSPACE the appropriate functions are implemented.

Having the AGS games in the same folder is not a problem, it's going to be required for the expansions to work anyway.  HOWEVER, it occurs to me that some of the functionality may need to go "up a folder".  In other words, it would probably work like this:

The game is in a directory called "Game".  Within that directory we have two other folders called "Journal" (where the journal pages go) and "Expansion" (where another AGS "game" goes that can only be accessed from the first one in the main "Game" directory).  Now, I'm pretty sure I can use "Expansion/NewGame.ags" or whatever to access the new game from the old one, but how do I go UP a folder from the new game?  i.e. from the new game's program, access the Journal pages which are in the Journal folder, and the main game which is in the Game folder?

Thanks for your help already, and in advance for whatever else you can help me with.

P.S: Whoa, conversation log.  Good idea.  Wish more AGS games had something like that.

GarageGothic

#3
First of all, I must repeat that this kind of String manipulation and use of external files is pretty advanced stuff. If you thought this belonged in the Beginner's tech, either you are very skilled, or not aware of how much work it will take. If the latter is the answer, perhaps you should ask yourself whether a feature like this is essential to your game or could be simplified somehow.

For security reasons, AGS doesn't allow you to go "up" a folder, since that would allow the script to do evil things, like deleting stuff from the Program Files or Windows folders.

As for how to use the listbox, this is what I meant:

Say the player clicks on a line of text. Then you would use ListBox.GetItemAtLocation(mouse.x, mouse.y) to retrieve which line number (index) the player clicked on. Then you can retrieve the content of this line using ListBox.GetItemText. Alright, since you know the x-coordinate of the ListBox, as well as the mouse.x, you can now find out how far into the line the player clicked ((mouse.x - ListBox.X) - ListBoxGUI.X).

So, to find out which character the cursor is at, you could take this width value, and do something like this:

Code: ags
String tempstring = lstMyBox.GetItemText[lstMyBox.GetItemAtLocation(mouse.x, mouse.y)];
int width = (mouse.x - lstMyBox.X) - lstMyBoxGUI.X);
while (GetTextWidth(tempstring, fontnum) > width) {
    tempstring.ReplaceCharAt(tempstring.Length - 1, 0); //shortens the string by one character
    }


Doing this, the tempstring will be shortened down to the amount of characters to the left of the cursor, which means you know from which point in the text to manipulate it. You may have to deduct a pixel or two from width, since the text doesn't start at the exact coordinate of the ListBox.

I hope this makes sense. And that you do know this is just the very beginning.

Edit: Another solution, which would only allow a limited amount of space, and would take up memory while playing as well as drive space in every savegame, is to create a large array of Strings. I chose not to use this option for my own game, as a conversation log could end up being many MBs of data, but few players would end up writing as much text as the game itself contains. And it would make random access manipulation of data much easier.
You could still have the listbox as a managing device, but the data would be stored within your savegames rather than in external files. Then, when moving onward to the expansion, data could be exported to one big txt file, read back into the expansion. This could be generated when quitting the game.

KingMick

Hmmm.  Well the problem with doing things the way your ListBox suggestion works is that this would be overriding characters instead of inserting them.

I am thinking that the String array idea would indeed be better.  I don't think I would include it in the saved game at all, in fact.  Rather, I would just have it "save" the journal entries by dumping them straight to a text file.  That way I can skip a step in the process.

Of course, I'll have to learn more about String editing to figure out how to make this work.  Since v2.71 allows infinite strings (from what you've said), I suppose I could make each page be a single string.  That could easily fix the word-wrap and other issues.

In the end, if I can't figure out how to do it, or if it seems like just too much of a hassle, I suppose I could go with a bare-bones version where you could add, delete, and view entries (strings), but not edit previously made strings.  I may have to be satisfied with just that.  I'll have to see.

Thanks for all your help, GarageGoth.  Couldn't have figured out even this much without you.

*is already putting "GarageGoth" under Special Thanks in the game manual's credit section, along with a few other helpful people from these forums*

GarageGothic

The listbox code was just an example of how to use the mouse coordinates to figure out where in the text the user had clicked. The rest of the manipulation would be done through other commands - the tempstring is just there to figure out WHERE to insert new text.

KingMick

Thanks for your help Garage!  I'm almost done, just bumped into one or two little obstacles.

In the end, I decided to do it this way: The journal is a gui with 5 labels and corresponding buttons to delete or add to a label.  The buttons are a "toggle" deal--if there's text in the label you can delete it, if there's not then you can enter text into a new pop-up gui with a textbox, and the game enters that text into the appropriate label.  File input-output is handled any time a label changes.

I've run into a couple of problems with the textbox, though, and one minor inconvenience relating to the file.  I posted 'em as separate issues since...well, that's what they are :)

Anyway, I wanted to just say thank you and let you know how I decided to do it in case you were curious.  If you want to try to figure out the obstacles, links are HERE and HERE.

Thanks again Garage!

mods: You can mark this as solved now...

Ashen

Quote from: KingMick on Fri 21/04/2006 11:08:05mods: You can mark this as solved now...

Well, OK, but you know, you can do that yourself - just edit your first post.
I know what you're thinking ... Don't think that.


SMF spam blocked by CleanTalk