Pulp how-to: Character portraits with dialogue

My Pulp game CAT WORLD has a lot of dialogue, so to bring the characters to life I wanted to add a little character portrait to the dialogue boxes. Something a bit like in the GBA game Golden Sun.

GoldenSun2Cutscene

With a little help from Neven on Discord, I was able to implement my own version. Here's how it looks:

To achieve this, I'm using the PulpScript draw function.

The character portraits are made out of a 5x5 grid.

Screenshot 2022-02-20 at 14.14.02

The outer tiles are designed to match the dialogue window. They look like this, with names like Top-left, Left, Top-right, and so on.

Screenshot 2022-02-20 at 14.25.59

The inner nine tiles are character-specific. The name format I use is {name}-p-{x}{y}. For example, here's the lumberjack portrait's top-left tile (x=1, y=1).

In terms of scripting, the longest chunk of code takes place in player. It uses PulpScript's while to loop through the x/y coordinates of the inner nine tiles.

// run this on every frame
on draw do
       
	// only draw this if active_speaker is set
	if active_speaker!=0 then
		
	        // draw the frame, starting at coordinates (3,9)
		draw "Top-left" at 3,9
		draw "Top" at 4,9
		draw "Top" at 5,9
		draw "Top" at 6,9
		draw "Top-right" at 7,9
		
		draw "Left" at 3,10
		draw "Left" at 3,11
		draw "Left" at 3,12
		
		draw "Right" at 7,10
		draw "Right" at 7,11
		draw "Right" at 7,12
		
		draw "Bottom-left" at 3,13
		draw "Bottom" at 4,13
		draw "Bottom" at 5,13
		draw "Bottom" at 6,13
		draw "Bottom-right" at 7,13
		
	        // draw all nine tiles for the active speaker's portrait
		x = 1
		while x<=3 do
			y = 1
			while y<=3 do

                   	        // generate dynamic tileId
				tileId = "{active_speaker}-p-{x}{y}"

                   	        // we want the portrait to draw at coordinates (4,10)
				localx = x
				localx += 3
				localy = y
				localy += 9
				draw tileId at localx,localy
				
				y += 1
			end
			x += 1
		end
	end
end

To display the character portrait, I set the variable active_speaker to the name of a character.

on interact do
	active_speaker = "lumberjack"
    say "Howdy! Don't see too many other cats around these parts."
end

To hide the portrait box when dialogue ends, we need to set active_speaker back to 0. We could do this manually each time, but it's easier to use the loop event in the game object.

on loop do
	// hide dialogue portrait
	active_speaker = 0
end

And there you have it! It takes a little bit of PulpScript, but the effect is almost seamless.

dialogue
(You may need to click on the above GIF to get it to animate.)

11 Likes

Wow, I really love the way this looks!!!

1 Like

This is really neat! It's got me thinking the same principle could be used to e.g. add a character name label above the dialogue box. Can this draw over the dialogue box to make any overlap or does that always get drawn on top?

Thanks @cabel! Can't wait to see it on my physical Playdate :playdate_wink:

@orkn -- Neat idea, but unfortunately the dialogue box always gets drawn on top, as far as I can tell.

Which reminds me, I noticed that the player sprite also gets drawn on top. So if the player happens to be standing in that 5x5 grid, they'll break the portrait. That could be solved by calling the hide function when the player happens to be within that range, but I haven't tried it myself yet.

2 Likes