We're archiving the forums and going read only! You'll be able to see old threads, but new topics and replies have been disabled.

Visit the Game Jolt community for new questions and conversations.


Update 2/25/16 - This thread is quite old, but I appreciate how much traction its consistently getting. I improved the formatting. If you're willing to spend $0.99, check out this Smooth Dialogue Engine I released on the YoYoGames' Marketplace.


A game with dialogue can be drastically improved with a "typewriter" effect, in my opinion at least. Not only is it aesthetically pleasing, but can ease the burden of a lot of text on-screen. Though this example is written for Game Maker, it can be adapted to other languages with ease. Absolutely no credit is necessary, as this took only two minutes to write.


Create Event:

		
			//write your messages in an array, starting at 0, like so
message[0] = "Hello there! Welcome to the world of Pokemon!";
message[1] = "My name is Oak! People call me the Pokemon Prof!";
message[2] = "This world is inhabited by creatures called Pokemon!";
message[3] = "For some people, Pokemon are pets.";
message[4] = "Others use them for fights.";
message[5] = "Myself...";
message[6] = "I study Pokemon as a profession.";

message_current = 0; //0 is the first number in our array, and the message we are currently at
message_end = 6; //6 is the last number in our array
message_draw = ""; //this is what we 'write' out. It's blank right now
increase = 0.5; //the speed at which new characters are added
characters = 0; //how many characters have already been drawn
hold = 0; //if we hold 'Z', the text will render faster

message_length = string_length(message[message_current]); //get the number of characters in the first message
		
	

Step Event:

		
			if (characters < message_length) { //if current character count is less than the amount in current message* 
    hold = keyboard_check(ord("Z")); //hold is true or false if we hold 'Z' or not
    characters += increase * (1 + hold); //increase speed based on hold
    message_draw = string_copy(message[message_current], 0, characters); //copy string to current character
} 
else { //if current character is more than the amount in the current message
    if (keyboard_check_pressed(ord("Z"))) { //if we press Z...
        if (message_current < message_end) { //if there are more messages left to show (0 -> 6, in our case)
            message_current += 1; //increase the message by 1
            message_length = string_length(message[message_current]);  //get the new character length for message
            characters = 0; //set the characters back to 0
            message_draw = ""; //clear the drawn text
        }
        else { //if our messages are done (we reach 6, in our case)...
            instance_destroy(); //destroy the object
        }
    }
}
		
	

Draw Event:

		
			draw_text(x, y, message_draw); //draw the text at the coordinates
		
	

Page 1 of 85 replies.

about 12 years ago

Very nice tutorial! Thank you it works perfectly!

over 11 years ago

well i found this randomly from google and it has helped me out so thanks even though its a really old post.

almost 11 years ago

Thanks a lot, this is perfect! :)

almost 11 years ago

Wow! I'm definitely using this, and since I have a general lack of credits, I'll just add you in for the sake of doing it. XD

almost 11 years ago

Thank you! I will be using this for Alex in High School 3 and onward.

about 10 years ago

Is this for any specific kind of game maker? I am using 8.0, and nothing shows up at the coordinates where my character is. PLEASE HELP! THIS GAME IS REQUIRED IN 24 HOURS!

about 10 years ago

@Something_Games
No specific version of recent Game Maker is required.

Couple things to try:
draw_set_halign(...);
draw_set_valign(...);
Ensure your object is visible.
draw_set_alpha(1);
Ensure nothing is being drawn over the text.
Ensure the depth exceeds other objects'

about 10 years ago

Wow, this looks really really nice! I'll probably be sticking to the less impressive text engine that I made myself, but If I need to upgrade I'll know where to look.

about 10 years ago

This works until you try and do it with multiple objects.

almost 10 years ago

Thanks a lot zack!

almost 10 years ago

awesome!

almost 10 years ago

how do i add a box around it btw this is the only working one i can find and i love it but is there a way to add a box?

almost 10 years ago

ERROR in

action number 1

of Step Event

for object text:

Error in code at line 10:

message_length=string_length(message[message_current]); //get the new character length for message

		
			                            ^
		
	

at position 31: Unknown variable message or array index out of bounds

almost 10 years ago

also how do i change the color of the text?

almost 10 years ago

Add to the Draw event of your dialogue object.

draw_set_color(c_white)

// or whatever color you want.

almost 10 years ago

I solved my own problem! For anyone who wants the text ONLY to appear when they step on the object, AND be able to add as many of these things as they want, here's my code! It's not the neatest thing, and is kind of... Well. Messy. But hey, it works. You don't need to have 100 messages like I do, but you do need to make sure that they all get destroyed at the same number, or else you will get an error. Edit it as you please!

Create:

//write your messages in an array, starting at 0, like so

message[0]=""

message[1]=""

message[2]=""

message[3]=""

message[4]=""

message[5]=""

message[6]=""

message[7]=""

message[8]=""

message[9]=""

message[10]=""

message[11]=""

message[12]=""

message[13]=""

message[14]=""

message[15]=""

message[16]=""

message[17]=""

message[18]=""

message[19]=""

message[20]=""

message[21]=""

message[22]=""

message[23]=""

message[24]=""

message[25]=""

message[26]=""

message[27]=""

message[28]=""

message[29]=""

message[30]=""

message[31]=""

message[32]=""

message[33]=""

message[34]=""

message[35]=""

message[36]=""

message[37]=""

message[38]=""

message[39]=""

message[40]=""

message[41]=""

message[42]=""

message[43]=""

message[44]=""

message[45]=""

message[46]=""

message[47]=""

message[48]=""

message[49]=""

message[50]=""

message[51]=""

message[52]=""

message[53]=""

message[54]=""

message[55]=""

message[56]=""

message[57]=""

message[58]=""

message[59]=""

message[60]=""

message[61]=""

message[62]=""

message[63]=""

message[64]=""

message[65]=""

message[67]=""

message[68]=""

message[69]=""

message[70]=""

message[71]=""

message[72]=""

message[73]=""

message[74]=""

message[75]=""

message[76]=""

message[77]=""

message[78]=""

message[79]=""

message[80]=""

message[81]=""

message[82]=""

message[83]=""

message[84]=""

message[85]=""

message[86]=""

message[87]=""

message[88]=""

message[84]=""

message[85]=""

message[86]=""

message[87]=""

message[88]=""

message[84]=""

message[85]=""

message[86]=""

message[87]=""

message[88]=""

message[89]=""

message[90]=""

message[91]=""

message[92]=""

message[93]=""

message[94]=""

message[95]=""

message[96]=""

message[97]=""

message[98]=""

message[99]=""

message[100]=""

message_current=0; //0 is the first number in our array, and the message we are currently at

message_end=100; //6 is the last number in our array

message_draw=""; //this is what we 'write' out. It's blank right now

increase=0.5; //the speed at which new characters are added

characters=0; //how many characters have already been drawn

hold=0; //if we hold 'space', the text will render faster

message_length=string_length(message[message_current]); //get the number of characters in the first message

Step:

if place_meeting(x,y,obj_character) then //this makes sure that the thing only appears if your character is on it.

if characters<message_length{ //if current character count is less than the amount in current message

hold=keyboard_check(vk_space); //hold is true or false if we hold 'Z' or not

characters+=increase*(1+hold); //increase speed based on hold

message_draw=string_copy(message[message_current],0,characters); //copy string to current character

}

else{ //if current character is more than the amount in the current message

if keyboard_check_pressed(vk_space){ //if we press space...

if message_current<message_end{ //if there are more messages left to show (0 -> 6, in our case)

message_current+=1; //increase the message by 1

message_length=string_length(message[message_current]); //get the new character length for message

characters=0; //set the characters back to 0

message_draw=""; //clear the drawn text

}

else{ //if our messages are done (we reach 6, in our case)...

instance_destroy(); //destroy the object

}

}

}

{

}

Draw:

if place_meeting(x,y,obj_character) then //this makes it so the text only appears while your on the object

draw_text(340,305,message_draw); //draw the text at the coordinates

over 9 years ago

This happens to me can someone help me?

FATAL ERROR in

action number 1

of Step Event0

for object obj_smile:

Push :: Execution Error - Variable Get -1.message_length(100008, -2147483648)

at gml_Object_obj_smile_StepNormalEvent_1 (line 1) - if characters<message_length{

over 9 years ago

@Zack how can you make a sound play as the message is typing and make the sound stop when the message is done typing?

over 9 years ago
In response to %{ user }@GamesReformed

Bit of an old thread, but I revisted to see if I could find anything on pausing a string. This is quite easy to do, but the way I do it is probably not as efficient as it could be.

//Under Step
if characters < message_length
{
character_old = characters
characters += increase_speed
message_draw = string_copy(message[message_current],0,characters)
if round(characters) > character_old stop_and_sound(<sound name here>)
}

You must activate character_old in the create event. It doesn't matter what you set it to as in the step event it'll be set to characters before characters increases.

stop_and_sound is a script I use for stopping and playing a sound, it's good for bullets, talking, lots of stuff. Argument 0 is your sound name.

//stop_and_sound
if audio_is_playing(argument0)
{
audio_stop_sound(argument0)
audio_play_sound(argument0,0,0)
}
else
audio_play_sound(argument0,0,0)

over 9 years ago

I updated the thread and improved formatting. Glad to see people are still getting a use out of this simple, albeit old, example.

over 9 years ago

Hello! This is a good system, but I was planning on making my own, and had a question. How did the waiting work? There's no command for it, and I know you used a variable to give it a slight pause, but I don't know.... how?

over 9 years ago
In response to %{ user }@EyedHero

The "increase" variable is the number of new characters added per frame. Since you cannot only display 0.5 (what it is defaulted to) of a character, when the variable reaches the next whole number, it renders the next character. So, 0.5 would be one char every other frame, 0.25 would be one char every fourth frame, 0.1 would be one char every ten frames, etc.

over 9 years ago

Hey. Would it be possible to add the Create Event code to an object's Creation Code?

over 9 years ago

Hello, I have a problem with this kind of event, and I was wondering if anyone here could help.

I've been attempting to use a very similar set up to the one listed here in order to get an rpg type-writer effect, but what seems to happen is that with each draw, the previous one is never erased. And so the text just becomes a blob.

I tried making use of the code here, even copying and pasting it exactly as is, but it has the same problem when I attempt to run it.

I'm using the most recent version of Game Maker Studio. If anyone has any idea how to fix this, it would be appreciated.

EDIT

I figured it out, it was a real face palm type thing on my part. I was accidentally spawning the text controller every frame, ha ha.

Last modified on March 8, 2016 by 1_d27b0a @1_d27b0a

over 9 years ago

Looks great! Question though, does the marketplace asset create the bubbles via draw_event?

over 9 years ago

how to insert sound??

over 9 years ago

I fucking love you<3 :'D thanks

over 9 years ago
In response to %{ user }@MrEpicIsHere777

I still have gotten some errors, let me post what I got so far.

so I created a script called stop_and_sound

//stop_and_sound
if audio_is_playing(sd_voice_blip)
{
audio_stop_sound(sd_voice_blip)
audio_play_sound(sd_voice_blip,0,0)
}
else
audio_play_sound(sd_voice_blip,0,0)

...sd_voice_blip is a sound I created with my "blip" sound in it.

under my object I created a create event with the code

//write your messages in an array, starting at 0, like so
message[0] = "Hello there! Welcome to the world of Pokemon!";
message[1] = "My name is Oak! People call me the Pokemon Prof!";
message[2] = "This world is inhabited by creatures called Pokemon!";
message[3] = "For some people, Pokemon are pets.";
message[4] = "Others use them for fights.";
message[5] = "Myself...";
message[6] = "I study Pokemon as a profession.";

message_current = 0; //0 is the first number in our array, and the message we are currently at
message_end = 6; //6 is the last number in our array
message_draw = ""; //this is what we 'write' out. It's blank right now
increase = 0.5; //the speed at which new characters are added
characters = 0; //how many characters have already been drawn
hold = 0; //if we hold 'Z', the text will render faster

message_length = string_length(message[message_current]); //get the number of characters in the first message

character_old = 0;

then I created a step event with...

if (characters < message_length) { //if current character count is less than the amount in current message
hold = keyboard_check(ord("Z")); //hold is true or false if we hold 'Z' or not
characters += increase (1 + hold); //increase speed based on hold
message_draw = string_copy(message[message_current], 0, characters); //copy string to current character
}
else { //if current character is more than the amount in the current message
if (keyboard_check_pressed(ord("Z"))) { //if we press Z...
if (message_current < message_end) { //if there are more messages left to show (0 -> 6, in our case)
message_current += 1; //increase the message by 1
message_length = string_length(message[message_current]); //get the new character length for message
characters = 0; //set the characters back to 0
message_draw = ""; //clear the drawn text
}
else { //if our messages are done (we reach 6, in our case)...
instance_destroy(); //destroy the object
}
}
}

if characters < message_length
{
character_old = characters
characters += increase_speed
message_draw = string_copy(message[message_current],0,characters)
if round(characters) > character_old stop_and_sound(<sd_voice_blip>)
}

then I created a draw event with the code....

draw_text(x, y, message_draw); //draw the text at the coordinates
draw_set_color(c_white);

....I got the some errors in the step event saying unknown symbol in if round(characters) > character_old stop_and_sound(<sd_voice_blip>) which I then made (sd_voice_blip), and then got this error

Variable obj_text.increase_speed(100011, -2147483648) not set before reading it.
at gml_Object_obj_text_StepNormalEvent_1 (line 23) - characters += increase_speed.

Not sure what to do next. Thanks for the reply, and any additional help.

Last modified on May 25, 2016 by Odhrain @Odhrain

over 9 years ago
In response to %{ user }@Odhrain

Stop_and_sound code needs to go into a script named stop_and_sound. The code under step must go in the Step event, and character_old should come after characters in the create event.

over 9 years ago
In response to %{ user }@Odhrain

Edited my reply because I couldn't put a new one in for some reason, thanks for you continued help! :)