Showing posts with label technology. Show all posts
Showing posts with label technology. Show all posts

2021-03-10

Making Faces in nanDECK

The other day I was working on a game in Screentop, and decided that I wanted the dice I had in it to be spotty dice rather than the digit dice that are the default. All this requires is uploading an image which shows the required faces (this works for any custom faces). If my image has a transparent background, then you can set the fill colour for the die to be whatever you want and then use the same image for a range of different coloured dice.

I figured that nanDECK would be an effective way of constructing the image, and it didn't take long to make the script. I thought I would share my script here as a kinda worked example. I'll break the sections of the script down with discussion about what each section does.

So, here goes...

BORDER=RECTANGLE,#000000,0,MARKDOT
PAGE=21,29.7,PORTRAIT,HV

These lines are just boilerplate stuff that I put at the top of all my scripts, formatting a page for printing or creating a PDF at A4 size, with crop lines added. It's not necessary for what I am doing here, but I left them in anyway.

DPI=200
CARDSIZE=5,5

The next bit of the boilerplate, but a bit that I modify as necessary. My usual card size is 6.3 x 8.9 cm for poker-sized cards, but I want squares this time. As I am just making an image, the size doesn't really matter, so 5 cm square was just a convenient number.

[DotColour]=#000000
[CircleColour]=#999999
[TransparencyColour]=#ffbbff

It can be useful to define variables rather than using numbers in the guts of the code. Specifically the [DotColour] one meant that I could run the script once to generate an image with black dots, and then change the value (to #ffffff) in order to run again and output white dots.

The [TransparencyColour] is helpful because in nanDECK you can define a specific colour to be replaced by transparency in an output PNG file. As long as you select a colour you don't want to use in the actual image (I'm using a pink here), all is good.

RECTANGLE=,0,0,100%,100%,[TransparencyColour],[TransparencyColour]

So this is just filling the "card" with a solid background field of the colour I selected for the transparency.

ELLIPSE="1,3,5",2,2,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="4,5,6",0.5,0.5,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="4,5,6",3.5,3.5,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="2,3,4,5,6",3.5,0.5,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="2,3,4,5,6",0.5,3.5,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="6",0.5,2,1,1,[CircleColour],[DotColour],0.02
ELLIPSE="6",3.5,2,1,1,[CircleColour],[DotColour],0.02

That's the guts of it. You can look at a standard spotted die face as having seven locations where spots can exist, and each spot is present on some faces, so this sort of arrangement does the job.

It's worth noting that this is just outputting images for faces, without any thought about where on the die those faces are placed. For instance, the standard die arrangement of opposite faces adding up to seven is not covered here, but at present, Screentop appears to simply treat a die as a randomiser, with no physical analogue, so this point is irrelevant for my current use case.

DISPLAY="dottydice.png",1,6,3,,[TransparencyColour]

And that last line outputs the six faces to a single PNG image, three "cards" wide, converting the colour we specified earlier to transparency.

And here's the output:

Black on transparency. Feel free to take and use if it is of any use to you. CC0 v1.0

And, as an alternative, re-running the script with the white version of [CircleColour] gives:

White on transparency. Feel free to take and use if it is of any use to you. CC0 v1.0

I don't know if this sort of thing is helpful or interesting, but here it is anyway. 


2021-02-27

From Spreadsheet to Screentop via nanDECK

 I have an old card game project that has been languishing without attention for a few years with the working title Monster Invasion, which was a solitaire game (which I could probably make into a cooperative multiplayer game) that I used to enjoy playing back in the day. I recently decided to give it a look again and see what I can do with it, which gives me a perfect opportunity for me to demonstrate my current workflow for building a virtual prototype on Screentop.gg, a 2D virtual tabletop that I am learning to love, with the wonderful nanDECK for creating the card graphics.

I'm not going to go into every detail of how this all works, but hopefully will give you a few pointers if you want to work in this way.

The state of the game as I got back to it was a nanDECK script taking data from a CSV file. This was last worked on in 2017, and I've developed my way of working quite a lot since then (even ignoring the shift to virtual prototypes), so my first task was to update the data source. nanDECK is capable of drawing data directly from a Google spreadsheet, as long as the spreadsheet has been shared appropriately (there are details of how to do this in the nanDECK documentation), so I imported the dats, made a couple of tweaks, and shared as appropriate.

My card data in a Google spreadsheet, all ready to go.

If you can see the image of the spreadsheet above, there are probably a couple of things to draw your attention to or at least explain. At the top right is the number 55; this is calculated as the sum of the values in the "Quantity" column, and I find it helpful to have something like that for my reference as I make changes. At the bottom is a line for a card back and a set of nine "blank" cards; this is to help me later build a card image for import to Screentop.gg later on. When I am working with physical cards it is convenient to work in multiples of nine, which is a good number to print on a single A4 page, and coincides nicely with a standard deck size for manufacturing purposes if we get that far. On Screentop I find it convenient to have sets of 55 cards in a five-by-eleven grid, which allows me that same number of cards plus a slot to use as a card back which, if I pad appropriately with blanks, I can make always appear in the last slot of the image.

As an aside, a similar strategy works well for Tabletop Simulator, though typically you use the final slot for a "blanked out" card face. Tabletopia required individual images, which are also easy to set up using the same tool chain, but I'm not doing that today.

As you may know, nanDECK is a system for building cards (and other game components) using a scripting language that allows you to have huge amounts of control if you want it. There is a "visual" mode to the system that I have never spent any real time trying to use, and I gather that works well for some people, but I can't offer advice on this. 

OK, so the nanDECK script. I'm not going to show you the whole thing here, but can show you some of the bits that are relevant...

The first part of my nanDECK script.

A few comments on this first part of the script, assuming you can see the image above...

The first few lines are there primarily for when I want to output a printable PDF document, but an important point here is line 3, which defines 'DPI=140'. This defines the resolution, and thus the file size of the output. Normally for printing purposes you might want to work with about 300 DPI (dots per inch) to get a high quality output, but for virtual prototypes you may have file size limitations, and so may need to reduce the resolution. In the case of Screentop, the limit is an image size of 4096x4096 pixels, and to fit within that constraint I need to either reduce the resolution to about 140 DPI as I have done here, or go for a slightly higher resolution and make the output image a more square shape than I have done.

Line 9 is the link to my spreadsheet. nanDECK is smart enough to recognise that this jumble of characters is a Google spreadsheet ID and acts accordingly.

Lines 11 to 20 define icon images to associate with the letters I am using in the "icons" columns of my spreadsheet. 

Lines 22 and 23 (and the earlier line 6) are a habit I got into long ago of printing a version number onto prototype cards so I can tell that I am using the set of cards that I mean to use -- and this can be important with a game that I am iterating over and revising rapidly.

Then at the bottom I start off the definitions of the actual cards, using an IF structure to select options according to the "CardType" column in the spreadsheet.

After skipping a few lines, here's the end of the nanDECK script.

Towards the end you can see the card back being made by drawing a coloured rectangle at line 55. I have got into the habit of using two-colour radial gradients like this (with various colour mixes) for place-holder card backs, sometimes with text over the top if that seems appropriate. I find them sufficiently pleasing for minimal effort.

Finally, line 60 is where the magic happens, outputting a single image file for cards 1 to 55 (i.e. all of them), arranged in a grid 11 cards wide. 

So, if I validate and build this script, I end up with a nice image of all my cards...

And here we have the output of my script: a big image ready for upload.

So, on to the next tool in the chain: Screentop.gg...

Screentop is a bit of a work-in-progress at the moment, but it is very useful as it stands and is being actively developed and supported. I like it because it does enough for most of the projects I am working on, and is far less demanding on computer resources than its 3D cousins, and just about anyone can join a game from their web browser if I send them a link. On the other hand, there are a few odd quirks to get past. One of these scares off a lot of people: rather than having intricate GUI elements, several of the tasks you may want to do will require using the "bulk editing" system, which uses a programming language and you need to type code into a window to make your changes. Back on the positives though, there is very useful documentation, which provides bits of code that you can just copy and paste as appropriate for most situations, and this makes it potentially rather less scary than the likes of nanDECK.

The Beginner's Tutorial for Screentop takes you through the steps of creating a deck of playing cards, and you can simply follow that, substituting your personal deck image (as I have just created) instead of the sample one they provide.  The tutorial only uses the necessary cards from the image, but I usually make cards for everything, including the blank cards, which allows for more flexibility and cleverness later, which I will go into shortly.

So, just a few minutes of work and I have a pile of cards, some of which are blank...

Cards now up on Screentop.gg - ready to go!

So the game is more or less playable now in it's present state, though I need some way of tracking two scores: power and threat. I can do that by adding some tokens, adding a little score board and a couple of tokens, or using one of the built-in component types, a counter. Or doing the tracking offline with physical components too, I suppose. I can leave that as an exercise to the reader, as I wanted to just show one little extra thing.

The way Screentop handles graphical assets is that you can upload an image and then divide it into a certain number of rows and columns, which are then indexable sub-assets. This is useful for handling entire decks of cards together or potentially other components like custom dice. (Tabletop Simulator is similar in this respect.) In this case, what this means is that once you have set up a deck of cards (or similar set of components), you can, with just a few clicks, upload a replacement for the graphical asset and it will instantly update the cards.

So, if I want to change the background colour of the boss cards, that's one line in the nanDECK script, and replace the blank cards with a pointless message, that's a quick edit of the spreadsheet. A couple of clicks in nanDECK regenerates the graphic, which I can then upload.

Uploading a fresh asset in Screentop is really quick and easy

And, ta-da!...

An updated version of the game in just a couple of minutes.

This updated version is actually the same session as the one in the previous screenshot, having refreshed the page a few times -- this behaviour is brilliant, but doesn't seem to always work first time. A fresh session would (and did) update the cards straight away.

Anyway, now we're all in place, I can start looking at the game and decide what I want to do with it. Card updates will be absolutely trivial with the basics now in place, so we'll see what inspiration comes. 

I'm not sure how interesting or useful this sort of post is, but I guess if you found it really boring you won't have got to this point anyway. Thanks for reading!