Anxiety

Tags:

I had a job interview for a contracting role today. I think it went well and should find out soon if I got the gig. I also got my last pay check from my previous full time role.

So I spent a large chunk of the day freaking out, am I doing the right thing? Am I being foolish? If there's one thing I'm good at it's self hatred and a goodly dose of impostor syndrome. I can't take my talents or accomplishments seriously when I'm looking at them myself. It's like when there's a games convention (or just an adventure to run) before it starts I'm a ball of nerves and fear. Sometimes it gets too much and I have to call it off, but if I push through I find the other side is great.

Because, and I really need to remember this, once I'm in an interview or I'm at the table about to run a game it alls kicks in. Whilst I might not rate myself I can't help but tell the truth, I've had lots of experience in the web sphere for almost 20 years professionally and almost 30 years all told. And I've yet to encounter a technical challenges I can't take on, given a run up...

And the gaming? Once the dice start rolling and the words start flowing I remember why I love roleplaying and my ability to keep a story flowing in an interesting fashion.

Anxiety can kill. But I know I can beat it. If you need help with it know I'm here for you.

I said I'd write every day. I didn't say it would always be long. But short is better than nothing.

Valheim and lessons for RPG's

Tags:

I'll write a blog every day he said. How hard can that be?

Well if I don't mind actually talking about stuff that I think about rather than my normal trick of just leaving it in my head? Maybe not too hard.

Scimon TrollslayerSo I'd like to talk about something I mentioned on Sunday about running a game based on building a community. This is something I'd been thinking about for a while mostly from reading Numenera Destiny. But I've also recently being playing Valheim (like 3 million other people apparently). And the more I play it the more I want to distill it's gameplay into a table top game.

Here's my character in my local game, yes he's only got leather armour, in my defence I took this a couple of days ago. But he's still wearing leather armour (some of it troll hide leather) because I need more bronze. And this is one of the things about the game that I like. You character fights creatures for a few reasons but they are all ultimately linked to surviving.

You hunt boars, deer and neck (little lizard people) for food and leather. You fight Greylings and Greydwarves mostly because they try and stop you from cutting down trees for wood and you need wood, lots of wood. If you want to build a nice house to live in you're going to need to chop down a small forest.

And then there's the dungeons, why would you want to go into a burial mound that's full of skeletons? Armed skeletons that really seem to not like you. But you need to go down there, if you want to stop using a flint axe you need bronze and for that you need a smelter for smelt ore. And to make that you need to use a thing called a surtling core, it seems to be some kind of magic heat generator.

And at least in the early game the only place to find surtling cores is in burial mounds, past the skeletons.

Burial Chamber Entrance

So down into the burial mound you go, sword and axe in hand. It's dark, there's twisty passage and groaning sounds. You're sure that at any moment the roof is going to cave in. And did I mention the Skeletons? And the Ghosts?

Now the argument could be made that this is what D&D is except the reason to go down into the dungeon is treasure. Gold coins that are lying around that you can use to but stuff. It just feels... less personal. Whereas if you are going into the dangerous ruins to find the magical runestone that your village shaman needs to cast the spell to being back tha rain? That's personal.

So yeah, this is the kind of thing I want to run. A game where the characters are part of society, where they do the things they do to help others. Of course the trick is to write adventures that do that... that's the hard bit.

Weekly Challenge in Raku : Week 101 (Part 2)

Tags:

So for this task I found a neat little trick for calculating if a point is inside a triangle. If you calculate the area of the triangle it should equal the area of the three triangle made of connecting the point with each of the sides.

So I decided it was time to whip out some simple classes and write a mini DSL. Now I'd like to give a caveat with this, I'm using user defined operators which are awesome but also rather slow. Generally I would not advise using them directly in a script but instead putting them in a module that can be precompiled for faster loading.

With this in mind lets write a few tests. I'm creating three new operators p[], v[] and t[] these will create a point, a vector and a triangle object. Here's the tests which should hopefully make some sense :

#| Run tests
multi sub MAIN("test") {
  use Test;
  isa-ok( p[2,3], Point, "Point Creation OK" ); 
  isa-ok( v[p[0,0], p[2,2]], Vector, "Vector Creation OK" );
  isa-ok( t[p[0,0], p[0,3], p[4,0]], Triangle, "Triangle Creation OK" );
  is( v[p[0,0], p[3,4]].len, 5, "Vector Length works" );
  is( t[p[0,0], p[0,3], p[4,0]].area, 6, "Triangle Area works" );
}

Note I've also added a len and area method for the Vector and Triangle as I'm going to need these.

The Point method and operator are simple enough :

class Point {
  has Rat() $.x;
  has Rat() $.y;
}

sub circumfix:<p[ ]>( *@ (Rat() $x, Rat() $y) ) {
  Point.new( :$x, :$y );
}

The Vector object just takes two points and we include the len method (with use of ² which is great).

class Vector {
  has Point $.p1;
  has Point $.p2;

  method len() {
    ( ($.p1.x - $.p2.x)² + ($.p1.y - $.p2.y)² ).sqrt;
  }
}

sub circumfix:<v[ ]>( *@ (Point $p1, Point $p2) ) {
    Vector.new( :$p1, :$p2 );
}

And finally we add the Triangle object, this takes three points and uses Heron's Forumla to calculate the area.

class Triangle {
  has Point $.p1;
  has Point $.p2;
  has Point $.p3;

  method area() {
    my \a = v[$.p1,$.p2].len;
    my \b = v[$.p1,$.p3].len;
    my \c = v[$.p2,$.p3].len;
    my \s = (a + b + c) / 2;
    return ( s * (s - a) * (s - b) * (s - c) ).sqrt;
  }
}

sub circumfix:<t[ ]>( *@ (Point $p1, Point $p2, Point $p3 ) ) {
  Triangle.new( :$p1, :$p2, :$p3 )
}

Ok. So that's the basic tests done. Now I'll add a point-inside method to the Triangle object.

The tests for this (from the challenge).

is( t[p[0,1],p[1,0],p[2,2]].point-inside(p[0,0]), False, "Origin not in Triangle" );
is( t[p[1,1],p[-1,1],p[0,-3]].point-inside(p[0,0]), True, "Origin in Triangle" );
is( t[p[0,1],p[2,0],p[-6,0]].point-inside(p[0,0]), True, "Origin on edge test" );

The point-inside method is quite simple as I've got my DSL in place :

method point-inside( Point $pn ) {
    my $*TOLERANCE = .000001;
    return self.area =~=
    ( t[$pn, $.p1, $.p2].area +
      t[$pn, $.p1, $.p3].area +
      t[$pn, $.p2, $.p3].area );
}

One note in order to get this to work I needed to define a stub Triangle class using class Triangle {...} so I could define the t[] operator as otherwise the Triangle class doesn't know what it means.

Because I'm using Square Roots I'm having to deal with floating point number and approximate equality. I could use a different method with raycasting and vector crossing but I've done this and it works so that's cool.

Last bit make a nice MAIN sub that takes size numbers and runs the check.

#| Does the triangle made from the 6 gives points contain the origin?
multi sub MAIN( Rat() $p1x, Rat() $p1y,
                Rat() $p2x, Rat() $p2y,
                Rat() $p3x, Rat() $p3y ) {
  say t[p[$p1x,$p1y],
        p[$p2x,$p2y],
        p[$p3x,$p3y]].point-inside(p[0,0]) ?? 1 !! 0;   
}

One of the many things I love about Raku is it's ability to easily let you make a language to do what you want. Hopefully work that's being done at the moment will deal with some of the startup costs of user generated operators so we can really play about with them. But until then libraries work just fine. As it is this takes 43 seconds to run on my VM with Raku 2021.12.

If I change the p[], t[] and v[] operators to simple subroutines p(), t(), v() it takes 0.6 seconds... So I guess that's the version I'm going to submit. Anyway, I hope you found this interesting, more soon.

Weekly Challenge in Raku : Week 101 (Part 1)

Tags:

So one of the things I'm going to blog about with my daily blogging plan is the Weekly Challenge. As I've got some time on my hands I've also volunteered to review the Raku solutions which I'm going to do over the week with the plan being to get the review to done for Friday.

Anyway, lets look at this weeks challenge. Normally when I do these I write the code and then return back and write my thought processes out after the fact. This time I'm going to try something a little different and write here as I do the code.

Challenge 1

We're given an array of things and we want to display them as a sprial going counterclockwise, the spiral needs to be the tightest possible. As I see it there's three parts to this :

  1. Find the factors (M and N) of the length of the input array which have the smallest distance.
  2. Make a MxN array of the data from the input array spiralling counter clockwise.
  3. Print this out (in a pretty fashion so with added spaces).

I'm a fan of TDD so I'll be applying that here. Generally for the weekly challenges I like to write a command line script that can take a "test" input to run the tests like so.

#| Run the test suite
multi sub MAIN( "test" ) {
  use Test;
  done-testing;
}

Of course this doesn't do anything yet but because I've got a declarator block we get a nicely formatted usage out put with -? and ch-1.raku test runs without crashing.

So first up lets do some factorisation. Lets update the test code with some tests :

#| Run the test suite
multi sub MAIN( "test" ) {
  use Test;
  is( tight-factors(4), (2,2), "4 factors to 2 and 2" );
  done-testing;

}

Ok test the first, based on the first example in the challenge. If we run that the script fails because the sub doesn't exist yet. Now for the little dopamine hit you get from making the tests pass, I mean... that's why we do TDD right?

sub tight-factors(Int $len) {
  return (2,2);
}

And now when we run the tests the pass! Awesome job done! Of course it's not, but this is one of the core disciplines of TDD, as soon at the tests pass stop. So if we want to write an actual factoring algorithm we need another test.

is( tight-factors(12), (3,4), "12 factors to 3 and 4" );

I'm skipping the rest of the test sub for now. Or this post will get insane. Here we not only test the factorisation of 12 but also that we get our results in the order smallest then largest.

So the tests are failing lets work out the algorithm. Now I always tend to start with the application of brute force and work from there. My thought for this algorithm in it's simplest is something like this.

  1. For a value L loop through 1..L/2 assign to I
  2. If L is divisble by I put (I,L/I) into a list.
  3. Sort the list by the difference between the two values.
  4. Return the first item from the list.

This nice thing with that algorithm as opposed to one that tracks the smallest difference during the loop is that you can multithread it easily. I'm probably not going to but still, that's the way my mind goes. Basically if I can write it as a series of list operations I'm happy.

sub tight-factors(Int $len) {
  (1..$len div 2).grep( { $len %% $_ } ).map( { ($_, $len / $_ ) } ).sort( -> ($a,$b) { abs($a-$b) } ).first;
}

Ok so that works, next up making a spiral. So I'm going to skip a few steps for the blog, I'm adding a couple of tests and the code for them.

is( spiralize( [1,2,3,4] ), [[4,3],[1,2]], "4 long list" );
is( spiralize( [1,2,3,4,5,6] ), [[6,5,4],[1,2,3]], "6 Long list" );
is( spiralize( (1..12) ), [[9,8,7,6],[10,11,12,5],[1,2,3,4]], "12 Long list" );
...

sub spiralize( @list ) {
  my ( $height, $width ) = tight-factors( @list.elems );
  my @out = [[Any xx $width] xx $height];

  my @current = [0,$height-1];
  my @direction = [1,0];

  for @list -> $val {
    @out[@current[1]][@current[0]] = $val;
    my @next = [ @current[0]+@direction[0], @current[1]+@direction[1] ];
    if @next[0] < 0 || @next[1] < 0 ||
       (@out[@next[1]][@next[0]]:!exists) || (defined @out[@next[1]][@next[0]]) {
      given @direction {
        when [1,0]  { @direction = [0,-1] }
        when [0,-1] { @direction = [-1,0] }
        when [-1,0] { @direction = [0,1] }
        when [0,1]  { @direction = [1,0] }
      }
    }
    @current = [ @current[0]+@direction[0], @current[1]+@direction[1] ];
  }
  return @out;
}

So lets go over this. Firstly we get our height and width from our tight-factors function. Then prefill an array with Any objects (so it's effectively undefined. Then we make a note of the current point (starting in the bottom left corner). Then we fill the current point with the first number in the list.

We've got a note of the direction we're moving so we work out what the next point will be. If the next point isn't valid when change the direction. What counts as not valid?

  • It's out of bounds
  • There's a value already set at that point

We just go through this loop with each value from the list. So finally it's time for the last part. Pretty printing. I'm not going to write tests for this part instead I'm just going to add a second MAIN sub that takes a list, spiraliazes it and prints it out.

#| Given a list of items print them in a tight anti clockwise sprial
multi sub MAIN( *@items ) {
  my $width = @items.map( *.chars ).max;
  .say for spiralize( @items ).map( -> @l { @l.map( { sprintf("%{$width}s",$_ ) } ).join(" ") });
}

So we get our list of stuff. Find the length of the longest item. Then spiralize it, format it and join with spaces then print each line. And there we go, job done.

Still I've written a lot. I think I'll look at Part 2 later. I hope this has been interesting, do leave a comment with your thoughts.

Do I play D&D?

Tags:

It's a question I've been asked a few times recently, thanks to the upsurge in it's popularity is I play D&D.

Short Answer

No.

....

Still here?

Long Answer

So the longer answer is a bit more complex. No I don't play D&D for a number of reasons, I find the limitations of a level based system annoying and unbelievable. The same goes for Armour Class, the magic system and the generaly premise of how most games are laid out. The concept of a world where you have heavily armed and armoured warriors, who often appear to be delusional or utterly psychopathic wandering around does not fill me with glee. Going down into dangeours, trap and monster filled dungeons for treasure what's that about?

I got my first copy of D&D almost 40 years ago, it was my 8th birthday present and this year I'll be 48. And yes, it opened something up in my brain but over the years I found other games who I felt more akinship to. I do own D&D (the 3rd edition), 13th Age and King of Dungeons though I've not got round to getting 4th or 5th editions D&D. I'm kind of sad the recent Magic the Gathering campaign settings books are for D&D really as I feel it's not the best system for it.

So here's the thing, one of the things I mentioned yesterday was I'd like to try some RPG writing. But I'm trying to work out what, as the kind of games I love to run are not the kind of games people seem to want to play. So maybe before I write some stuff I should work on the selling of different ideas to people.

And of course there's the fact that dispite it being lockdown and all the gaming moving online I've still not managed to actually run something... My social anxiety and general belief that no one wants to actually spend time with me doesn't help. I'm hoping that with my new start I can fix this.

So here's five games I'd like to run if I can find some players. Each appeals to me and should give people lots of potential to make interesting characters and stories

Invisible Sun

The surreal game of magic and dimension hopping. One of the many things I like about and would like to explore is it's a very player driven game. It's a game for people who want to spend time on making their character, and even their characters house, just right. Players advance by completing character arcs that they choose and the GM works to entwine into the story.

This may have to wait until after the current crisis though as I think it really wants to be played at the real table. It's got so much stuff.

The Yellow King

Four interlinked campaign settings of extradimenional horror investigation. Uses the Gumshow Quick Shock system, which focusses on narrative outcomes over crunchy rules. One thing I like about it is that it's just based on the King in Yellow stories rather than dragging the King and his Daugthers into the bulging Cthullhu Mythos. The game starts in Paris in 1895 where a play must not be staged...

Numenera

I love Numenera the setting just oozes style and also you can apply large gobs of handwavium to it. Plus there's a totally reasonable reason to explore ancient ruins, you're not looking for gold you're looking for ancient technology you can repurpose to you own ends. I also would really like to try running a game using the rules in the Destiny book of the 2nd Edition. In Destiny the focus is not just on the characters but on the settlements they live in. Now exploring dangerous places makes even more sense as you are looking for stuff you can bring back to help build your community not just riches for yourself.

GURPS Dungeon Fantasy

So I've been a GURPS fan for almost as long as I've been a roleplayer. The recent(ish) release of Dungeon Fantasy takes the GURPS system and throws away all the bits you don't need. If you want a crunchy dungeon exploration then this would be my game of choice. Lots of chances for players to make their own characters and lots of options to make combat interesting. I've got my own setting Trevallis that I started writing about a few years ago or I could come up with something else.

Again if I'm running this the focus would be on how the characters fit into their world and making sure their actions have real impact, good and bad.

The Dracula Dossier

This is one of those games I really want to run at some point but again I think it really could do with a table as it's based on the most awesome player handout ever. A complete, updated and annotated copy of Dracula that gives clues to his reality and the shadow war between him and British Intelligence that's been going on since the 1800's.

Another Gumshoe games because frankly they are awesome.

Final thoughts

So this, as many of these posts will probably be, was something of a stream of consciousness type thing. I know I'd love to run a roleplaying game, I also know I've been very very prone to flakiness in this regards over the years due to my mental hangups. I'd love to promise that's not going to be the case again but all I can promise is I'm trying to make my mind a better place.

Drop me a line if you're interested in a game.