Demo builds and folder/file structures

Hi! I was wondering if there were best practices around creating a demo version of a game that shares pretty much all of it's assets and files with the main game. Ideally without copy and pasting, and the demo version would live in the same repo.

I wonder about whether this is possible with the playdate SDK?

So here's the scenario:
You have a game with all its files in /source.

Option A (may be the only option besides copy & pasting):
Have a file named main-demo.lua and simply target that during compile. But this means that both the demo & game will have the same game art and pdxinfo. Which might be ok, i'm not really sure how that affects the experience to the user. Install the demo, then later decides to get the full game. I assume this option would mean the main game would install in place of the demo. Is that right?

I've tried this method and it works.

  • Pros
    • Simple & clean
    • No copy & pasting and having to maintain different copies.
  • Cons
    • Can't easily choose what is included in demo version so,
    • the demo build will roughly the same size as the main game.

Option B: Have a /demo-source folder next to source and import the files as needed.
This would be my preferred way, but I haven't found a way to import files outside of the source folder that is passed to pdc.

In other words from a root folder /demo-source I can't, for example: import '../source/some-asset/asset.lua'. I've even tried symlink on osx but it didn't seem to make a difference

Is there a way to do this and I've just missed it?

The way I did it is to have one game that is clever enough to run with any amount of assets (demo or full).

My default build is the full game, and I have a script (called on demand from my make file) to duplicate the "full" .pdx and delete certain files to produce the "demo" .pdx. The binary is the same in both.

I thought this approach was OK for an early demo. The full game changed afterwards and broke compatibility with the demo, but I see this as a feature not a problem as I don't want people sharing final "full" assets for use in the old demo.

1 Like

Yes, a script to strip levels from the pdx that are not needed for the demo is what I would do as well. Remember a pdx is just a regular folder.

You can use the file and listdirectory functions to count the number of available levels. Make sure to properly test this.

1 Like

Thank you both for the input! I hadn't considered the option of modifying the pdx. It's good to know that modifying the contents won't mess with any sort of checksum or something.

Does give me food for thought, but not sure how useful it'll be for my specific game since there's really only one level and not much else to "trim".

Thanks again! I will continue to tinker and see if I come up with something elegant, if so I will post an update.

Actually speaking of makefiles...

Does anyone know of a way to retrieve and use variables from the pdxfile?

I would love to automatically include the version and build numbers in the output filename, but haven't quite figured out how.

See Question re pdxinfo buildNumber and sideloaded updates - #5 by zothynine

Or similar

1 Like

Thanks @matt! I will try and add that into my makefile.

I also have an update on another method of doing a demo build. I think this one will suite my style of game well, hopefully it'll work for others too.

There's a --main or -m (for short) flag for pdc where you can change the target main.lua file to something else.

I point that to a main-demo.lua which basically sets a global variable IS_DEMO = true and then importing main.lua

(There's probably a way to set this flag via env variables but I couldn't get that to work and it looks like argv is only meant for access in simulator?)

main-demo.lua source:

-- THIS IS THE ENTRY TO THE DEMO BUILD
-- SET THE DEMO FLAG
IS_DEMO = true
print("DEMO BUILD!") -- for visibility in the console
import "main"

That's pretty much it! Then in my other files I simply add:

if not IS_DEMO then  
...
end
-- or 
if IS_DEMO then
...
end

in some of my logic to alter behavior.

You could even have a completely different main file if you wanted to with it's own update function. Or entirely different logic if you wanted to!


Here's what my make script looks like this for the demo build ( change the file name (main-demo.lua) to whatever you end up naming it) it will append Demo to the filename so it builds separate from the main game.

# DEMO
compile_demo: 
	"$(SDKBIN)/pdc" -k --main 'source/main-demo.lua' '$(GAME) Demo.pdx'

You could even do a combination of this method and the methods mentioned above.

I hope this helps someone else too. Cheers!

I wrote my own build version script but I can't find it here and don't have it to hand. Hmm.

Your demo technique is interesting, but watch out: somebody could run it and change the value of IS_DEMO at runtime, then because all the game logic and assets are there they'll be in the full version.

(There is no real compilation going on, but rather byte code generation, and the byte code product of Lua code can be reverse engineered)

Making sure IS_DEMO is a const would help. But it's more complicated than just that.

Ahh dang it, I knew there had to be some downsides didn't realize they'd be that big lol. Thanks again for the info! I'm still pretty new to lua in general so still have lots to learn.

fwiw I did try making a global const, but looks like it only works for local variables? Though perhaps I did it the wrong way.

-- this didn't work, and errors during build
IS_DEMO <const> = true

-- this didn't work either 
_G.IS_DEMO <const> = true

--- this seemed ok, but to the imported main.lua it reads as nil
local IS_DEMO <const> = true

wow am I out of practice with Lua.

Yeah, not sure it's going to be possible to make that a const.

:smiley: no worries, I appreciate all the help!

1 Like