Anyone interested in helping turn my dialogue drawing system into a library that anyone could use?

https://gfycat.com/pastkaleidoscopicbasenji

So I'm working on a system that can take a long string of essentially any length, then correctly display it in any rectangle's dimensions that you specify, as well as "animating" that text being written out.

I've got it basically working (see gif above), but there are still some weird edge-cases I'm having trouble fixing.

I also know that other people have expressed interest in having a system like this in their game, so I would like turn this into a public portable library that could be imported into essentially any project.

The issue is I am a very novice programmer, so I'd need some help making the code a little more portable and less embedded with my game code, and I also don't know much about making/maintaining a public GitHub repo.

I'll attach my current project in it's entirety which you should be able to build and run in the simulator or on device to see what I have so far. It's a Noble Engine project, so the scene structure may seem odd if you aren't familiar with that already.

Feel free to ask any questions here. Thanks!
HatTrick_Deluxe-EarlyAlpha.zip (3.4 MB)

6 Likes

What's the wish-list?

I'm kind-of halfway through a C-API text box. I want to have up/down scrolling when the text is too big for the box. I also want different text justifications - left, centre & full. (I guess I'd do right-just too, for those that need it).

1 Like

My desired end-goal would be a library/function that the user can give;

  • a string of arbitrary length
  • a rect that will contain the text (so proper newlines and paginating can be determined)
  • x,y for the top left corner of the rect
  • a font to use
  • what speed to reveal the text at
  • (bonus: also handle a nineslice background for the text to be drawn on)

then the function/library would handle properly formatting that input string into lines/pages, no matter how long or short, and would also handle "animating" the dialogue box to reveal one letter at a time.

the player could then "skip" the reveal animation with a button, and if it was all already revealed the button would start the next page.

My favourite interaction on such boxes are to hold the button to speed up the text. And it takes a second press to dismiss or go to the next test.

5 Likes

Those would be great options to be able to let the user set when integrating the library (after we get base functionality figured out of course :sweat_smile: ).

Something like;

  • no animation = draw the entire page of text instantly
  • pokemon style = hold B to speed up text, press A to go to next page
  • pulp style = press A to skip animation and/or A to go to next page
  • etc.
1 Like

Didn't get far, but now there's a build_and_run for Linux (bash):

build_and_run.sh.zip (818 Bytes)

(checks clock, oooh I still have 30 minutes!)

Heh ... you used the correct English for "Dialogue", I thought I was the only one.

Note: Entry point for TextBox dialogues is function Overworld:startDialogue(text).

The text dialogue is modal right? (When it's on-screen, the player can only interact with it, until it's closed).

I'm thinking the whole dialogue should be in a separate class. That means I'll have to learn Lua.

1 Like

Yes, (again, there are some Noble Engine features at play here, which is part of the "de-coupling" that will need done to make this more modular) but I currently have it set up so that all my entities are frozen and the Noble Input handler is changed to "DialogueInput" which doesn't allow movement or any interaction other than advancing the dialogue box.

And I didn't even realize there was a "USA" spelling for dialog, but I'm definitely not from the UK :sweat_smile:

1 Like

Ok, I'm out of time. But my first thoughts are to pack all the "Text Box" stuff into it's own class/object, that will clearly separate the local text box variables from the Overworld parent object. ( I'm slow, because I have to learn the Lua syntax as I read. )

I can't see the cause of any issues yet, not familiar enough with it.

Ok, back in 8 hours or so... who knows what this day will bring.

2 Likes

I've been doing that @UrlOfSandwich! I started with Nick's code he shared on discord and have broken it into a few "wrap" and "paginate" steps. This was for 300, 60 rect:

It also has a window option, here it is with an initial index of 2 and a custom font (idk how to do font families):
image

Here's a gist, it's pretty untested and uncommented but it's also only 94 lines: Paginate helper library in Lua (for the Playdate) · GitHub

And here's some test code:

local windowWidth, windowHeight = 300, 120
local text = Paginate.read("filename")
local wrapped = Paginate.wrap(text, windowWidth)

local paginated = Paginate.paginate(wrapped, Paginate.getRows(windowHeight))
Graphics.imageWithText(paginated[3], windowWidth, windowHeight):draw(2, 2)

local window = Paginate.window(wrapped, 2, Paginate.getRows(windowHeight))
Graphics.imageWithText(window, windowWidth, windowHeight):draw(2, 2)

Graphics.drawRect(2, 2, windowWidth, windowHeight)

Edit: read probably shouldn’t be in the paginate tools, for dialogue you’d call wrap and then paginate for each line so there wouldn’t be a need to read an entire file

I also can’t help but to think that Paginate isn’t the best make for this particular script. Something like Atropos would be cool if it wasn’t such a niche reference lol

3 Likes

Looks good! What's the difference between using window and just setting a smaller rect for wrapped text?

Also, is image with text a performance increase? What's it doing differently than just normally displaying text?

1 Like

window lets you set an initial index and limits the output to a single “page”. You could do the same thing manually by creating a new table with the desired lines and passing them to paginate, but I figured window would be useful if you wanted a panel of text that allows the user to scroll line by line.

I used imageWithText because it lets you “render” the text once and then draw the image instead of having to do all the text drawing every frame. Not really important for example code but that’s what I’m using in my own stuff so I used it there too :stuck_out_tongue:

ALSO! A wishlist item would be for the dialogue to work like BotW dialogue boxes:

  • Hold A to speed up text, press A to start animating next line
  • Tap B to draw rest of text immediately, Press B to show all of next line immediately

It’s kinda subtle but I thought the difference was nice when I was skipping dialogue on my second playthrough

3 Likes

@Gamma - looks good. Not sure there's anything for me to add here :wink:

1 Like

I added a process method that takes a string, width, and height and it automatically wraps and paginates it for you. I also fixed a bug!

Paginate.process(
        "This is a very long line of text, and it should wrap AT LEAST ONCE but maybe even twice!",
        windowWidth,
        windowHeight
    )

image
image

1 Like