The plan is for my game to have maybe about a dozen books. These can be read where they are, and some maybe picked up and carried as inventory. I figured instead of making a dozen different GUIs or a dozen different rooms, I'd make a "book GUI system" instead. I haven't completed it yet, but I'd figure I'd mention how I'm planning on going about it here, and get input on if I'm doing something wrong or overcomplicating stuff.
Things I'm doing to simplify my life:
- No page turn animations
- Books always open to the middle (the border image would stay the same, and you'd never see the cover from the front)
- There can be images, but if a page has an image, it'll only be in a fixed position (center top)
- No position saving when you close and reopen a book
EDIT: I wanted to share a mockup, but imgur doesn't seem to work any more. Someone have an alternative?
My idea was to have a struct that would contain:
- The text of the book (likely not going to be more than 5-6 "pages")
- A variable to hold the colour of the cover (will be used to assign relevant images to the visible edges of the cover)
- A variable to hold the colour of the pages (will be used to assign the relevant images for the edge of the paper, as well as the "page turn" button)
- (Getting complicated for me here) An array holding all the images in the book, with the index having 0 if there is no image on a page
Then when the player picks up a book and reads it, set up the GUI with the variables of the relevant instance of the struct, and make it visible.
Two things are currently worrying me:
Could there be an easier way of having the book than just typing it all out as a string in the script?
Splitting the text of the book into pages- I'm guessing I'll need to figure out a max number of characters, and if a word extends beyond that, move it and the rest of the text to the next page. Will need to figure out a way to calculate that includes whether the page has an image or no image
Is there something I'm missing that vastly simplifies this all? Is there something that I'm missing that will complicate everything? Is there a better way to do this? Thanks in advance for your help!
EDIT; I wanted to share a mockup, but imgur doesn't seem to work anymore. Someone have an alternative?(https://i.ibb.co/HTX38sJk/book.png)
I have used different implementations of ImgBB for file hosting sometimes - I think one of those is https://imgbb.com/ ? It's like a hosted by someone Imgur basic clone like thing I think.
About the book GUI system, you need the images? If you want you can try using the Fancy module to see if it can handle images in the strings themselves and assign the resulting image (with text and sprites) in a button to be the page contents. Not sure how well that will go but it's an idea.
I once did a text only book system and used a directory that I packaged along the game (using the option from general settings) and had a bunch of "book_001.txt" text files which I edited in a different text editor that had spellcheck and made they be loaded by the game (using the $DATA file token). It worked nice but I didn't have images or any need for complex layouts so there wasn't much testing of the text of each book to get it to render correctly in the engine.
Quote from: Babar on Tue 12/08/2025 16:27:17EDIT; I wanted to share a mockup, but imgur doesn't seem to work anymore. Someone have an alternative?
Imgur worked a day ago, I've posted one image here, and it's still showing:
https://www.adventuregamestudio.co.uk/forums/index.php?msg=636684832
Are you sure you are using the correct BBCode link?
Quote from: Crimson Wizard on Tue 12/08/2025 17:28:52Quote from: Babar on Tue 12/08/2025 16:27:17EDIT; I wanted to share a mockup, but imgur doesn't seem to work anymore. Someone have an alternative?
Imgur worked a day ago, I've posted one image here, and it's still showing:
https://www.adventuregamestudio.co.uk/forums/index.php?msg=636684832
Are you sure you are using the correct BBCode link?
It wasn't even letting me upload.
But I've shared an image now with imagebb, thanks eri0o.
Quote from: eri0o on Tue 12/08/2025 17:17:40About the book GUI system, you need the images? If you want you can try using the Fancy module to see if it can handle images in the strings themselves and assign the resulting image (with text and sprites) in a button to be the page contents. Not sure how well that will go but it's an idea.
I once did a text only book system and used a directory that I packaged along the game (using the option from general settings) and had a bunch of "book_001.txt" text files which I edited in a different text editor that had spellcheck and made they be loaded by the game (using the $DATA file token). It worked nice but I didn't have images or any need for complex layouts so there wasn't much testing of the text of each book to get it to render correctly in the engine.
I was thinking about simplifying the images by just having them be full page width in the background, and text on top of them, and manually spacing out the text if an image is there. So the images array could have one value for an empty page, and another for an image (could just be the sprite index, in fact).
Like Eri0o, I would suggest reading the contents from a separate text file rather than putting it directly in the script.
I always default to managed structs, which in AGS v3.x don't support strings or dynamic arrays, so that might be an issue.
As for the images, instead of using sprite IDs directly, I would suggest putting them in a view, and for example using the loop number for the book index and the frame number as the page index of the one to display. You have to do a little bit of work to retrieve the sprite, but it will make it easier to inspect and play around with the images.
In case you want to use all images for your books, including text, assuming your game has a low resolution so having many images is "cheap", you can just have the entire book as image and put the text either as layers in external software or generate the images using some python script and then you just import the images in ags and done. Make an int array in AGS for book inlets and put each sprite there or a managed struct with any data.
If you need strings that aren't too long in a managed struct you can use a fixed char array and it should work good enough, make sure that it has a char with "0" value at the end and I think you can even String.Format("%s", char_array) to retrieve back the string you stored there (I think for storing you need to use a for).
If I would approach this problem, I'd probably store books as either a JSON file or some sort of a custom textual descriptive format that would allow to mix text and image references.
E.g. a syntax like
text:
bla bla bla bla
image: spritenumber (or a view/loop/frame number, if you follow Snarky's suggestion)
text:
bla bla bla
For displaying the book in game, I would use either DynamicSprite + DrawingSurface to draw everything on a sprite and then assign to a GUI background; or alternatively a mix of Overlays (graphical and textual) over a book's GUI.
About storing things in script.
Honestly, I don't recommend using "array of chars" as a method to have strings in managed structs, because working with char arrays is not trivial for non-programmers, and also, please remember that this way your char arrays will also be fixed-sized! This "array of chars" approach is good as the last resort only.
I'd probably just use non-managed structs, stored in a array of fixed and big enough size. If that does not work, then have Strings in a separate dynamic array, while the main struct (describing a page) contains references (index) to that array. Hide this mixed implementation inside a module, behind a convenient interface.
Quote from: Snarky on Yesterday at 16:11:04As for the images, instead of using sprite IDs directly, I would suggest putting them in a view, and for example using the loop number for the book index and the frame number as the page index of the one to display. You have to do a little bit of work to retrieve the sprite, but it will make it easier to inspect and play around with the images.
I'll add: If you do use this approach, you can let this view define the page-to-image mapping, rather than storing it either in the struct (where you have to hard-code it blindly) or in the text file (where you have to do text parsing).
Would AGS allow to read PNGs at runtime, I would propose storing book images as files in a custom folder packaged into the game (along with the book text), and then loading them up as dynamic sprites when needed. That would make it possible to edit books fully externally.
Unfortunately, AGS still does not have a PNG loader in the engine, and can only load BMP files (uncompressed).
I like the idea of using a view, it's like a pre-built data structure where I can keep the first few frames of the loop for stuff like the cover and corners and such, and the rest would be images in the book (or sprite index 0 if that page has no images).
The game is low res, but I don't want the whole book to be images, because there might be translations at some point down the line, and having multiple translation images in a loop feels like it would get very complicated.
I'll try to come up with a demo over the weekend, using an external text file, and then if (when) I have problems, I'll ask more here!