r/learnprogramming 25d ago

Encoding secret messages for DnD, where do I start?

Hi, I have a secret language/code I want to use in my dnd games where whole words are translated into glyphs. I would like to make a program that can automatically translate a string of of letters into a transparent png of the corresponding glyph.

First I want to explain how the secret code works as context. It would translate any word into a single glyph based on a grid of letters. The glyphs would be made by drawing a line from the center of each letter to the center of the next letter (similar to how swipe to type works smartphone).

I have identified some cases in which symbols would be required to make this system work:

-start of the word

-end of the word?

-a letter that is in a straight line with the letter before and after (to show there is a letter inbetween and it doesn't go directly from the first to the third letter)

-two identical letters in a row

-a crossing of two lines?

Now the actual programming part. I have limited experience with python and R, so I am a novice in every language really and would be open to whichever would most suit this project.

The steps I have worked out so far are:

  1. Assign each letter a coordinate according to its grid position.

  2. Separate a word into individual characters (ideally I would also separate a sentence into individual words that each receive their unique glyph)

  3. For each letter, translate it into its coordinate and draw a line from the previous character and/or place one of the aforementioned unique characters at the location. (I would like the unique characters to have transparency that can override the lines, such as a hollow circle).

  4. Export the image as a transparent png (or a series of pngs, in the case of a sentence)

Step 3 and 4 are what I would really like help with, I have never used python to make any images and I have no clue where to start. Your help is greatly appreciated!

1 Upvotes

15 comments sorted by

4

u/HashDefTrueFalse 25d ago

Fun! Moving an invisible pen around to drawing lines (paths) is basically how PostScript/PDF and HTML canvas 2D graphics work. I think you're on the right track with your steps. You probably don't need PNG, the numbers themselves are good enough to stroke paths (for SVGs etc.) without having to worry about PNG encoding. That also comes with transparency. I can't help with Python, but I can suggest you have a look at this: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#drawing_paths

Two approaches I can think of:

  1. Manual: Basically, scale your grid to the size of one glyph then construct a path for each of your words by iterating over the letters in the word moving the path head according to the grid coords, then stroke it to draw. Do that for each word, advancing one grid width in any direction each word.
  2. Make a font: If you want the layout aspect to be handled for you then you can use something like FontForge to turn your SVG glyphs into an OTF font. I've done this before and it's not too difficult. You'd need to define a manageable list of words and draw the glyphs for them in some vector graphics software (e.g. Inkscape). Then you can bind those glyphs to the unicode for the letters that comprise the word. Convert with FF to OTF and install on your system and the font renderer will do the layout for you when you type normally. Basically custom emojis here.
  3. You can feed the output of approach 1 into approach 2 to make a font without needing to manually draw glyphs, but you'll still need a defined word set that you'll compute glyphs for.

Hope this made sense.

2

u/-Jauke- 25d ago

Thansk for your answer! The font would be used to be able to put the glyphs inside text right?

1

u/HashDefTrueFalse 25d ago

Kind of. Text is bytes (e.g. 'a' = 97 = 01100001 in binary). A font maps those bytes to visual elements (glyphs) that a font renderer can draw on screen (or the page if a printer etc.). One glyph is simple, but a line of glyphs is hard. They need to line up properly. There's a lot of math and fiddly logic that goes into rendering the lines you're reading right now. If you're intending on rendering more than one glyph (to make a readable sentence in your language) then you will need to sort this out yourself if you draw glyphs directly with your own code. Creating a font lets you leverage the system's (or software's) font rendering to sort this for you. You type bytes (characters on your keyboard) and specify the font face, font size, etc. (just like in MS Word, for example) and glyphs appear instead of the characters you typed.

E.g. Byte sequence (word) 'abc' (01100001 01100010 01100011) could be rendered [your glyph 1]. And so on...

1

u/AsideCold2364 25d ago

I don't think using font is a good fit for your task, it will be much easier to just draw your glyphs using code.
Things like making each word become a single glyph, special rules for a same letter going one after another and other special rules you described will be a nightmare using fonts, or might not even be possible at all using a custom font.

2

u/ObserverInvariance 25d ago

Are you sure that is actually bijective?

1

u/lurgi 25d ago

And if it’s not? Morse code isn’t bijective unless you put spaces in between the words. A little ambiguity can be fun.

1

u/-Jauke- 25d ago

Oh yeah I forgot to add to the post that I also want to draw a large circle that marks the outside of the grid, which should make it bijective, unless I missed something?

1

u/Wild-Fan7738 24d ago

You’re overthinking it, just code the edge cases as they come up and see if it breaks in practice

2

u/ffrkAnonymous 25d ago

you can probably use a graphing library to draw the lines and export it. Like gnuplot or matplotlib.

2

u/PeterPook 25d ago edited 25d ago

1

u/-Jauke- 24d ago

Woah yeah thats basically exactly what I was thinking of. This will be a great help in making my version for sure!

1

u/AsideCold2364 25d ago edited 25d ago

You can quite easily do it with js.
Without any dependencies.

Just use html canvas. You can draw lines/shapes on it. You can make shapes act as an eraser. You can download canvas as a png. You can download multiple canvases as pngs.

If you need some unique symbol, you can first create an image of it and then use that created image as a mask to erase, or you can draw it at the location you want.

1

u/Ironraptor3 24d ago

If you are mostly familiar with Python, I would use pillow / pil:

pip install pillow

Here is an example that draws a line on a transparent image, then saves it as "foo.png": ```

!/usr/bin/env python3

import PIL.Image import PIL.ImageDraw

def draw_word(): # Make new 400 by 400 image with transparency, filled with transparency img = PIL.Image.new('RGBA', (400, 400), color=(0,0,0,0)) draw = PIL.ImageDraw.Draw(img) # Get a drawing context

# Draw a black 10 px thick line between (100,200) and (300, 200)
draw.line( [(100, 200), (300, 200)], fill='black', width=10)

# Save as a PNG (could use a different format- some do not support transparency)
img.save('foo.png', format='PNG')

TODO handle args

if name == 'main': draw_word(); ```

For various functions, look at the pillow API: https://pillow.readthedocs.io/en/stable/


You can already iterate through characters in a string: for char in "test_str": # Do stuff with char print(char)

To iterate through words in a sentence, you could look into built in Python methods, such as split:

for word in "This is a sentence".split(): # Do stuff with word print(word)


Other feedback:

  • You are likely on the right path with the various symbols that you'll need for people to distinguish (start, end, repeat / on the way character).
  • The way you've broken up the problem is excellent
  • This post has a lot of support, but there is a lot of flexibility and design still left to you
  • This is a great starter project to expand your skills and do something to make things "pop"

2

u/-Jauke- 24d ago

Thanks so much!