Categories
Uncategorized

Random DnD Monuments

For fun, I dove into procedural text generation using Improv. It works well enough – the fact that grammars are JSON files is tedious but you can create some interesting bits of text at random. After getting the hang of it, I went down the rabbit hole to generate descriptions of monuments a party might encounter while traveling. Here are some examples, feel free to use and adapt them.

I like seeing how things come together in unexpected ways and hint at a deeper story. The difficult part is brainstorming enough details so you don’t see the same ones over and over.

“A well-preserved fountain in an a ruined keep. It is covered by thick, woody vines. The fountain was designed by elves to study the night sky.”

“A worn crystal in an a wooded clearing. It is inscribed with demonic faces and beings. The crystal was constructed by goblins to sacrifice their victims.”

“A well-preserved stone surrounded by 4 statues. It is covered by burn marks. The stone was built by orcs to perform dark rituals.”

“A cracked table upon a low rise. It appears to be made of marble. The table was built by humans to commemorate an important battle.”

“A crumbling burial mound in an a wooded clearing. It appears to be made of slate. The burial mound was carved by dwarven masons to commemorate an important battle.”

“A shadowy burial mound in an a small cave. It is covered by soot and ash. The burial mound was conjured by dark sorcery to perform dark rituals.”

“A cracked table surrounded by standing torches. It is covered by burn marks. The table was made by drow to sacrifice their victims.”

“A cracked arch upon a low rise. It is covered by thick, woody vines. The arch was built by humans to ward away evil spirits.”

Categories
Games

Board Games to Get You Through Social Distancing

Many of us are stuck at home thanks to COVID-19 and while it’s important to get outside for some exercise, board games are a great way to pass the time and keep anxiety at bay. Today, I saw via ArsTechnica that Amazon is running a buy-two-get-one-free sale and includes some good games in the selection. It’s tricky to choose a good game without playing it first. Below, I’ll give you my recommendations, in no particular order but with an eye towards ones that don’t require too many players. I only picked the ones that A) I’ve played and B) are part of the sale.

Dungeons and Dragons Essentials Kit

Great way to get started playing D&D as it has pre-made characters and a sandbox-ish set of adventures to run through. You can even make your own characters based on the four core-classes (fighter, wizard, cleric, and rogue). If you’re limited by the number of players, it has rules to use sidekicks to buff up your party. It’s a great way to sneak some reading and math with kids too and can limit screen time. You can pair it with the Starter Set, but there’s some content overlap so you don’t really need both. Get it here.

Betrayal at House on the Hill

Betrayal is highly replayable and works well with four players, but probably no fewer. You start out as a group exploring a spooky mansion by uncovering and placing tiles. Eventually, someone triggers a haunt which changes the game as one person becomes the haunt and the other players have to figure out how to defeat them. More here.

Splendor

This semi-abstract game has you collecting different color gemstones, to build an engine to acquire more gems. Eventually, you want to curry the favor of nobles as you collect points to be the first to 15. It’s straightforward to learn, plays well with just two people, and speeds up nicely towards the end. More here.

Seven Wonders

Seven Wonders is a fun, fast-paced card drafting game. Admittedly there are a lot of rules to digest at first, and if you’ve played before you can quietly amass a lot of points before everyone else realizes what your doing or learns how to stop you. The best part about this game is it scales up to 7 players without slowing down. Seven Wonders.

Exploding Kittens

This is a quick game about taking cards from a deck, avoiding the exploding kittens, and sabotaging the other players. Plays quick, fun artwork, and involves a fair bit of luck. Get it here.

Escape Room the Game

Three escape room puzzles in this box will keep you all busy for an hour as you find clues to identify the four keys you need to get out from one room to the next and eventually “escape.” If you get stuck, you can get a clue or surreptitiously google the solution. Once you play a scenario, you can’t really go back through it but still fun, especially if you like escape rooms. More here.

Honorable Mentions

  • Codenames – fun party game, but you need a lot of players to really enjoy it.
  • Unstable Unicorns – similar art style to Exploding Kittens, this one has you collecting unicorns. I haven’t played it with fewer than five players but I think the fun in this one scales with more.
  • Munchkin – can be fun, lots of backstabbing.
Categories
Technology

Accessing a Docker container with NGrok

I want to access a local docker development environment from outside the host computer. This comes in handy for viewing a site on another device or sharing it with a client. There seems to be a couple of ways to do this documented online, but of course, none exactly worked for me. I’m going to assume you already have ngrok installed for doing the actual tunnel.

First, make sure nothing is using the port you want on the host machine. In my case, this means don’t run apache on the host machine if you’re docker container is using ports 80 or 443.

Then, to setup the ngrok tunnel I use this command:

ngrok http -host-header=rewrite local.example.com:80

The key there being the host-header switch. Without it, apache couldn’t match the configured virtual host to the random hostname assigned by the service. With it, the local site is accessible without having to change anything about its configuration.

Categories
Technology

Paying Attention to Drupal Admin experience

Capturing my answer to a question on a mail list I’m on about paying attention to the Drupal admin and editor experience. Particularly, someone was asking if they should open their allowed HTML to allow pasting form and iframe tags versus the risk of being compromised by the same. My initial reply was:

If your content team is relatively small and you trust them … I think it’s OK to all form and iframe embeds.
However, if you can I’d see if you can embed these snippets via some other way, like shortcodes in WordPress or as Paragraphs in Drupal (there are probably a dozen other solutions in Drupal too) which integrate with each of those platforms. HTML is easy to break, you won’t be able to just paste the HTML into your editor, and if they embed code has to change in the future (or be removed) it’ll be tedious to do so.
Which lead to a longer discussion on ensuring the overall Drupal editing experience is not ignored.
First, “locking” clients out of editing templates and configuration values makes sense, if the vendor will be hosting and supporting the site long term. There’s a lot going on in a CMS, and accounting for changes to configuration, CSS, templates introduced only on the production server is a migraine waiting to happen.
That said, it doesn’t mean you should give up a lot of flexibility for controlling the layout of your pages and you shouldn’t have to run to the vendor for every change. Things they and you should be paying attention to:
Ensuring they aren’t hard coding page and node layouts in a template such that changing them later requires a lot of effort. This was a pain on a site I worked on last year and had the Webforms module enabled. Instead of using the Webforms UI to build a form and control how the fields were grouped and displayed, the previous developer did that completely via custom templates. For the client,this meant that any new form had to have a custom template for it and changes made to forms in Drupal’s UI had no apparent effect (which kind of misses the point of having Drupal). Other pages on the site were handled similarly with custom templates.
Just throwing a WYWIWYG editor at your editors is also a big fail. If you have a document type which will have a link to a PDF file, don’t be content with a “file explorer” type plugin for CKEditor. Have a “Related Files” field in the document content type. Editors shouldn’t have to worry about how and where the file link will be rendered. Use Drupal/your CMS to consistently display the links (and integrate the PDF contents with Search, share files with other content types, etc).
For layout control within a page, Drupal has a couple of options which don’t require an editor making the layout in raw HTML. I think there’s a Layout builder in the latest release and there’s always the “Paragraphs” module which lets you define types of blocks you can stack to build an interactive page. Conceptually not unlike Mailchimp’s editor, if your familiar with it or how Gutenberg’s blocks will be handled in WordPress.
Media handling in Drupal has always lagged behind WordPress. I’m not sure what the state of the art is, but the latest release has Media in core. If you’re going to have a lot of photos, audio files, etc… you’re better off managing them as Entities you can tag and manage like a node and not just think of them as a file you upload and link somewhere (much like images I mentioned earlier).
Also if you have some custom workflows for managing the content creation process, you should ask your vendor to use well known modules like Workbench to configure and manage the process. I wouldn’t want to code a custom workflow for a client, since that becomes harder to change whereas Drupal modules exist which can let you manage and tweak those requirements in the UI (see https://www.palantir.net/blog/its-here-workbench-drupal-8)
Last, I’d say make sure you have a good content model. If you are going to have blog posts, articles, and press releases — each with their own quirks — they should each be a content type in the admin. Don’t make an uber “article” type which behaves differently depending on which fields are filled out. Within each content type, group fields which belong together, use vertical tabs or sidebars to break up forms with a lot of fields, etc… This is a good summary: https://evolvingweb.ca/blog/how-make-sure-your-content-editors-love-drupal

 

Categories
PHP Programming

Creating ZIP files and streaming the response with Silex

Creating a zip file is easy and Rob Allen has you covered on that front to get you started. I needed to do this to create a zip file of PDF files generated by Dompdf. It turns out, you can add files to a ZipArchive object without actually creating the file if you can get the contents as a string. This boils down to:

// $html is what you're going to render.
$dompdf = new DOMPDF(['defaultPaperOrientation' => 'landscape']);
$dompdf->loadHtml($html);
// this generates the PDF contents but does not output them anywhere
$dompdf->render(); 

// now we create a zip file and add the PDF
$zip = new ZipArchive();
$zip->open('/tmp/archive.zip', ZipArchive::CREATE);
// 'report.pdf' is the filename inside the zip archive
$zip->addFromString('report.pdf', $dompdf->output());
$zip->close();

The above adds one file, clearly if you want to create multiple PDFs, you would do that in a loop and call addFromString for each one. Then, if you want to stream the response to the browser with Silex (which uses Symfony components) you do:

use use Symfony\Component\HttpFoundation\ResponseHeaderBag; 

// ...

// at the end of a controller...
return $app->sendFile('/tmp/example.zip')
           ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'your-report.zip')
           ->deleteFileAfterSend(true);
Categories
PHP Programming

Everything I learned to manage my career I learned from Soccer

This was originally posted on the mojolive blog 5 years ago, but I want to preserve it here if/when it goes down.

When I started working as a web developer, there wasn’t a lot of guidance about what that meant as a career choice. Of course, back then we were getting over the excitement of the blink tag and the new design opportunities afforded by table tags. I had to figure out a career path, and I did manage to do just that by watching a lot of soccer.

1. It’s not a solo effort.

Rare is the player that can take the ball from one end line, dribble past 11 opponents, and score the winning goal. Even if they manage to do it during a game, they’re likely to use their hand to score the next goal.

It is tempting to think of your career as a solo effort, particularly in technical fields where introverts seek shelter. But the people you work alongside, meet at conventions, and connect with can be invaluable resources when you’re looking for the next challenge in your career. Even at a small company, you’ll have to work alongside other programmers, manager, designers, and end users.

It pays off to make the effort and get to know them beyond the current project, I wouldn’t be working at mojoLive if I hadn’t worked with Sandy previously. Take part in your local community events and conferences too, they’re great for expanding your network’s reach outside of colleagues, schoolmates, and clients.

2. Serendipity complements planning

When you’re watching a game, and maybe dreading a scoreless tie, the entire game can change instantly.  A player with a simple flick, a mazy dribble, or an audacious goal can change the tempo and momentum of the rest of the match.  It’s impossible for a soccer coach to plan every movement or play, like an American football or baseball manager.

It’s also impossible to plan every single move in a career, no matter how good your plan is; economic conditions can change and new technologies may become popular. You have to leave room for chance and serendipity to play a part in your career, and be willing to take a risk and make a change when an opportunity presents itself.

3. Keep your skills sharp

Once a player passes 30 years old, fans and coaches inevitably start asking how much longer they can play. Like any other athlete, the shelf life of a soccer player is limited by his physical condition. Some players can defy time; Preki was named Major League Soccer’s MVP at the ripe old age of 40.

For most of us, physical traits don’t affect our job performance so drastically. But, your own shelf life is limited by the skills you acquire and use each year. If you find yourself in a rut, using the same programming language all the time, one technology stack, or targeting a single platform, make it a point to look outside your comfort zone.

4. The good players practice, practice, practice

The best players have an almost single-minded focus on soccer. It might make them dull at dinner parties but it gives them an edge. They spend extra time after practice running through drills on their own, or hitting the gym on their off days.

Likewise, extra-curricular projects can help you learn something new. Always building Drupal sites? Check out python and django. Have an idea that could be a useful product? Build it in your spare time, to see just what it takes to build something from start to finish.

5. Play with the best to get better

I came to the game late and only started playing soccer recreationally in college. I quickly learned that playing with better players made me improve faster. Not that I ever became more than a barely adequate player, but playing with them meant I had to try to be quicker, and play smarter.

Once you find a comfort zone, it’s tempting to stay in it but you risk stagnation. If you find that you’re a big fish in a little pond or you’re a little bored with the work you’re doing, its time to think about working on more ambitious projects. For programmers, a ready avenue to collaborate with other top-notch developers is through open source projects, or simply sharing code on github.

6. Don’t be a one trick pony

It seems every team has at least one player who is one dimensional but the coach loves for some reason. The worst is watching a player who can only shoot with his left foot. Inevitably, they’ll be one-on-one with the goalkeep, but the ball will be on their right foot.  As they waste time maneauvering to get the ball on their favored left foot, a defender has time to recover and tackle the ball away.

Don’t be predictable. Don’t stick blindly to always using the same solution whether its PHP, Drupal, or jQuery. For some projects, you’ll waste time trying to fit a square peg into a round hole, when a faster, cheaper solution. It’s also tempting to think of yourself as a “Back-end programmer” or a “Front-end engineer”. Learning to do both not only improves your versatility, but you can speak intelligently about what it takes to do both.

Categories
Uncategorized

Get the First Page of a PDF as an Image

Easy with image magick:

# get the first page as a PNG
convert -resize 1275x1650 "example.pdf"[0] cover.jpg

# make the smaller version
convert -resize 155x200 cover.jpg
Categories
Programming

Procedural Map generation

This post explains an approach to generating fantasy maps that is really interesting. One part of generating a non-grid based map, is to use create Voronoi polygons around some random number of x,y points on the map. There’s a lot of heavy math involved, but there are libraries for calculating them with Python and even PHP.

Categories
PHP Real Life Web Design

20 Years of PHP

Ben Ramsey shared how he got started with PHP and had the great idea of asking others to write about their stories and tagging it as #20yearsofphp. This is my story.

When I graduated from college in 2000, I began looking for a job without a clear idea of what I wanted to do. In grad school I had done some projects using HTML, ASP, and ShockWave for various professors and figured I could get a job building web sites until I decided on something. I replied to a job posting (I think it was on hotjobs.com) and in September 2000 I started working as a web developer at Forum One. Thanks to that job, I spent a week working in San Francisco after meeting my (future) wife on a previous trip to California. We’d get married in 2004.

At the time, PHP4 had just been released. I worked on projects which still used PHP3, or interfaced via Perl CGI scripts to save data in a custom-build in-house CMS. I think my first actual PHP project was for a local Jewish Temple. Like other junior devs at that job, I took a shot at replacing the Perl scripts with my own PHP versions. Luckily, I never inflicted them on my colleagues.

From there, PHP was a gateway to learning about Linux, web servers, databases & SQL, and so much more. Thanks to PHP (and Drupal) I worked for my favorite soccer team, D.C. United. Today I’m grateful that, through running php[architect] I get to work not only with Eli, Kevin, Sandy, and Heather on daily basis but also with the wider PHP community through php[architect]’s magazine, books, and conferences.

I don’t think I could have planned the last 15 years better. Here’s to the next 20!

 

Categories
Programming

Being a life-long programmer

I read the following article this morning, and found a lot of useful insight in it about what it takes to be a programmer long-term. And, though I’m not approaching 55, as my 6 year old pointed out when I told him my age two weeks ago I am “almost near 100″… Yes I Still Want To Be Doing This at 56

I particularly identified with was the following paragraph

“The thing I find most important today is that you should never work longer, just smarter. Being older does mean you can’t code 20 hours a day any more, or rather imagine you can code 20 hours a day as it’s not really good coding. Is there a real limit to how many hours a day you can actually be producing a quality application? Probably it does go down over time but as long as you continue to learn how to code smarter the end result is still quality, just with less caffeine.”

When I started out of school 15 years ago, it was very easy for me to just sit and bang out code with little preparation or thought put into it. I’d come back, if there was time, and clean up some bit or I’d come back months later and have no clue what I meant to do and kick myself for the decisions and shortcuts I’d take. Nowadays, I’m a lot more reflective when I start something, even if its a simple class. If I can, I bounce ideas off of colleagues, which at the minimum forces me to articulate the pros/cons of approaches I’m considering. I spend less time actually writing code, but have cleaner, easier to use code as a result and usually there’s time re-factor and clean up the rough edges.