Friday, 24 April 2020

Any fool can write code that a computer can understand

Good programmers write code that humans can understand.
Martin Fowler

Generators are dope. While I'm working on a tool that will create generators for you, in the meantime I can write a quick guide on how to create your own generator in JavaScript. Bonus: you can also call yourself a programmer when you're done.

Today, I wrote https://place-and-region-generator.netlify.app/. It is, as the URL says, a generator for place and region names. It took me maybe half an hour because it's really quick to write ugly code like I did, and it's also a really simple program. I'm gonna teach you how to write it, too. Instead of place names, let's go with dwarven names. I want to generate dwarven names. How do I go about that?

Step 1: Node & NPX

Since I work as a web dev in my daily life, my computer already has all the dependencies I need to create projects (react projects, in this case). Here's a super short guide to how to get node and NPX on your machine:

We need nodejs. Let's not care so much about what it is,  we can dig into that some other day. Install it (installation varies between different operating systems), and then check that it worked with something like this in the terminal (this is in an ubuntu container):
On a mac, it can look like this:
Great. We're almost half-way. We also need either NPM or Yarn, two package managers that are used for javascript projects. Don't mind the technical details, for now. NPM comes with node, so we'll go with that.
The last part of step 1 is to make sure that npx is installed (it should come with the latest versions of npm):


Step 2: React & Previewing Stuff

The next command we need to run is this: "npx create-react-app dwarven_names"

Where "dwarven_names" is the name of our project/generator. This will create a new React app with the name "dwarven_names". It will create this in a folder named "dwarven_names" like the text says:

Let's do what it says: cd (change directory) into dwarven_names and run "npm start":

And if you now navigate to http://localhost:3000/ you will see your app running. It doesn't look like much, right now:

But hey, you did that! Awesome. Let's rip everything out and create something of our own instead.

Step 3: Creating a basic generator

Now we're touching on actual programming, but I'll try and write it so you can follow along and just replace things with what you, yourself, need. Feel free to reach out to me on discord, I'm Azaz#1947 there, or comment here and I'll help as best I can.

Alright, to edit code it's usually easier to do so in a code editor. But you can edit code in notepad.

Let's open the file "App.js", it's located in the "src" folder inside our "dwarven_names" folder. It looks like this:
Great. We don't need some of this junk, but I'll go through it nonetheless:

The first three lines are dependency imports. We fetch "React" from a package aptly named "react", we fetch a logo (it's the rotating atom thing), and we import some css, too.

After that, on line 5, we declare a function named "App", and inside our function we return some HTML... ish. It's HTML but with some extras. In HTML, you write "class", but you can't do that in JavaScript, so you instead write "className". We'll rip out most of the stuff inside this. Delete until it looks like this:



If you save that and look in the browser, you'll see we've successfully removed some cruft. You's a programmer!

We'll add a title, and create some Dwarf names. In Zonk's generator (which I borrowed for this tutorial), a Dwarven name comes from an appropriately dwarven base, such as "Dragon" or "Stone", combined with a suffix, something dwarven like "arm", "killer" (I guess these are WHFRP dwarves?), "shield" and similar. We'll create two arrays to hold these. An array is basically a list, but the syntax is important. Here's how it looks in JavaScript:



Not terribly difficult to understand. Here's the syntax, in its base form: const arrayName = [value1, value2, value3]

Values can be a lot of things, but we're working with text (or "strings" as the fancy name is).

It doesn't really matter where in the file we place these arrays, but imports should always be at the top, so we'll just tuck them in under that for now.

The second to last thing we need to do (ish) is to get a random item from both arrays onto our page. Here's how that's done:

The [0] part is "give me the item at position 0 from the array named 'base'". Let's see how it looks:
You know what? That looks okay. Now we just need to make it "random" rather than always being the first item in both arrays. The secret is to use a function. Here's how that looks:

And here's how it's used:

I realize now that I forgot to tell you what the {} deal in the code is, on line 14. It's telling React "run this function and insert the value returned from that function here".

And for the "randomElement" function we wrote, what we're doing is we're giving that function an array ("base" or "suffix") and then we're asking it to select a random item from that array and return it to us. It's a very fancy "modern" JavaScript syntax. So when we're using the function, we're saying "give me a value from 'base' and combine it with a value from 'suffix'"

Anyway, we're almost done. We want more than one dwarf name, though, so we'll do that with a fancy loop, like so:

There's a lot going on here. We're declaring a new array ("names") on line 10. On line 11 to 13 we're looping (going through the same code a specific amount of times, here it's 10) over the same piece of code 10 times and saving the result of that code in the new array we created.

array.push() adds an item to an array. randomElement(base) + randomElement(suffix) combines the result of the two randomElements into one (not all languages can do it like this, but JavaScript can).

the "names.map()" thing is just a shorthand way of saying "modify each element in the array like this". Here we're modifying them to create HTML paragraph tags. map() returns a new array, so we're not chaning the names array on line 10.

The "key" part is because React needs to know something unique about every item in the array, otherwise it complains a lot. Basically.

And here's how the results look:

There'll be a lot of repetition here because we only have three names of each kind to select from. More names = more combinations.

We've successfully created a generator. Right now you can use it on your own computer, which is pretty nifty, but we can also host it online for others to use. The last thing we need (can) to do in this step is clean up some junk that we don't need.

We don't want logo.svg, so remove that. Our CSS file can also be trimmed down to this:

the rest of the stuff in it is basically just "I want to create a rotating logo", and we don't have that.

Don't worry too much about the code; at the end of this guide I will show you all the files. We're basically done with it already.

Step 4: Version Control

Oh no, that sounds hard!

It is... kind of. I'm sorry to say, but this will be the hardest step to explain. Create-react-app, that we used to start our project with, has given us a .gitignore file, which is good because then we don't have to worry about that. Version control is basically like save points, but it's graphs and you can do lots of cool shit with it. I will not teach you anything about that. I will point out how we get this project onto our VC platform of choice.

I should probably have mentioned: YOU NEED TO INSTALL GIT ON YOUR MACHINE FOR ALL THIS TO WORK. It's not terribly hard, here's a guide: https://www.atlassian.com/git/tutorials/install-git

We have a few choices. Github is, ostensibly, the largest, most well-known of the platforms. Sign-up is easy (it is for most of these guys tbh). BUT they host ICE and so they can get fucked. Pick whatever. I picked GitLab, but the process is similar for all the platforms (you can also use Bitbucket, but stick with one of these three: Github, GitLab, Bitbucket, it will make it easier in the next step).

Create a new project on your platform of choice:

Note that I'm leaving the "Initialize repository with a README" checkbox unchecked.

Gitlab gives us instructions on how to proceed.

All that stuff is terminal-based. There are visual git clients available. I will not use one, but you can probably google for it. GitKraken is popular, and Fork is also a good one (if you're on Mac). Anyway, we'll follow the "Git global setup" first, then we want to do "Push an existing folder" because our project is already existing

If we follow the GitLab guide, everything should work just fine. (I sidestepped it a bit because I have several git accounts. If you want to specify a git account for a specific git repository, just omit the --global flag and the changes are local.) Here's the last few lines for me:
A whole lot of gibberish. It might make more sense to you later unless you already know git but then why are you reading this?

And this is how it looks like on Gitlab:

We are so nearly there. Lemme just hit on one point real quick: "git add ." means "stage everything that's changed in the folders you're tracking". "git commit" means "save all changes you have staged under this commit message" (it will prompt you for a message, or you can do "git commit -m 'your message here'" instead). If you end up in vim, the command to exit is "hit escape a few times, then :, then type q! and enter" and the command to exit and save is "hit escape a few times, then :, then wq and enter". That is, the command to start writing commands is :

For more on git, I recommend googling for guides. It's powerful and amazing.

Step 5: Get this thing online so help me

Let's get this app (you can use this word now, you're a PROGRAMMER) online! We'll use Netlify, because it's the easiest option. You can use your newly created Gitlab account to sign up on Netlify, so that's neat but they also offer the regular Google, Facebook, etc, etc. Once signed up, read their small guide/flash cards then hit that "New site from Git" button. Under "Continuous Deployment" ("CD" for us cool kids in the biz) select your poison of choice (GitLab for me). We need to authorize Netlify to access our GitLab resources, so I just hit okay because I'm wild like that. Find your newly created repository, and select it:
So the cool thing is, now that I've selected my "dwarven_name_generator" repo, Netlify is smart enough to know what tools I've used to create my application with. I cheated and used yarn, so I'm sorry about that but it will say "npm run build" instead of "yarn build" on this screen if you used npm:

All those settings look okay, so I just hit "deploy site" and I'm basically done. Because look at that, it's already deploying. I've got a new URL for my project; it's always randomized to start with, but poke around in the Netlify settings and you can change it to something else if you want to. I'm cool with the "modest-heisenberg-a2c78d" URL, because I figure I'm not going to push this application very much.
 
After a while, it switches from "Site deploy in progress" to "Last published at" and a link to our cool, new app. And here it is, in all its glory: https://modest-heisenberg-a2c78d.netlify.app/

Alright. Not too hard, right? YOU DID THAT. Well, I DID THAT but you could also do that if you follow along!

And the best part about Netlify is that if you ever update your master branch in git and push those changes to your remote repository (Gitlab, for me),  Netlify will spot those changes and deploy them automatically.

And that's pretty neat.

Step 6: ???


Step 7: Profit

Now that we know just how easy it is to make a generator, I hope you can see that it wouldn't be terribly hard to create a more advanced generator. It's basically just "pick a random option from this array, then a random option from this array, and then from this" and so on. It is easy. You'll run into problems -- you can google the answers, because the more you do this, the more you learn the "language" of programming, which in turn makes it easier to google for more answers.

Step 8: Collaboration

Oh, also, I made the Dwarven Name Generator public on GitLab: https://gitlab.com/cassie_/dwarven_name_generator -- so you can create pull requests that add code or names or suffixes or just whatever to it if you want to. But you'll have to read up on that yourself because this is getting very long. You can also inspect all the code for the project over there, so that's also neat. Especially Zonk should probably create a pull request because it's basically their idea, just chopped into a very small piece.

And if you have any questions, just hit me up either here or in Discord. Now go forth, my friends, and create! I expect great things from you!

No comments:

Post a Comment

Let's Go: setting up KataGo's Human-like network

TL;DR: It's all about them command-line arguments. Here's a short guide: Install Sabaki Download the latest release of KataGo  and e...