Uncertainty is fun!
Life is uncertain. Most of us try to forget this as we go about our daily business. But life without uncertainty is tedious and large school of orange fish. SEE! HA! By adding that bit about the fish, I added some randomness to your day, filling it with joy and delight!
Okay, that might be overstating things, but the point remains, however tenuous it may be. I'm a game developer and although the maths for games doesn't have to be complicated, pretty much everything is controlled by numbers. And it's useful to be able to come up with random numbers. Let's see an example: max = 100 r = math.random(max) print("I've picked a number between 1 and 100. It is:" .. r)
The result from this will be a some text and a number from 1 to 100. As I've shown you before, you can compact all that code down to one line if you want, but I'll leave that as an exercise for you folks.
This code may be used this to make a simple dice-roller if you want. All you'd do is swap that 100 for a 6. Woo! Useful! One important thing to notice is that there's an entire library of mathematical functions that do cool things like this held under the 'math.' name. You don't need to know them all, and will probably only use a couple but math.random()is one of the more useful ones. Arrays
Arrays are where the fun with coding really begins. You've previously seen how you can get sections of code to run again and again using 'loops' like for i = 1, 5 do, but arrays are where this starts to show its usefulness.
So what are arrays? Arrays are just like other variables: shoeboxes containing data. In the case of arrays, they are shoeboxes that can contain yet more shoe-boxes. They look a little different from variables in how we create them, but that doesn't mean they are scary. If I put a 2 small shoe boxes inside a large shoebox you'd be just fine. With a simple variable we just say a = 5 to make a piece of data with the label 'a' contain the value 5: fill shoe box 'a' with 5. Easy. With an array, it's simply a collection of shoeboxes with a label of its own, like 'the shoe boxes in my cupboard'. We might have more in the garage, or under the bed. Apparently we have a problem with shoes. Because we now want to name a collection as well as individual shoe boxes, putting data into the whole thing looks a bit different. We first have to say 'Hey! This data is going to be an array, and will contain more labels!' In addition, when we start putting in values, we need to say 'which shoebox in the cupboard we want to put the value in'. The format for creating an array is like this: cupboard= {} This means 'make an array called cupboard'. It's empty to begin with. cupboard[5] = "thingy" This means 'put the word "thingy" into the shoe box in the cupboard with the label '5'. The other shoe boxes are still empty! Let's take a look at how this plays out in actual code: t = {} -- Let's make an array named 't' t[1] = 5 -- Let's put a '5' into 't' at position 1 t[2] = 10 -- Let's put a '10' into 't' at position 2 print(t[1])
This prints out '5'. This is because we've put two numbers into the table: '5' and '10' at positions 1 and 2.
If I were to try print(t[3]) I'd get nothing, because there's nothing at position 3! Note the lines after the -- are called 'comments'. They do nothing but remind me what things are for. You can use them to write notes for yourself if you want. Any time the computer sees -- it will ignore everything afterward. Arrays are incredibly flexible, with multiple ways to set them up and the ability to hold anything at all, including functions and other tables! But why is this useful, and why did I bring up the whole 'random()' thing to begin with? Let's expand this a bit and see! friends = {} -- This tells the computer that 'friends' -- is going to be an array, not a number or 'string' friends[1] = "John" friends[2] = "Mary" friends[3] = "Kate" friends[4] = "Vlad" friends[5] = "Mimsy" friends[6] = "Kbun'daar the third" friends[7] = "Squiggles" friends[8] = "Spamford" friends[9] = "Mr Quackers" friends[10] = "Dickwings" -- print a line to give the data some context print("My friends are:\n") -- Now print out all my friends for i = 1, 10 do print(friends[i] .. "\n") end -- And pick out a best friend for me! r = math.random(10) print("But my best friends is " .. friends[r])
This will print out a list of all your friends, and then pick a best friend for you at random. If it's Vlad or Dickwings then you have my sympathies. Also, note that you already knew what this code did because of my comments, the things I put after --. This is good practice, so make sure you do it yourself.
But... still why?
Some of you will still be wondering how any of this is useful to anyone. Well, at some point you've played a game. Scrabble? Tic-Tac-Toe? Those games have grids which are held in an array like this. Minecraft? Its entire world is also held in an array like this. Every spreadsheet or word-processing application holds its data in a form like this. Arrays are everywhere.
An equivalent exists in pretty much every other language you might choose to learn. Computers are good at working on large sets of data very quickly, and arrays like these are the simplest way to do that. Alternatives
The way we created our friend list was pretty long-winded. There are alternatives! We could have written the friend array definition like this:
friends = {"John", "Mary", "Kate", "Vlad", "Mimsy", "Kbun'daar the third", "Squiggles", "Spamford", "Mr Quackers", "Dickwings"} print("My friends are:\n") -- Now print out all my friends for i = 1, 10 do print(friends[i] .. "\n") end -- And pick out a best friend for me! r = math.random(10) print("But my best friends is " .. friends[r])
This is exactly the same as the former version, apart from the way we set up the 'friends' array. In this case, the computer just assumes we want the labels to be numbers starting at 1 and ending at 10. Annoyingly, this means we have to count how many names we have in the array (10) so we can type in all those 10s in the rest of the code!
This is clearly rubbish. If we decide that Vlad is an ass, we might want to remove him and then we'd have to rewrite all the code! Ugh. The creators of Lua know this, so they gave us a gift: the '#' sign. friends = {"John", "Mary", "Kate", "Vlad", "Mimsy", "Kbun'daar the third", "Squiggles", "Spamford", "Mr Quackers", "Dickwings"} boink = #friends -- count how many things are in the 'friends' array -- store it in the variable 'boink ' for later print("My friends are:\n") -- Now print out all my friends for i = 1, boink do print(friends[i] .. "\n") end -- And pick out a best friend for me! r = math.random(boink) print("But my best friends is " .. friends[r])
When you have an array where all the 'labels' count up from 1 without skipping, you can use #array_name to ask 'how long is this table?' and it will put the answer in the variable you pick. Here we put it in 'boink'.
If we'd destroyed data by filling a container with 'nil' (which would look like friend[4] = nil -- bye Vlad!) this would no longer work! There'd be a gap between friend[3] and friend[5] so the computer would count until it hit that gap and then give you the answer '4'! Aren't computers silly? That was the hump!
This is the hard bit. Arrays and their more general form, the table, are the most complex part of Lua... as well as the most powerful. Today you learned about arrays, and how flow code allows you to process a lot of data with only a few lines (in this case using a simple numerical 'for' loop).
Next time we'll look at how arrays are a specific form of table, and what else we can do with them. Some words will be changed around a bit and it'll be all kinds of exciting. As ever, you can try out this code using this site. Just cut and paste it and play around with things. Get used to breaking code, figuring out what doesn't work and feel free to contact me if you still don't understand!
0 Comments
You can speak a language, right?
Okay, this is where things get a little bit more interesting. Let's look at a statement.
If I can code, I can call myself a coder, otherwise I'm a civilian. So what are you going to call me? What are you going to call my dog? See, you already understand flow. It's inherent in having a language, and in thinking.
Code is pretty much the same: banana = "I am a coder" if banana == "I am a coder" then print("Call me a coder!") end
There are a couple of things to note here:
== is a special operator that checks if what is on the left is the same what is on the right. This is different from =, which forces the thing on the left to equal the thing on the right. It's very easy to get these confused early on, but attempting to execute the code will give an error something like: main.lua:3: 'then' expected near '='
It's not particularly helpful, is it? A lot of error messages are kind of unhelpful, but there's still a clue there that the error is on the third line. A general rule is that when errors occur, it's best to look at the line in the error, or the line directly above it first.
So, yes, when you want to check if something equals something else, use ==. If you want to make something equal something else, use =. There's also that word 'end'. That is there to ensure that anything following that print("Call me a coder!") line isn't included in the 'stuff to do if the conditions are met' choice. We can make things more complex by adding an 'else' line. banana = "I am a coder" if banana == "I am a coder" then print("Call me a coder!") else print("Call me a civilian!") end
It works exactly like the previous code, but now provides a result when the 'if' condition isn't true.
Loops
Even with the 'if' statement, the code is still flowing straight from top to bottom. Boriiiiiiing. But it doesn't have to!
Let's look at another fun example every UK schoolboy in the '80s learned to type at stores with display computers . This will make you feel big and clever... or it did then. for kittens = 1, 10 do print(kittens .. " I am a big stupid computer from the '80s\n") end
The output here will be.
1 - I am a big stupid computer from the '80s 2 - I am a big stupid computer from the '80s 3 - I am a big stupid computer from the '80s 4 - I am a big stupid computer from the '80s 5 - I am a big stupid computer from the '80s 6 - I am a big stupid computer from the '80s 7 - I am a big stupid computer from the '80s 8 - I am a big stupid computer from the '80s 9 - I am a big stupid computer from the '80s 10 - I am a big stupid computer from the '80s
This is an example of a loop. Loops are really useful when you're working with a number of things and want to do the same stuff to each one of them. Think about bullets in a first-person shooter. You don't want to write a separate block of code for each bullet you fire, so you write a function, and then use a loop to go through them all and do stuff to each one.
The format looks a little scary to begin with, but let's break it down. for kittens = 1, 10 do
This sets up a temporary variable 'kittens', which then goes from 1 to 10, doing whatever is between the 'do' and 'end' each time it counts up. In this case, the line between 'do' and 'end' is:
print(kittens .. " I am a big stupid computer from the '80s\n")
You already know how 'print' works.
The only thing to note is that 'kittens' is thrown away after the 'end'. If you try printing it out after that point you'll get 'nil'. You can put more than one line those 'do' and 'end' pieces. Let's see how that works with another example. for i = 1, 100 do if i % 2 == 0 then print(i .. " is even") else print(i .. " is odd") end end
Try this one out, and see why a combination of loops and conditions is really powerful.
Don't worry about how I've staggered the various lines. Lua doesn't care about that at all. It's there to remind me which bits of code are inside loops and conditions. As you've probably noticed, the word 'end' pops up again. This is a 'keyword' in Lua and again means 'hey, whatever you started, I'm finishing it'! The format for 'if' statements is: if thing_happens then do_things end
The format for 'for' loops is:
for start_number, end_number do stuff_you_want_done_several_times end
That's about as complicated as things are going to get for a while. You've learned about data, you've learned about the flow of operation with loops and conditions. Next time I'm going to get you to write a function of your own and show how random numbers can be fun.
As ever, if you want to try any of the code out, you can use this site. If you have suggestions or comments, please let me know. I'll try and help as much as I can! Functions
A function is just a block of code with a name. Some will be created by you. Others are part of the language. In Lua, the language we're learning, there are built-in functions allowing coders to perform simple operations without writing having to write their own. print() is one of these. As you've already noticed, it output whatever text or variables you put in between those two brackets.
If you executed the code: print("Raspberry")
The output will be:
Raspberry
However, if you'd typed:
print(Raspberry)
...the result would be 'nil', which just means 'no data'.
Why is this? Well, anything you don't put in quotes is assumed to be a piece of data, an ingredient label. We've not created data with the name Raspberry so the value of Raspberry is currently 'nil'. Nada. Zip. Zilch. We could fix this by adding a line above that print() function to give us: Raspberry = "This is a bit of data labelled 'Raspberry'" print(Raspberry)
...and I'm pretty sure you can guess what the output would be!
See, you're starting to read code, too! More Built-in Functions
Let's define what functions are a little better:
Functions are labelled pieces of code which can take data, output data... or have other effects. There are quite a few functions which are part of Lua. You've seen print() so let's look at another one: math.floor() (Don't worry about the '.' between math and floor(). It just means that floor() is part of a group of functions which are all related to maths. There's math.random(), math.ceiling() and a host of others) The function math.floor() expects you to put a number (or a variable name) between the brackets. The function takes that number and spits it back out, but will have rounded it down to the nearest whole number. a = 2.5 b = math.floor(a) print(b)
This outputs 2.5 rounded down which is 2.
You'll notice that math.floor() is different from print() because we both pass something to it and get something back: in this case a value. If you look at the code above, we pushed the value we got from the function into 'b' using '=', saving it for later use. We could have written the whole thing like this: print(math.floor(2.5))
...and got the same result without using variables at all. In this case math.floor() would have just sent the value directly to print(). It's perfectly valid! There are often many ways to do the same thing. Welcome to coding.
Conclusion
As time goes on you'll be creating your own functions for things you want to do over and over again with different information, like adding numbers together, checking sentences for specific words, or displaying your art in a certain way.
It's a handy way to organize your code, and to stop you typing the same stuff over and over again, with the risk of making mistakes each time you do it. For now, all you need to know is that to use a function, you need to type its name, a pair of brackets, and probably one or more variable names between those brackets. If the function 'returns' something, then you'll often want to pass that into a new variable using '='. It'll usually look something like this: a = "Some data or other" b = "Yet more data" c = whateverFunctionNameWeAreUsing(a, b) print(c)
As ever, I hope this was useful. If you want to try it out yourself, you can use this web-site and type or copy the snippets of code there.
Numbers
Let's look at another little piece of code.
a = 10 b = 5 c = a + b print(c)
Can you guess what that does? It pushes two numbers into 'a' and 'b' and then adds those together, plonking the result into 'c' and then prints it out (15 if you're finding the maths tough).
Yes, you can use code like a calculator with the only difference being that some of the signs you learned in kindergarten arithmetic are slightly different. In Lua code (which is what we're learning here): a + b means 'add a to b' a - b means 'subtract b from a' a / b means 'divide a by b' a * b means 'multiply a and b' a % b means 'divide a by b... and give me the remainder!' a = b means 'make a contain the same thing as b'
Why the changes from English? Why make things more confusing?!
Well, taking multiplication, 'x' is a letter. As for 'divide', there is no 'divide sign' on a keyboard! The equals-sign is a different matter that we're not going to get into yet. Just know that when you see '=' it means 'make the thing on the left of the sign equal to the thing on the right of the sign'. Apart from that, things work much the same as writing out basic arithmetic. E.g. c = 12 / 2 * 3
The answer is, of course, 18.
But we can also force the computer to group calculations together in a specific order if we want by using brackets. Why would we do this? Mostly just to be clear what we want. a = (12 / 2) * 3 b = 12 / (2 * 3) print(a) print(b)
This gives us 18 and 2.
In the case of 'a' the process is 12 divided by 2 (which is 6) times 3, which is 18. With 'b' it's 12 divided by (2 times 3), which is 12 divided by 6, giving the answer 2. If that looks complicated just take a bit of time and do it step-by-step. Nobody's timing you. Words
When you are coding, pieces of code you want to be treated as text are called 'strings'. When you see the word 'string' people are just talking about "A piece of text like this".
a = "My dog is " b = "very sweet" c = "a pain in the butt" print(a .. b)
This is going to tell you what I think of my dog. The '..' in there means 'join this text to the other bit of text'. Notice I left a space at the end of "My dog is ". If I hadn't done that, the result would have been:
My dog isvery sweet
Ugh. The words 'is' and 'very' are squashed together which is enough to ruin my day.
If you want to print out a piece of text on more than one line, then you can use a 'special code' in your text: \n. It looks like this when used: print("This is a\npiece of text\nI am displaying on 3 lines")
The output from this would be:
This is a piece of text I am displaying on 3 lines
As I'm sure you've guessed, that '\n' thing says 'Start a new line please!' and allows you to write a one-line sentence in your code and have it turn out looking like third grade poetry. Woo!
Mixing Words and Text
You now have the power to do things with words and numbers. For example:
x = "My age is:\n" y = 109 z = "\nI'm feeling pretty creaky!" print(x .. y .. z)
Which will give you:
My age is: 109 I'm feeling pretty creaky! Conclusion
We've just learned about:
We've been using the print function for a while now, so it's about time we started learning about what functions are! I hope this was useful. If you want to try it out yourself, you can use this web-site and type or copy the snippets of code there. Introduction
Congratulations! You clicked on a link to something a lot of people consider to be well beyond their ability. Rumours of complex maths, arcane syntax and a host of other scary things put people off attempting to learn to code. This is a shame because even an idiot can learn to code. I am a living example of that.
My goal here is to prove that if you can write a sentence, you can code. In fact, that last sentence was practically code in itself! a = "Can write a sentence" b = "Can write code!" c = "Can't write code!" if a == "Can write a sentence" then print(b) else print(c) end
If you want to try this for yourself, you can go to the web-page here and type this into the box on the left, and then click 'execute'. If you type it exactly as shown (or cut-and-paste like a stinky cheater), you'll see the result:
"Can write code!" If you tried that out, then you've proven my point: you just wrote code, you didn't die, and your brain didn't explode. Congratulations! So What is Coding?
Coding is much like baking. You take ingredients, do stuff to them in a defined order, and end up with (something hopefully similar to) a cake. In the case of coding, those 'ingredients' are data: keyboard input, joystick buttons, text, an image, or anything else. Likewise, the output can be anything you want: a song, a game, or a piece of text.
Ingredients/Variables
In the example above, we had the line:
a = "Can write sentence" The 'a' is a 'variable'. It's like a label on an ingredient box that can contain anything at all. We use variables to store data and then perform operations on that data to get outputs we want. The '=' sign pushes the words "Can write a sentence" into the ingredient box labelled 'a'. After this, 'a' contains the words "Can write sentence". If we had typed: a = 10 ...then the variable 'a' would contain the number 10 rather than "Can write a sentence". A variable doesn't care what it contains. The variable is just a label. If you used a shoe-box and labelled it 'old DVDs' the world wouldn't end if you decided to fill it with socks, even though you might be confused on the day you move out. Also note that, like any label, what we chose as a label for the variable was entirely arbitrary. The letter 'a' has no significance at all. We could have written this instead: hedwig = "Can write sentence" The computer doesn't care what we name things (unless the name clashes with something else). We're just creating a label so that when we want to do something to that variable/data, we can refer to it in a sensible way. In this case... print(hedwig) ...will output "Can write a sentence" because we previously 'assigned' (filled) the box labelled 'hedwig' with those words. Note that it does not output the word hedwig, because the computer only cares about the contents of the data with that label, not the label itself. Conclusion
Today, you learned about variables (the ingredients of your code).
Next time we'll learn how to do more things with those variables. I hope this was simple and informative and that you'll join me for the next one! Good luck and ask any questions you want here. The Horns is a game I started writing - much like Spellrazor - when I felt a little discouraged by progress in BeMuse/Wardenclyffe. What began as a two-week fun project turned into 9 months of the most intense writing I've ever done. I'm also particularly pleased with how the soundtrack turned out.
The game is now available on iOS, with free versions on GameJolt and Itch.io. More details are here on the main game page, together with links to the game itself. I'm now back making The Project That Will Not Die, when I'm not thinking about other fun things to do! Let's See What's Out There...So, I said I'd do this a long time ago and never did. This game has been a weird, squidgy, hard-to-grasp thing for far too long, and getting something out at some point seems necessary to get the darned thing to 'bake'.
Here it is: Windows Mac It's not a finished game. It's barely begun, really, but I wanted to see if anyone else out there likes the world and the mood, because those things are what I live and breathe for. Things to be aware of: - Unity seems to have munged the keyboard controls on some PCs, making movement feel... weighty. This is odd, and wrong. - The world is not finished. It is far more blank a canvas than it should be right now. - The Book is too wordy. The intent is for it to become 100% visual. If you like where this is going, let me know. If you don't, you can let me know, too. I'm going to take a 'game jam' break from this game for a little bit in order to get a clearer view on what needs to be done with it. In the meantime, I hope the little cottage fire keeps you warm, and you enjoy the music. Why Are You Doing This? My shaders for Wardenclyffe/BeMuse haven't compiled yet. Some of them are really big. As such, I could twiddle my thumbs, or be angry at some bigots on the internet. Instead, I thought that I'd write an opinionated little piece on Fable, what makes it special to me, and what I'd like to see persist in some form if/when a new version is made. For those who didn't know, I was one of the blokes who started Fable back when it was 'Project Ego', so I've lived in Albion for quite some time. As such, here are my musings, in no particular order: 1) Keep the Charm & Keep it British
Fable was a peculiar game. People may talk about the NPC interaction, the combat, not planting acorns, and the total lack of any challenge, but none of these gave players warm and fuzzies in their tender parts. For that, one needs to realize that we crafted the world's first 'Walking Simulator With a Bit More To Do'. That lack of challenge gave players the opportunity to wander around aimlessly, absorbing the waving grass, exotic locales, ambient chatter of witless country-folk, permanently moody palette, and Russ's magnificent score, while also casually decapitating chavs holding Stanley knives. Oh, and if you got that joke then you'll understand the other part of this little screed: keep it British. No, I don't mean the curtain-twitching, finger-pointing, racism-laden-toxic-wasteland of Brexit Britain (or 'Poundland'). I mean something closer to the idyll evoked by the lovely 2012 Olympic ceremony. Admittedly, if we won the Olympics today we'd just have a swarthy-looking wicker man burning in a field. Britain is filled with a rich variety of folk-customs, dialects and casual violence. Keep that. 2) Folk Tales, Ghost Stories and Weird Fiction, Not Fantasy Fable was called Fable for a reason: we didn't think Folklore or Folktale were good titles. But, if we could have called it one of those we probably would have. I read way too much Fantasy (with a capital 'F') in my early years. After a few years all the back-of-the-book blurb started to blur into a melange of similar-sounding nonsense: "The Wielder of the Dwar'K'N'Giiin must push back the Squigaaar in a desperate attempt to Qwerty the Uiop! Only through gathering his trusty band of violent bigots can he..." etc. Writers: nobody believes that - in a world where everyone speaks English the entire time - you have things named Dwar'K'N'Giiin. It sounds like someone responding to the question "What's that place over there?" while on an exceedingly large dose of DMT. Do you know the Hebrew for Holy Grail? No. See my point? No? Ah. Well. Um. Think about it. Fable's influences were Jim Henson's 'The Storyteller', 'The Princess Bride', 'Labyrinth', 'Monty Python and the Holy Grail' and 'Legend', as well as a large dose of Terry Pratchett, Michael Moorcock and H.P. Lovecraft. You'll notice a distinct lack of traditional Fantasy authors there. So, if you're making Fable, you're making a Fable, and not High Fantasy. Other people are doing that exceedingly well already and it's probably unwise to assume Fable's audience is exactly the same. It isn't. 3) No Orcs Please. No, Really. This one is particularly important to me. No orcs. Please. No bloody orcs. Or elves. Or anything else from Tolkien. Why? Because they are trite... oh, and they're Tolkien's. Note that I didn't write "Please don't use Imperial Stormtroopers or Dementors". People would say: "Huh? Why would you put those in Fable?" Yes! Exactly! They belong to someone else! Why would we add them? Because we are lazy? Inspirationally bankrupt? We wish to bait sizable legal teams? Actually, those are three very good reasons. In addition, Fable's monsters were monsters, not cultures. - Hobbes were twisted children, fed unspeakable meat in the dark. - Hollow men were the tortured souls of the dead, wandering the world animating nearby corpses. - Balverines were my inability to read a street sign in Wandsworth (no, really). And sort of werewolves. But why is this important? Well, if you're making monsters so they can be pummeled with a frying-pan, it's probably a good idea not to just make them exotic, inscrutable foreigners. As soon as you make your monsters a people or race with their own civilization, language and values you put the player in the tricky position of being an imperialist with a deadly weapon and a silly hat. A bit like the British were for most of the 19th century. So. No. Orcs. 4) Keep Things Vague - It's More Realistic A lot of High Fantasy makes the weird assumption that lore is fixed, known and historically accurate. "In the third age of Kranbaroon, 3 kings set out..." "Hang on. Where are you getting this from, Mr Farmer?" "I... um... I read it in a book." "Really? So there's widespread literacy in this world, is there?" "Um. There was a school in Bowers..." "And you remembered all this stuff about what happened 3000 years ago from school" "Yes" "You were 5. You're now 50. Really? I don't believe you." "Um. Arrrr? Oim a farrrrmerrrrr" "Much better." The assumption that anyone in the world knows what happened all that time ago with any accuracy is nonsensical. So, don't give your NPCs an encyclopedic knowledge of the world. In fact, you probably shouldn't give pre-industrial people books at all. We all know that leads to revolution. Keeping things vague also means your monsters are more mysterious: "What's that?" "I don't know! I'm scared!" ...is far better than... "What's that?" "It's a Squigar Hatchling. Level 6 by the looks of it!" If you take care, your lovely fans will have spaces they can fill with 'reckons'. Plus, there is a lot of room for misinterpretation and embarrassment all round. And how British is that? Very British. See, I added an extra sentence to undermine the joke. Because that's funny. Which leads me to the trickiest point. 5) Don't Take Yourself (Or Humour) Too Seriously Albion is a silly place. It is full of silly people. But, we didn't set out to make a 'comedy' game, which is why there are very few actual jokes. There are plenty of nods and sniggers into the palm of the hand, but not jokes or punchlines. This is important: If you make a game designed to be a comedy, you need to be funny at all times or else you are failing. It's the difference between being a professional stand-up comic and an amusing wit at a party. One is tortured, drinks too much and wants to die when their audience isn't as good as the previous night... and the other is the comedian. No, wait. See - that's exactly my point. I decided to turn that into a joke and ruined everything. Don't do that. With any luck, it's not necessary as your staff are silly enough already. Conclusion I don't know for sure if a Fable game is being made somewhere out there. I would very much like to play one without knowing everything about it, tutting my way through thinking "Oooh. We probably should have fixed that." I hope this mini-screed is received in the spirit with which it was written. In a tooth-grinding frenzy of semi-literate rage while pointing angrily at eggs on Twitter. See that's also a joke... oh, I give up. This week has been a preparation for the imminent 'Playable Teaser' version of Wardenclyffe.
Yes, really. No, I'm not joking. I know it's been a long time. I have friends playing it and discovering the stupid bugs that only appear when you let someone else play around with your stuff. Yay. This summer, my wife played my game for a few moments and said: "Why the hell are you doing this on mobile. That's is stupid." So, in grand Fluttermind-ey tradition... I... um... rewrote a vast amount of stuff, and made the game a free-roaming, 'bigger' thing than it was before. BUT! Before you batter your foreheads to jelly with frustration, the good news is that it means I'm actually able to do the thing I wanted right at the beginning, the thing that people have been bugging me for since, ooh, 2013. I can now put out a testbed you can all play with. Soon. Major bugs notwithstanding, in the next week or so. It's not going to be a finished game, or even much of a game. Most of the rituals I've put together need more work, so there's a lot to be done. But the important thing - getting people to move around my new world and perhaps speculate as to what might be coming - that's entirely possible, and really, really soon. So, yay? Yay. Speaking in PublicAnyone who knows me knows how I feel about public-speaking. While I am a reasonable practitioner, the level of discomfort and self-doubt it elicits rather stifles any benefits the exercise might produce. So, by and large, I don't do it. Nevertheless, I was asked to speak at this year's GDC, and after attempting to offer a witty diatribe on my own particular hobby-horse (how to revivify magic in games) and receiving some raised eyebrows, a certain GDC spokesperson convinced me this was far too esoteric a subject for someone who has been in the industry for so long, and has yet spoken so rarely about any aspect of it. Thus, on Tuesday 28th of February, I shall be giving this lecture in room 2009, at 1:20pm: schedule.gdconf.com/session/from-indie-to-fable-back-again-30-years-of-wisdom I'll be doing it in public. Where there are cameras. May the Goddess be kind and save me from both an untimely embolism and renal failure, live on stage. Imposter Syndrome vs. Dunning KrugerPeople familiar with Impostor Syndrome are familiar with its general effect: the feeling that somehow, somewhere, someone is is going to point out and correctly identify you as a phony, because they suddenly realize (quite accurately) of course, that you're not an embodiment of physical or intellectual perfection. Dunning-Kruger on the other hand is that strange over-confidence granted to the terminally ignorant - those so ignorant that they have no concept of quite how high their ignorance is on the ignorance scale (which runs from 'Trump' at the highest to 'Hitchens'). How do you work out where to sit on this continuum? At one end, you risk crippling inactivity. On the other, unwarranted braggadocio. And of course, neither is truth, and even if it were, it would be a mutable truth, constantly in flux and flow. I think accepting this muddiness is ultimately the most useful thing to do. Or to ignore it. That works, too. Either way, I think it's best to understand that one is imperfect, and to simultaneously go out into the world and do something that at the very least least allows time to note your passing. Wardenclyffe (formerly BeMuse)BeMuse is no more. Long Live Wardenclyffe! Same project, though. As ever - I'm regretting ever making this a 3D game. While it does wonders for the visuals (sometimes) and grants me the opportunity for a novel control interface (you can rotate any scene 360 degrees), it also makes things many times more difficult. The good news is that I now have the Book mechanism in the game, several demons, rituals work, and so on. The bad news is that I'm not happy with the general 'adventure' flow, and need to go back and revise several elements. Making an adventure game (open room, use the 'Quigar' on the 'Woozle', open new room, repeat) is not really natural to me. Adventure GamesWhen I began this game, the intention was to make it 'a pleasant walk', like Proteus, with an open world, seemingly nothing to do, and many secrets learned while you ambled around.
The problem this poses is that it sets the primary action for the game as 'do nothing'. It turns out I'm not very good at this, as it shifts the game into a 100% experiential mode which makes me deeply uncomfortable. It's also very boring for those who don't 'get' what you're trying to do. As a result, the game has grown increasingly 'Adventurey'... which solves certain problems while causing others. Adventure games avoid 'Death By Meandering Boredom' by gating sections. This provides a tension ('how do I get that wheel to turn?') and resolution ('use the oil to remove all rust... unlike real oil'), which is relatively satisfying, but frequently errs into absurdity ('how come I can't use the tire iron to open this door, but I can use a piece of broken pipe' and 'why did that item disappear from my inventory... oh, I guess I never need it again'). Items in Wardenclyffe don't have that weird impermanence. They are multi-functioning, and remain in your inventory unless you use or burn them or Demons do something nasty. If they are lost, they are all re-fillable in some way or other. Ultimately, though, an 'adventure' game is all about gating flow, and so more of Wardenclyffe's island content is gated than I had originally intended. This works to some extent (a newcomer won't be wondering what the hell to do next, as they are corralled a little more than they were), but I feel that this direction suggests the game is more traditional than intended, and may confuse people ('Hey, what the hell is up with all this ritual magic weirdness? I just want to put oil on rusty wheels!'). Anyhow, I digress. I am currently re-jigging the adventure's order a little, and once that is clarified, I shall continue with my efforts to get this little horror out in a timely manner. |
AuthorFluttermind’s director, Dene Carter, is a games industry veteran of over 25 years, and co-founder of Big Blue Box Studios, creators of the Fable franchise for the XBox and XBox 360. Archives
April 2022
Categories |