Log In  

Cart #35123 | 2017-01-06 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
71

Dialogue Text Box Library (DTB)

DTB is a code snippet that you can use to implement a dialogue text box to any game in just seconds.
Setting it up goes as follows:

  • Add the dtb code to the top of your own code.
  • Call dtb_init in your initialization.
  • Call dtb_update in your update.
  • Call dtb_draw function in your draw.
    And that all there is! You can now simply call "dtb_disp" wherever you want.

Usage

dtb_init(numlines)

Call this to initialize all dtb's variables. Takes an optional parameter which defines the maximum number of lines that will be displayed. Defaults to 3.

dtb_update()

Call this every update. All logic is contained within dtb.

dtb_draw()

Call this every time the screen gets drawn. Preferably at the end so the textbox always appears at the top.

dtb_disp(txt, callback)

Call this to display txt in a textbox. The text is added to a queu so this function can be called multiple times after each other without interfering with the previous text.
Takes an optional callback parameter (function) which is called when this particular piece of text is done displaying.

The actual snippet

Here is the minimized snippet. 1370 characters and 447 tokens:

-- dialogue text box library by oli414. minimized.
function dtb_init(n) dtb_q={}dtb_f={}dtb_n=3 if n then dtb_n=n end _dtb_c() end function dtb_disp(t,c)local s,l,w,h,u s={}l=""w=""h=""u=function()if #w+#l>29 then add(s,l)l=""end l=l..w w=""end for i=1,#t do h=sub(t,i,i)w=w..h if h==" "then u()elseif #w>28 then w=w.."-"u()end end u()if l~=""then add(s,l)end add(dtb_q,s)if c==nil then c=0 end add(dtb_f,c)end function _dtb_c()dtb_d={}for i=1,dtb_n do add(dtb_d,"")end dtb_c=0 dtb_l=0 end function _dtb_l()dtb_c+=1 for i=1,#dtb_d-1 do dtb_d[i]=dtb_d[i+1]end dtb_d[#dtb_d]=""sfx(2)end function dtb_update()if #dtb_q>0 then if dtb_c==0 then dtb_c=1 end local z,x,q,c z=#dtb_d x=dtb_q[1]q=#dtb_d[z]c=q>=#x[dtb_c]if c and dtb_c>=#x then if btnp(4) then if dtb_f[1]~=0 then dtb_f[1]()end del(dtb_f,dtb_f[1])del(dtb_q,dtb_q[1])_dtb_c()sfx(2)return end elseif dtb_c>0 then dtb_l-=1 if not c then if dtb_l<=0 then local v,h v=q+1 h=sub(x[dtb_c],v,v)dtb_l=1 if h~=" " then sfx(0)end if h=="." then dtb_l=6 end dtb_d[z]=dtb_d[z]..h end if btnp(4) then dtb_d[z]=x[dtb_c]end else if btnp(4) then _dtb_l()end end end end end function dtb_draw()if #dtb_q>0 then local z,o z=#dtb_d o=0 if dtb_c<z then o=z-dtb_c end rectfill(2,125-z*8,125,125,0)if dtb_c>0 and #dtb_d[#dtb_d]==#dtb_q[1][dtb_c] then print("\x8e",118,120,1)end for i=1,z do print(dtb_d[i],4,i*8+119-(z+o)*8,7)end end end

A readable/editable version can be found in this demo's code.

Feel free to use and customize this code in your own projects! I'd love to see it being used!

P#35126 2017-01-06 19:00 ( Edited 2017-07-12 14:30)

Very nice! I might try using this is in my next adventure game.

P#35625 2017-01-13 20:11 ( Edited 2017-01-14 01:11)

Excellent, great job! Any plans to implement scrolling via up/down on dialogs that end up longer than 3 lines?

P#35646 2017-01-14 02:13 ( Edited 2017-01-14 07:13)

@Scathe that's a neat idea! I'm struggling a little with adding more features tho. It rapidly increases the number of tokens even though some people might not need/require all of the features.

P#35845 2017-01-16 06:34 ( Edited 2017-01-16 11:34)

@Oli414 I'll be using this in one of my carts. Thank you so much!

P#35866 2017-01-16 16:15 ( Edited 2017-01-16 21:15)

Is there a way to implement this on my #tinytvjam to display directions?

P#35927 2017-01-17 13:48 ( Edited 2017-01-17 18:48)

@JetJaguar not really, you only have 10x11 pixels to work with in the useable draw routine for the jam; anything bigger than that is basically drawn over by the uneditable code.

P#35941 2017-01-17 15:55 ( Edited 2017-01-17 20:55)

Appreciate the insight, @2Tie

P#35976 2017-01-18 00:06 ( Edited 2017-01-18 05:06)

This looks really solid. I've been dreading tacking dialogue in my current project with my dwindling token budget. Totally going to use this :)

P#35985 2017-01-18 03:58 ( Edited 2017-01-18 08:58)

@HotSoup Awesome! Looking forward to it!

@JetJaguar Like 2Tie said, there's just too little space to make it work I think.

@jade Thanks! Feel free

P#36003 2017-01-18 08:23 ( Edited 2017-01-18 13:23)

Wow that's really nice and small!

P#36461 2017-01-23 07:28 ( Edited 2017-01-23 12:28)
1

@Oli414 This is amazing! I've also added in a thing when it changes the text sound effect depending on what you set the variable 'mood' to.

P#41990 2017-06-29 00:56 ( Edited 2017-06-29 04:56)

Goodness this is sexy! I'll definitely be using this in my game. I was dreading refactoring my own text box library but it looks like I can cut that todo item now!

P#42398 2017-07-12 10:30 ( Edited 2017-07-12 14:30)

Bless! I was working on my own dialogue system, but it proved complicated. This is a real neat template! :D

P#69496 2019-10-30 22:06

Hey, I might be doing something wrong, but when I use the callback in dtb_disp(), the callback function gets called immediately, instead of for the text to be finished. Any idea?

EDIT: I fixed it. having the full function under callback does work

dtb_disp(text[level], --start fade function() fading=true end)

P#70468 2019-12-01 20:10 ( Edited 2019-12-01 20:22)

I'm actually working on something like this, but it operates at 4-different messaging levels. Will let you know more when I do myself. :)

P#70477 2019-12-01 22:54

Nice library; only 7 functions!

I've been working on my own and it's nice to see how someone else solves the problem. What made you choose to store the current character? I'm considering using a single string as input that then gets broken into lines ahead of time, then they get fed to the animation part. I like your use of a queue, it makes a lot of sense since the best dialog in games is dynamic and DTBs need a general interface.

Do you have any plans to expand this to include basic widgets that show up in dialog, like Yes/No and multiple choice? Highlighted words? I'm hoping to get something like that going for mine.

Thanks for sharing!

P#76778 2020-05-17 18:13

Hi! thank you! I've been using this for my personal little fish adventure game.

I can't seem to get it to display text when i move to another map screen tho :( i'm changing some coordinates in dtb_disp() is that not enough ?

EDIT: i fiddled with Camera() and it is doing the right thing, (128,0) at one screen over, but the dialogue is still not printing on the second screen. is the draw functions not being affected my camera() somehow ?

P#77159 2020-05-25 06:15 ( Edited 2020-05-25 07:15)

NOICE

P#85081 2020-12-06 02:10

This is really neat! However does anyone know how to use it in between interactions? Like for example
scene 1: A and B were talking (showing with this dtb module)
scene 2: allow player to investigate the environment
scene 3: A and B talking again (showing with this dtb module)

as far as I understand the content of dtb_disp() was decided inside _init(), but scene 2 requires interactions inside _update. How to add the conversation in scene 3 after that? Sorry if my question sounds silly, thank you in advanced!

P#91354 2021-05-01 13:14
3

Made a little example to cover @Vincewassig's question :>

.

Cart #text_lib_example_7382-0 | 2021-09-20 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
3

P#97590 2021-09-20 14:48
2

Been a while since I made this, I'm currently revisiting the project for which I made this and I made a much more efficient version if you don't need any fancy features:

function dtb_init()
    dtb_q={}
    dtb_p=1
    dtb_qt=nil
end

function dtb_update()
    if #dtb_q~=0 then
        dtb_p+=1
        if dtb_p>#dtb_qt then
            dtb_p=#dtb_qt
            if btnp(🅾️) then
                del(dtb_q,dtb_qt)
            dtb_qt=dtb_q[1]
                dtb_p=1
            end
        elseif btnp(🅾️) then
            dtb_p=#dtb_qt
        end
    end
end

function dtb_draw()
    if dtb_qt~=nil then
        rectfill(2,105,125,125,1)
        print(sub(dtb_qt,1,dtb_p),4,107,7)
        if dtb_p==#dtb_qt then
            print("🅾️",117,119,13)
        end
    end
end

function dtb_disp(str)
    add(dtb_q,str)
    if (#dtb_q==1) dtb_qt=dtb_q[1]
end

This version has no callback, no sounds and no no configurable line length.

You can split your text across multiple lines using a line break /n

It's a bit more basic but uses lot less tokens!

If you wish to modify this:
dtb_q is the queue of texts to display. Each string in this table is shown as a separate box, and displayed in the ordered it's in.
dtb_qt is the current queue text, usually dtb_q[1] or nil.
dtb_p is the text pointer, ranging from 1 to #dtb_qt.

P#116573 2022-08-30 12:46 ( Edited 2022-08-30 12:48)

This is exactly what I was looking for and I had no clue where to start tackling it. Thank you so much, beautiful work :)

P#122266 2022-12-12 00:51

Beautiful!! I was just opening a new file to play around with displaying dialogue and wow here it is all solved already 😊

P#124965 2023-01-29 00:33
2

I hacked in some rudimentary support for speaker/title on the text box. You can now identify who or what is sending the message. It also supports not having a title or speaker defined and will display that like it used to.

I've attached a cartridge for reference (the forum software kept removing lines from my codeblocks??). Press the left arrow to initiate the text box, press Z (⭕) to advance.

I'm also keen to allow for the ability to change textbox position (just top or bottom, maybe center too) for each message, but that'll wait for another day.

Cart #gozimtapi-1 | 2023-01-29 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2

P#124968 2023-01-29 05:29

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 20:09:42 | 0.098s | Q:72