"Pulp Mill": a Pulp-to-Lua converter

I made a python script that converts pulp .json files into lua projects. This is primarily to improve performance, but it also allows you to enhance your pulp projects with lua-only features not normally acessible in pulp. You could, for example, double the resolution of your game to have 16x16 tiles.

Pulp Mill available here.

You will need to download Python3 in order to use this.

The lua code is intended to be a 100% accurate simulation of the pulp runtime. However, there are still some bugs being worked out, so you had better verify that everything works the same. For example, text pagination (for say, ask, etc.) is still a little buggy, and that is because I did a bad job coding the paginate function (you are welcome to contribute a better one!).

I have verified the game works approximately correctly as far as I can tell on the following projects:

The following games are completely broken:

You are all welcome to join in and help verify / report issues on more transpiled pulp games.

10 Likes

Amazing work @NaOH.
And nice cute name!

1 Like

Adding this to the wiki Immediatly. It's very important to have a tool like this. Great job!

2 Likes

Very nice! I may try this out.

Where is this wiki?

https://playdate-wiki.com/wiki/Main_Page

There ya go!

2 Likes

super excited for this

  1. This is amazing. I compiled both my game and a test-script doing full-page draws, and both ran well with significant performance increases.

  2. There appears to be a bug with certain enormous label statements. Embedding 375 identical tiles works well everywhere except Pulpmill, where it throws an overflow error. I'm thinking it may be something to do with handling extremely long strings, but I couldn't say for sure.

Obviously it would be nice to use pulpmill on full-screen labels, since without pulpmill they drop the FPS by 5 frames even with the efficiency of labelling over drawing.

I'm attaching a test project which shows this. This project runs at 5 fps on device, but gives an error when running through pulpmill.
Fadein-labelPOC.zip (3.9 KB)
(hit B to start full-screen label, hit A to start 5x3 label)

Edit: a bug related to mimic -

I found another bug that could be causing widespread (minor) issues:

It looks like "any" runs after the corresponding event rather than before, and the variable __evname can be altered by other functions before "any" runs, causing "mimic" to run for the wrong event.

Full bug description

I noticed that one of my "mimic" functions was not running properly. I had "rooma" mimic "tilea" for "any". On "enter" I had "tilea" tell "rooma" to call "enterstats."

This should have triggered "rooma" to

  1. mimic "tilea" for event "enterstats" then
  2. run "enterstats"

Instead, it triggered "rooma" to

  1. run "enterstats"
  2. mimic "tilea" for event "now" (an unrelated event in my code).

In my code, "now" is an event that is never called on "tilea" or "rooma", so it seems like __evname got rewritten somewhere. I verified this by adding a variable "coronavitae," setting it to "__evname" the moment that "tilea" tells "rooma" to call "enterstats," then rewritting rooma's mimic code to run for "__evname" "any" and "coronavitae", instead of just "__evname" and "any".

Using a new variable instead of __evname fixed the problem, so I'm pretty sure the __evname variable is vulnerable to being rewritten for mimic functions, causing them to run events other than the ones they are supposed to.

Another bugreport:

If you have a variable in your code that is never read, then it is not initialized in the code created by pulpmill and causes an error when run.

Obviously you should not have variables that are never read, but for example I accidentally left a variable called "testvar" in the script that increased every time I called certain draw functions. At one point I logged this variable for debugging, then I deleted the log function.

At the vary least, users should know (maybe by finding this post) that this is the cause of uninitialized variable errors in pulpmill, but it would also be nice if this were fixed (assuming it's easy).

I've got a super-clean bug report for a demo that runs on Playdate but crashes the playdate if run through pulpmill. It seems to indicate that, in this program, "crop" is causing a system crash when run through pulpmill.

It only has 134 lines of code, all in player (embedded below), except that the game script also sets crop to 7.5, 2.5, 9, 9.

Running the pulpmilled game causes the playdate/simulator to crash, with error:

Update error: pulp.lua:1127: attempt to index a nil value (field '?')
stack traceback:
	pulp.lua:1127: in function <pulp.lua:991>

which correspond to:

        for x = cropl,cropr do
            for y = cropu,cropd do
                local tilei = roomtiles[y][x]

and

function playdate.update()

respectively.

Clearing the Game script (which basically only contained crop) caused pulpmill to run normally. The pulp .jsons and compiled outputs of the broken and fixed versions are attached.

Full code:

Full pulpscript of game except Game script: Player
on draw do
	if rick==1 then
		initx = 9
		initx -= shiftleft
		inity = 4
		call "drawrick"
		initx = 15
		inity = 4
		initx -= shiftleft
		draw "white" at initx,inity
		log "drawing player at x,{inity}"
		inity++
		log "drawing player at x,{inity}"
		draw "white" at initx,inity
		inity++
		log "drawing player at x,{inity}"
		draw "white" at initx,inity
		inity++
		log "drawing player at x,{inity}"
		draw "white" at initx,inity
		inity++
		log "drawing player at x,{inity}"
		draw "white" at initx,inity
		inity++
		log "drawing player at x,{inity}"
		draw "white" at initx,inity
		initx = 16
		inity = 4
		initx -= shiftleft
		call "drawrick"
		if shiftleft>=7 then
			shiftleft = 0
		else
			shiftleft += 0.125
		end
		
	else
		initx = 9
		inity = 4
		call "drawrick"
	end
	
	fill "black" at 4,32,64,48
	fill "black" at 124,32,64,48
end

on drawrick do
	draw "Rick 1" at initx,inity
	initx++
	draw "Rick 2" at initx,inity
	initx++
	draw "Rick 3" at initx,inity
	initx++
	draw "Rick 4" at initx,inity
	initx++
	draw "Rick 5" at initx,inity
	initx++
	draw "Rick 6" at initx,inity
	initx -= 5
	inity++
	draw "Rick 7" at initx,inity
	initx++
	draw "Rick 8" at initx,inity
	initx++
	draw "Rick 9" at initx,inity
	initx++
	draw "Rick 10" at initx,inity
	initx++
	draw "Rick 11" at initx,inity
	initx++
	draw "Rick 12" at initx,inity
	initx -= 5
	inity++
	draw "Rick 13" at initx,inity
	initx++
	draw "Rick 14" at initx,inity
	initx++
	draw "Rick 15" at initx,inity
	initx++
	draw "Rick 16" at initx,inity
	initx++
	draw "Rick 17" at initx,inity
	initx++
	draw "Rick 18" at initx,inity
	initx -= 5
	inity++
	draw "Rick 19" at initx,inity
	initx++
	draw "Rick 20" at initx,inity
	initx++
	draw "Rick 21" at initx,inity
	initx++
	draw "Rick 22" at initx,inity
	initx++
	draw "Rick 23" at initx,inity
	initx++
	draw "Rick 24" at initx,inity
	initx -= 5
	inity++
	draw "Rick 25" at initx,inity
	initx++
	draw "Rick 26" at initx,inity
	initx++
	draw "Rick 27" at initx,inity
	initx++
	draw "Rick 28" at initx,inity
	initx++
	draw "Rick 29" at initx,inity
	initx++
	draw "Rick 30" at initx,inity
	initx -= 5
	inity++
	draw "Rick 31" at initx,inity
	initx++
	draw "Rick 32" at initx,inity
	initx++
	draw "Rick 33" at initx,inity
	initx++
	draw "Rick 34" at initx,inity
	initx++
	draw "Rick 35" at initx,inity
	initx++
	draw "Rick 36" at initx,inity
	
end

on confirm do
	if rick==0 then
		rick = 1
	else
		rick = 0
	end
	log "rick={rick}"
end
'Game' pulpscript which needed to be removed
on load do
	cropx = 7.5
	cropy = 2.5
	crop to cropx,cropy,9,9
	restore
	
	if hasPlayed==1 then
		log "welcome back!"
	else
		log "nice to meet you."
	end
	
	hasPlayed = 1
	store "hasPlayed"
end

on finish do
	log "who are you again?"
	// toss
end

Starv-broken and fixed.zip (75.9 KB)