excel

Disyllabic roots in greyfolk language, 2: creating the database

In my end of February report, I mentioned that I was able to create a database to help me create disyllabic roots while preserving Hamming distance. One big part of that was devising a macro for Excel that would do the following:

  • Range A is a bank of possible (according to the rules of my language) disyllabic roots. I generated this using Zompist’s Gen.
  • Range B is where I input the roots I have chosen.
  • Range C is a bank of roots that conflict with the roots in Range B. I also generated this using Gen with some really roundabout tricks.
  • Rule 1: If a cell appears in Range A and Range C, it is highlighted yellow.
  • Rule 2: If a cell appears in Range A and Range B, it is highlighted green.
  • Rule 3: If a cell appears in Range B more than twice, it is highlighted red.
  • Rule 4: If I a cell appears in Range B and Range C, it is highlighted red.
  • Rule 5: Otherwise, a cell should not be highlighted.

Thus, any white cells in Range A were roots that could still be used because they didn’t conflict with anything else. Even though the highlighting was all done by a macro, there was still a significant portion of manual work that took a few hours. Much more time went into figuring out how to get the most efficient set of disyllabic roots. By that, I mean that I had to figure out how to get as many roots as possible that didn’t conflict with each other from the total bank of possible roots. It always comes back to Hamming distance!

Macro for disyllabic roots database
Sub HighlightDuplicates()

    'Keyboard Shortcut: Ctrl+Shift+D

    Application.ScreenUpdating = False

    Dim ws As Worksheet, t0 As Single, t1 As Single
    Set ws = ThisWorkbook.Sheets("Database")
    t0 = Timer

    'Rule 5: Otherwise, a cell should not be highlighted.
    ws.cells.Interior.Color = xlNone

    Const RANGE_A As String = "B1:E2300"
    Const RANGE_B As String = "G1:G2300"
    Const RANGE_C As String = "I1:AH2300"

    Dim dictA As Object, dictB As Object, dictC As Object
    Set dictA = CreateObject("Scripting.Dictionary")
    Set dictB = CreateObject("Scripting.Dictionary")
    Set dictC = CreateObject("Scripting.Dictionary")

    Call buildDict(dictA, ws.range(RANGE_A))
    Call buildDict(dictB, ws.range(RANGE_B))
    Call buildDict(dictC, ws.range(RANGE_C))

    'Rule 1: If a cell appears in Range A and Range C,
    'I want them highlighted yellow.
    'Rule 2: Then, if a cell appears in Range A and Range B,
    'I want them highlighted green.
    
    Dim cell As range, key As String
    For Each cell In ws.range(RANGE_A)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictC.exists(key) Then cell.Interior.Color = vbYellow
            If dictB.exists(key) Then cell.Interior.Color = vbGreen
        End If
    Next

    For Each cell In ws.range(RANGE_C)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictA.exists(key) Then cell.Interior.Color = vbYellow
        End If
    Next

    For Each cell In ws.range(RANGE_B)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictA.exists(key) Then cell.Interior.Color = vbGreen
        End If
    Next

    'Rule 3: Then, if a cell appears in Range B more than twice,
    'I want them highlighted red.
    'Rule 4: Then, if a cell appears in Range B and Range C,
    'I want them highlighted red.

    For Each cell In ws.range(RANGE_B)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictB.exists(key) Then
                If dictB.Item(key) > 1 Then
                    cell.Interior.Color = vbRed
                End If
            End If
        End If
    Next

    For Each cell In ws.range(RANGE_B)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictC.exists(key) Then
                If dictC.Item(key) > 0 Then
                    cell.Interior.Color = vbRed
                End If
            End If
        End If
    Next

    For Each cell In ws.range(RANGE_C)
        If Len(cell.Value) > 0 Then
            key = CStr(cell.Value)
            If dictB.exists(key) Then
                If dictC.Item(key) > 0 Then
                    cell.Interior.Color = vbRed
                End If
            End If
        End If
    Next
    
    t1 = Timer
    
    'MsgBox "Completed in " & Int(t1 - t0) & " seconds"

    Application.ScreenUpdating = True

End Sub

You can click on the plus icon or the name to expand that section to see the macro. It’s a biggun, so I decided that it was better to default to it being collapsed and not immediately assaulting any eyeballs.

Now, to even generate Range A, as I said, I used Zompist’s Gen tool. Making rules to create all possible disyllabic roots in greyfolk language was easy.

Categories for all possible disyllabic roots
C=mnptksylh
S=yl
A=a
T=mnl

Rewrite rules for all possible disyllabic roots
hl|h
hy|h
lh|l
ll|l
yy|y
mh|m
mm|m
nh|n
nn|n

Syllable types for all possible disyllabic roots
CACA
CASA
SACA
SASA

CSACA
CSASA
CATCA
CATSA
SATCA
SATSA
CACSA
CACAT
CASAT
SACSA
SACAT
SASAT

CSATCA
CSATSA
CACSAT
SACSAT
CSACSA
CSACAT
CSASAT
CATCSA
CATCAT
CATSAT
SATCSA
SATCAT
SATSAT

CSACSAT
CATCSAT
SATCSAT
CSATCSA
CSATCAT
CSATSAT

Of course, the output type was for all possible syllables.

To generate Range C in Gen, I had to figure out some really roundabout tricks, and, even then, I still had to generate it one chunk at a time. Think of each disyllabic root as a STUVWXYZ map where each letter corresponds to a phoneme. S and W are the first position of their respective syllable and can be «m, n, p, t, k, s, y, l, h». T and X are the second position of their respective syllable and can be «y, l» or ‘-‘. U and Y are the third position of their respective syllable, but, when working with roots, both of them are always «a». Finally, V and Z are the fourth position of their respective syllable and can be «m, n, l» or ‘-‘. For example, the root «myaman» would be ‘mya-m-an’ because the fourth position of the first syllable and the second position of the second syllable are open. If you look at the above Gen rules, it should be clear that STUVWXYZ is essentially CSATCSAT.

Then, to figure out the roots that wouldn’t be compatible with other roots, which is what Range C is, I had to switch the process for ABCDEFGH. Each letter corresponds to the letter in the same position in STUVWXYZ, but each letter of ABCDEFGH take the values of phonemes that do not have enough Hamming distance from those in STUVWXYZ. So, if S=m, then A=mnp because «m, n, p» conflict with «m» according to my Hamming distance parameters. Oh, I also set a meaningless Q=xxxxxx so I could see the separation between ABCDEFGH and STUVWXYZ at a glance.

Categories for «myaman»
A=mnp
B=yl
C=a
D=mnl
E=mnp
F=yl
G=a
H=mnl
Q=xxxxxx
S=m
T=y
U=a
V=-
W=m
X=-
Y=a
Z=n

Syllable types for conflicting roots
ATUVWXYZ
SBUVWXYZ
STCVWXYZ
STUDWXYZ
STUVEXYZ
STUVWFYZ
STUVWXYH

Of course, the output type was for all possible syllables.

Output for «myaman»
mla-m-an
mya-m-al
mya-m-am
mya-m-an
mya-mlan
mya-myan
mya-n-an
mya-p-an
myalm-an
myamm-an
myanm-an
nya-m-an
pya-m-an

From there, it was a matter of removing the dashes. However, an interesting question popped back up. What is the Hamming distance between something like ‘mya-m-an’ and ‘myamm-an’? What about ‘myamh-an’? I went ahead and decided that they were all equivalent (which is actually why ‘myamh-an’ doesn’t generate as I had already taken that into consideration). Because it was a problem I had faced before, I knew how to deal with it. However, another question popped up. What is the Hamming distance between something like ‘myamy-a-‘ and ‘mya-mya-‘? Same thing, I ended up deciding that they were the same as well. Though, they do have enough Hamming distance between them. I just wanted to simplify things and continue to get rid of roots that sounded too alike.

However, I did get some conflicts that weren’t actually conflicts. On the surface, «katya» and «kalya» might seem like they conflict because «t» and «l» conflict in the same position. However, «katya» is «k-a-tya-» (pronounced /ka.tja/) and «kalya» is «k-aly-a-» (pronounced /kal.ja/). So, the «t» and the «l» aren’t actually in conflicting positions.

Anyway, I had to run every planned disyllabic root through Gen, put the output in the database, then format it and remove dashes. It took quite a bit of time to do that manually for over 166 roots—yes, it was more than 166 because I had to add other altered roots at the cost of others after having already processed roots that had to be removed. More than anything else, it was just really repetitive and boring, and I pushed myself so hard during this entire process that I ended up really fried, stressed, and anxious. Oops!

In the next part, I will finally reveal the disyllabic roots!

End of February report

My arm has recovered quite a bit! It’s functional, but it’s not quite back to the pain-free strength that it had before. My infection (or, perhaps, the symptoms left behind by the infection) hasn’t quite resolved yet, however. I went through another round of antibiotics and painkillers, and I am waiting to see if the discomfort and pain continue to go away or… if they don’t.

Also, the GURPS stuff report has changed to RPG stuff report because I foresee talking about other RPGs as well. I have a couple in mind, but I don’t want to jump the gun.

Conlang stuff report

Even as my arm was still not doing so hot, I was still working hard on my conlang. With help from the internet in creating a macro for Excel, I got a nice database of disyllabic roots running.

  • Range A is a bank of possible (according to the rules of my language) disyllabic roots. I generated this using Zompist’s Gen.
  • Range B is where I input the roots I have chosen.
  • Range C is a bank of roots that conflict with the roots in Range B. I also generated this using Gen with some really roundabout tricks.
  • Rule 1: If a cell appears in Range A and Range C, it is highlighted yellow.
  • Rule 2: If a cell appears in Range A and Range B, it is highlighted green.
  • Rule 3: If a cell appears in Range B more than twice, it is highlighted red.
  • Rule 4: If I a cell appears in Range B and Range C, it is highlighted red.
  • Rule 5: Otherwise, a cell should not be highlighted.

Thus, any white cells in Range A were roots that could still be used because they didn’t conflict with anything else. Even though the highlighting was all done by a macro, there was still a significant portion of manual work that took a few hours. Much more time went into figuring out how to get the most efficient set of disyllabic roots. By that, I mean that I had to figure out how to get as many roots as possible that didn’t conflict with each other from the total bank of possible roots. It always comes back to Hamming Distance!

I’ll share much more about this soon.

RPG stuff report

Over the past couple of weeks, I have started to work on a very loose and flexible magic system that I think is good enough. Ritual Path Magic is loose and flexible, but it is slow and uses a whole new system. Divine Favor has flexibility built in with its prayer system, but it’s way too expensive and it doesn’t focus on flexibility. Sorcery has the same advantages and disadvantages of Divine Favor, though I do like it a bunch more. I based my system off of Wildcard Powers from GURPS Supers, but I’ll talk about it in much more detail soon.

Two more things. First, I just want to say that GURPS Transhuman Space is really cool. Second, I’m a bit late, but I just discovered The Path of Cunning, which is a new (and free!) fan-zine for GURPS content that is doing a good job at slowly filling the void left behind by the discontinuation of Pyramid #3. I’d love to hop on that in its infancy and review the zines as they come out. And—who knows—maybe even try to submit something one of these days. In fact, maybe that flexible magic system is just the thing.

Writing stuff report

I wrote a couple of short vignettes for fun. I dove into some stuff about Gnosticism for inspiration. I also toyed around with some new ideas for my main stories. That’s about it.

Added a site icon

It’s something small—literally quite small—, but I did it. It took a lot of trial and error—perhaps more than it should’ve taken. All I used was Excel and Paint.net.

It’s a bit squishy-squashed, but that’s the Greyfolk word «pe», which is the first-person singular pronoun, translated into English as “I” or “me”, depending on the context.

Furthermore, it almost ended up being «pom», which is a verb that can be translated into English as “to love”.

Honestly, I’d prefer to «pom» to «pe», but I think «pe» looks a lot better as a 16×16 icon. But I might change my mind.