Link Bar

Home | Games | Programming | Tutorials | Donate | Legal (These are mostly empty right now. Placeholders!)

warning code

This website contains adult content.

Wednesday, February 29, 2012

Day 13: TECS, Chapter 1, Part 2.

Zach gave me a suggestion that I thought would work.  After half an hour of Googling, it still did not work.  Back to the books!

I picked up exactly where I left off, on the testing scripts.  Here is a test script from the textbook (testing the Xor gate which I discussed yesterday):

load Xor.hdl,output-list a, b, out;   
set a 0, set b 0,   
eval, output;   
set a 0, set b 1,   
eval, output;   
set a 1, set b 0,   
eval, output;   
set a 1, set b 1,   
eval, output;
Oh, man.  This is easy, after understanding the chip itself!  Just load up the chip, specify what goes onto the output list (in this case, our values for a, b, and the evaluated outputs), then set a & b to all combinations they could be, evaluate the chip's function, and output it.  Like unto a pie.  Sure enough, we get:

a | b | out   
0 | 0 | 0   
0 | 1 | 1   
1 | 0 | 1   
1 | 1 | 0 
Hot cha.  What's next?

Next is what the chips are and how to build them.  Easy-peasy, quick an' breezy.  Well, up until we get to the 4-way 16-bit multiplexor, anyway.  The Alert Reader will recall that multiplexors gave me a small headache yesterday, but today I only got slightly narrowed eyes and increased attention.  Demultiplexors were a cinch after that; it's just the same thing, backwards!  Building these exclusively out of NAnd gates?  Ehh, not so much.

I just learned this yesterday.  Now you want me to build it with
two pop tabs and a paperclip?  CHALLENGE ACCEPTED.
(From The Elements of Computing Systems, by Noam Nisan & Shimon Schocker)

But that's the end of the chapter!  Now for the project:  build all the chips/gates mentioned in the chapter out of NAnd only (that would be Not, And, Or, Xor, Mux, DMux, Not16, And16, Or16, Mux16, Or8way, Mux4way16, Mux8way16, DMux4way, DMux8way).  If this were a real course, I'd have a week to do this, so let's see how I feel after doing Not, And, Or, Xor, and Mux.  Then I'll sleep on it and try the rest tomorrow.

Ready?  Go!

First up, Not via NAND.  Easy enough, right?
IN in;
OUT out;
PARTS:
Nand(a=in, b=in, out=out);
Ha ha, NAnd already does the heavy lifting for me!  Load the test script, and:  SUCCESS!  Now for And via NAnd.  Whoah, I almost thought I could just put a Not at the end, but herp-a-derp, that wouldn't work because NAnd isn't the...  Wait.  No, that's exactly what I want!
IN a, b;
OUT out;
PARTS:
Nand(a=a, b=b, out=r1) //the R is for RESULT, get it?
Not(in=r1, out=out); //let's make it more explicit, shall we?
Nand(a=r1, b=r1, out=out);
Load the test script, make sure I didn't do anything stupid, and... SUCCESS!  I'm on a fuckin' roll!  Now for the inclusive Or.  This will require gymnastics...wait, no it won't, because I can just put Nots after a & b before they go into NAND, and poof!  Let's be super explicit again:
IN a, b;
OUT out;
PARTS:
Nand(a=a, b=a, out=nota);
Nand(a=b, b=b, out=notb);
Nand(a=nota, b=notb, out=out);
Too sexy, too sexy!  This is going smoothly.  Now, I can't help cheating for Xor, since I was already given a diagram and the HDL for it; what I can help is whether I cheat further by simply copying, or instead translate the existing HDL into Super-Exciting Mega-Explicit NAnd-Only Language!  (I'm not shouting, the "!" is just part of the phrase.)  The tough part here is now no longer coming up with the HDL, but keeping my terms straight.  I'll make a new diagram and divide it up into three phases like the old one:  the Not phase, the And phase, and the Or phase, finally leading to the output.  Here it is:
I haven't felt this enlightened since I learned why
the square root of two is necessarily irrational.
Hey, r1 & r2 just get Not'ed twice - at the end of the And phase, and at the beginning of the Or phase - which means... carry the one... I can skip steps.  As long as I skip the right ones.  Now I'm actually learning!  Doing that, my new Optimized NAnd-Only Xor HDL is:
IN a, b;
OUT out;
PARTS:
Nand(a=a, b=a, out=nota);
Nand(a=b, b=b, out=notb);
Nand(a=a, b=notb, out=r1);
Nand(a=nota, b=b, out=r2);
Nand(a=r1, b=r2, out=out);
Instead of crossing my fingers, I'ma crack my knuckles.  Crackita-pop!  Plow!  Annnd... SUCCESS!  In the same number of lines of code as their original Xor gate, which needed Not, And, and Or!  HOO-HA!

Uh-oh.  Now for Mux.  OK, there's a reason I decided to make this the last one for the night, and it's not just that it's 10:22.  You're on a roll, just keep it going, man.  Think out loud.  Or on paper.  Erm, in type.  Whatever.  You've got your a in, your b in, and your selector, and the selector decides which input comes through.  I can do this.  Think of it in terms of the shortcuts, first.  Then blow it up into NAnd-Only, then simplify (if you can).  OK.

Dammit, now it's 10:42, and I've been staring at this for 20 minutes and thinking, "No, this won't work.  No, that won't work.  Shit, what am I gonna do?"  Urge... to cheat... rising... WAIT.  Re-draw the truth table so it's less confusing.  OK, now it looks like an Or for a & sel when sel=0, and it looks like an And for b & sel when sel=1.  Good, you can work with this.  Keep going.  All right, it can't trigger the And for b & sel when sel=0, so... run an And from sel & b (result:  selAndb).  Duh.  Keep going.  Run an Or from sel & a (result:  selOra).  Now we've got selAndb which gives b when sel=1 and 0 when sel=0; and we've got selOra which gives 1 when sel=1 and a when sel=0.  Good.  Paragraph break.

Now compare your "mini" truth tables with each other.  Wait.  Duh.  You're barking up the wrong tree here.  Stop trying to make it explicitly perform based on why you know it ought to go, and make it perform based on why it needs to go. Back up and brute force the fucker, then clean it up in post.  You'll be fine.  OK.  Start with sel&a&b=1.  Work up from there.  Run them all to And gates, then make those come out how they ought to do.  Then funnel them into bottlenecks so that you get what you need at the end.

OK, finally.  I got it.  It's 11:50, and I fucking got it.  First, I just did everything in terms of "and," "not," and "output" - not HDL-wise, just logic-wise.  Like, I wrote on a piece of paper:
s&a&b=1
s&a&~b=0
s&~a&b=1
...and so on.  Then I drew up HDL-like parsings of those functions, and tried to make them as similar as possible.  I noticed that I could capture three correct outputs with only (s*a)*b (call it x), four more with (s+a)*b (call it y), and the last one with (s+a)*~b (call it z).  (For the uninitiated, + = or, * = and, ~ = not.)  Then I drew up a truth table for s, a, b across from x, y, z, and also drew up the output.  I noticed that y predicted three of four outputs of 1, and z got the other one when s=0.  The x function was useless, so I discarded it, and made x':  y+(z*~s).  (Fun Fact:  I accomplished this step by folding over the s/a/b section, MAD Magazine fold-in style!  Now that's thinking outside the box!)  Finally, I drew up a schematic for a, b, and s inputs, into y and z functions using And, Or, and Not gates, then put it all through to the x' function, and that gives the output.  So we have:
IN a, b, sel;
OUT out;
PARTS:
Or (a=a, b=sel, out=sva);
And (a=sva, b=b, out=y); //these lines describe the y function
Not (in=b, out=notb);
And (a=sva, b=notb, out=z); //these lines describe the z function, and I can re-use sva from above
Not (in=sel, out=nots);
And (a=z, b=nots, out=zAndNots);
Or (a=y, b=zAndNots, out=out); //these three lines describe the x' function, which is just output
OK, let's see if that runs... SUCCESS!  Holy carp, that was insane.  OK, that's my proof of concept, now to break it down into NAnd-Only.  Picture first?  Picture first!
And to think, this is still the easy part...
Whoops, that "&s" at the bottom coming out of the first NAnd should read "~s"; and I need to label some results r1, r2, and r3; and I should also label that bit that comes out notzAndNots when you come anticlockwise around the lower-right corner.  Not taking another picture, though.  Now for code:
IN a, b, sel;
OUT out;
PARTS:
Nand (a=a, b=a, out=nota);
Nand (a=sel, b=sel, out=nots);
Nand (a=nota, b=nots, out=sva);
Nand (a=sva, b=b, out=r1);
Nand (a=r1, b=r1, out=y); //BAM!  That's y, now for z.
Nand (a=b, b=b, out=notb);
Nand (a=sva, b=notb, out=r2);
Nand (a=r2, b=r2, out=z); //Sweet.  Now to wrap it all up!
Nand (a=z, b=nots, out=r3);
Nand (a=r3, b=r3, out=zAndNots);
Nand (a=y, b=y, out=noty);
Nand (a=zAndNots, b=zAndNots, out=notzAndNots);
Nand (a=noty, b=notzAndNots, out=out); //done!
Plug & chug, and... BAM!  Success on the first try!  And it only took me - TWO AND A HALF HOURS?!  Whatever, I'm done now.  By the stars, I've got a lot to do tomorrow, though... I'm starting to see why hardware designers burn out and how programming conventions become insane.

Tuesday, February 28, 2012

Day 12: Poking around the internets.

Zach left a helpful link in a comment on yesterday's post, and after reading through the whole thing, I have a slightly clearer idea of what's going wrong.  See, line 187 says:
wcx.lpszClassName=WINDOWCLASS;
...and the error returned is:
error C2440: '=' : cannot convert from 'const char [7]' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
So, OK, at least that's not gibberish to me any more.  And way, way back up in line 15, when I wrote:
#define WINDOWCLASS "Fetris"
...that must have made "WINDOWCLASS" into a constant.  OK.  And on line 187, I'm not certain what that "wcx" bit is all about, but "lpsz" means that I'm setting a long pointer to a null-terminated string - so it wants ASCII.  Right?  But... if it's trying to use a long pointer to a constant wide string... that means it wants Unicode.  So I'm telling the machine to do something with ASCII, and it's trying to do it in Unicode, and that's the problem?  I think so.

I don't know how to fix that, though.  Either I need to do something different in the WinMain function (which I'm not sure what that would be), or I need to change my definition up at the top (and I'm not sure how I ought to do that).  Well, this is what I get for using someone's code from over eight years ago.  And holy carp, I spent over half an hour just typing out the above.  Well, more like five minutes typing and revising it, and 25 minutes cradling my head trying to sort everything out.  This is in addition to the hour I spent poking and prodding and reading and trying to make it work.  And I'm still probably missing something (like a real programming course).  Fine.

I'm going to play around with that NAND to Tetris thing.

Got the hardware simulator running after installing the 64-bit version of Java (had to consult their forums to find out I needed to do that - apparently the version I had before wasn't good enough).  Got the Hardware Simulator running, and figured out how to load and test gates/chips in it.  Nice.  Project 00 complete, on to Chapter 1!

I started flipping through the slides for the lecture, figuring I'd read the chapter after I got an idea of what I'll be learning.  Right away, multiplexers stumped me (well, on slide 9 of 24, anyway).  I could not for the life of me figure out what was going on in that truth table.  Wikipedia to the rescue!  (By the way, is Wikipedia being wonky for anyone else lately?)  Man, multiplexers are easy once you know that the selector picks which input gets to be translated into output!  (I did not know that more than five minutes ago.)  The rest of the slide show was easy after that - but now I have to basically re-learn all of my logic using NAND only, which is doable, but confusing.  Whatever, that's the point of the exercise.

Reading the chapter itself, I further learned what the "canonical representation" of a Boolean function is (it's the inclusive disjunction of all the possible values which yield "true" on the truth table).  I've also got the hardware description language (HDL) down.  See, twenty minutes ago, this was gibberish to me:
/* Xor (exclusive or) gate:If a<>b out=1 else out=0. */  
CHIP Xor {
IN a, b;
OUT out;
PARTS:
Not(in=a, out=nota);
Not(in=b, out=notb);
And(a=a, b=notb, out=w1);
And(a=nota, b=b, out=w2);
Or(a=w1, b=w2, out=out);
}
But now I get it!  See:
/* Xor (exclusive or) gate:
If a<>b out=1 else out=0. */
CHIP Xor { //we have a chip, called "Xor"
IN a, b; // it has inputs "a" and "b"
OUT out; // it has output "out"
PARTS: // these are its parts
Not(in=a, out=nota); // A "not" gate with input from a, outputting to "nota"
Not(in=b, out=notb); // A "not" gate with input from b, outputting to "notb"
And(a=a, b=notb, out=w1); // An "and" gate with input from a and notb, outputting to "w1"
And(a=nota, b=b, out=w2); // An "and" gate with input from nota and b, outputting to "w2"
Or(a=w1, b=w2, out=out); // An "or" gate with input from w1 and w2, outputting to "out"
}
I feel smarter already!

OK, I've been doing this for hours, I'm halfway through the first chapter, and this is like a week's worth of work anyway.  My brain is full.  G'night, everybody!

Monday, February 27, 2012

Day 11: Fetris bug-huntin'.

Before I dive into the "actual" errors, I decided to fix the "pretend" errors (i.e. the errors caused by my human error, like typos).  In addition to the errors I found last week, I found one case of necessary capitalization, one case of extra comma (which caused three other syntax errors in the same line), one case of super-exciting extra "}", and one case of a comma that should'a been a semicolon.

I take solace in the fact that I was able to solve my own syntax errors (which were the larger portion of the errors generated) simply by looking at them.  I said, "Oh, that's obviously what's causing the problem," attempted to compile it once again, and BAM!  Error gone!  There was one case where I put a 1 (one) instead of an l (lower-case L), but... look, they look the same.  I would say to them, "You want an ice cream cone?"  Both of them say, "Yes."  Everything that got more complicated than that, I checked against the original post, and yeah:  did it exactly like he said (except for the one part where I kinda-sorta skipped a line).

I am unlikely to get support from Evil_Greven himself on this, but that's OK.  It wouldn't be a learning experience without like six bajillion hurdles.  My high school chemistry teacher, Dr. Landorf, once gave us a universal problem-solving method.  I forget most of it, but the two parts that stuck with me were:  "A problem is not when you simply have to get from A to B.  A problem is when you have to get from A to B and have no idea how.  Otherwise you merely have a number crunch," and, "When you  can't find the solution to a problem, start at the answer and derive the question."  I couldn't find the list itself on the internet (this was a handout from before the internet was everywhere, and apparently drew from several sources), but I did find a really great joke while I was looking:
A mechanical engineer, an electrical engineer, and a software engineer are in a car that breaks down.  The mechanical engineer says, "Maybe is's a stuck valve."  The electical engineer says, "Maybe it's a dead battery."  The software engineer says, "I know. Let's all get out and get back in again, and see if that fixes it."
BWAHAHA!  Oh, what a groaner!  Love it!  OK, so I've now got it down to three errors:

1>------ Build started: Project: Fetris, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\d\documents\visual studio 2010\projects\fetris\fetris\main.cpp(187): error C2440: '=' : cannot convert from 'const char [7]' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\d\documents\visual studio 2010\projects\fetris\fetris\main.cpp(196): error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [7]' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\d\documents\visual studio 2010\projects\fetris\fetris\main.cpp(260): error C2664: 'BitMapObject::Load' : cannot convert parameter 2 from 'const char [11]' to 'LPCTSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>  BitMapObject.cpp
1>  Generating Code...
Much more manageable than the two dozen I had on Friday.  I can handle this.  I think.  I Googled the first error, in accordance with the prophecy (the prophecy is "JFGI") and found this thread, which led me to this other thread., which led me to this excellent article.  The article is called "Making Wrong Code Look Wrong," and the author goes on about the true history of Hungarian notation (which I did not know was a thing until today) and how to be your own best friend with your programming conventions.  Since one of my errors from this very day was an extra "}" nestled amongst some 50 lines of nested "how to make teh bloxxxorz," I really wish that Evil_Greven had followed rule 5:  "Don't put closing braces more than one screen away from the matching opening brace."  It would've been gallons easier to spot that extra brace, had he done so.  But no worries!  I learned a valuable lesson.  And I bookmarked that guy's blog, because it's rad as Hell.


OK, so the guy in thread number two said that I could either switch the compiler settings to multibyte character set, or use unicode strings instead (the recommended option).  I can't find that option after combing through them all, and I don't know how to make it unicode compliant quite yet, so I'm calling it a night.  It's quarter after ten, I have learned some things and done some things, and I'm happy.


For now.

Sunday, February 26, 2012

Down the Rabbit Hole...

I started reading the textbook for The Elements of Computing Systems, it's very accessible and I recommend it to anyone who wants to know more about how computers work.  Here's their course map:
From The Elements of Computing Systems, by Noam Nisan & Shimon
Schocker (free online course) http://www1.idc.ac.il/tecs/book/preface.pdf

I just read through the preface & introduction, and I can't wait to get started!  I'm already learning new things, like the different levels of abstraction (as represented in the image above, and the text block below) that really go on inside the box.  I used to think that you just had your programming language, which was made "binary compatible" (whatever that would mean) by the compiler (whatever that did), and the computer ran on binary.  Well, binary and smoke (if you let the smoke out, the computer stops working).  Lo and behold, the introduction comes to the rescue, curing me of my misconceptions:
If you have taken any programming course, you’ve probably encountered something like the program below early in your education. This particular program is written in Jack—a simple high-level language that has a conventional object-based syntax.
// First example in Programming 101:
class Main {
function void main() {
do Output.printString("Hello World");
do Output.println(); // New line.
return;
}
}
Trivial programs like Hello World are deceptively simple. Did you ever think about what it takes to actually run such a program on a computer? Let’s look under the hood. For starters, note that the program is nothing more than a bunch of dead characters stored in a text file. Thus, the first thing we must do is parse this text, uncover its semantics, and reexpress it in some low-level language understood by our computer. The result of this elaborate translation process, known as compilation, will be yet another text file, containing machine-level code. Of course machine language is also an abstraction—an agreed upon set of binary codes. In order to make this abstract formalism concrete, it must be realized by some hardware architecture. And this architecture, in turn, is implemented by a certain chip set—registers, memory units, ALU, and so on. Now, every one of these hardware devices is constructed from an integrated package of elementary logic gates. And these gates, in turn, can be built from primitive gates like Nand and Nor. Of course every one of these gates consists of several switching devices, typically implemented by transistors. And each transistor is made of— Well, we won’t go further than that, because that’s where computer science ends and physics starts.
Computers are like way faster than I ever realized.  Also, no wonder my framerate starts chugging when I jack up the draw distance.

I also read the tutorial on the hardware simulator, and the lecture notes on the introduction.  I'm calling it:  my brain is officially full.  Project 00 can wait until, I dunno, whenever I get sick of trying to fix Fetris.  Catch you crazy cats later.

Friday, February 24, 2012

Day 10: FETRIS (work in progress)

I went through Evil_Greven's tutorial on how to build a Tetris clone in an hour with C++.  I followed his instructions using Microsoft Visual Studio 2008 Express.  I'm much less intimidated by C++ now than I was two days ago, but I feel like I'm back in the 5th grade again, learning Spanish for the first time.  "Yeah, I know what 'buenos días' means.  'Pantalones?'  Oh, man, this is gonna be easy.  Wait, why is N-yay a totally different letter from N-eh?"  Seriously, you guys, for the longest time I thought that "vedevaca" was the name of the letter, not just "veh" - I didn't learn about "b de burro" until I was in freakin' high school.  Same with "y griega," I didn't know it was as opposed to "i latina" until I dated a girl from Uruguay and she told me.

I guess what I'm saying is, I need to date a programmer now.  No, that is not the most cynical use of dating ever.  But, uhh... I can't come up with a more cynical one.  Because I'm so totally not cynical.  Double-promise.

Anyway, I got through with no problem, except that VC was telling me that I hadn't declared shit which I had so too declared, just look.  But whatever, I didn't let it bother me, and I kept on chugging through.  I would highlight everything that turned blue and hit F1 to bring up the help, and read through those articles.  This made it take like three hours instead of one, but that's OK.  Then I went to compile it at the end, and that's when shit hit the fan.

As my grandma would say, "Errors out the yin-yang."  Yes, my grandma talks like that.  No, it's not cool if you say that while being under 70 years old.  Yes, that's a moving target; it won't be cool for 70-year-olds to talk like that when you're 70.  Modern medicine has made it culturally impossible for us to be ironic by speaking in the fashion of young people when we are in fact old people.  And no, current old people do not suffer from this flaw in our age-based system of behavioral standards.  But hey, that's what you get for longevity.  Stupid double-standards.

ANYWAY.

I dutifully read the errors and went to the lines of code where they allegedly occurred.  Ahh, shit, I forgot a "( )".  Oh, damn, a legit typo; must'a fat-fingered it.  Whoops, left out a semicolon!  And... that... I can't...
fetris\main.cpp(187): error C2440: '=' : cannot convert from 'const char [7]' to 'LPCWSTR'
What the blue fuck does that mean?  OK, let's go to line 187:
wcx.lpszClassName=WINDOWCLASS;
Right.  And what did Evil_Greven say to do here?
wcx.lpszClassName=WINDOWCLASS;
All right.  Double-check each and every character, and... yup, that's exactly the same.  And what other sage advice does VC have to give me on this?
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Ohhhhh-kayyyyy... I know what that means and everything.  And I've got 21 more errors to go.  That's not bad, for over 600 lines of code on my first day.  Wait.  Hold on.  Remember Alexander the Great.


This tutorial was written in 2003.  This might be nobody's mistake, just a case of mismatched standards.  Maybe.  But if it is Evil_Greven's mistake, it's almost certainly beyond my ken to fix it now.  Dammit.  I really wanted to play my very own Fetris.  I even made the bitmap for the blocks!

Whatever, I'm putting this aside for now.  I'll come back to it over the weekend and see what else I can learn.  It's not like those errors are going anywhere, right?  Besides, there's nothing like fixing a broke-ass machine to get you familiar with its workings.  But for now, I'm done with this.  You get the Tetris God:


Also, you should check out Hatetris.  Because I just bet you're a masochist.

Thursday, February 23, 2012

Day 9: The Alexandrian Solution

After reading some more about the Playskool programming that is RPGcode, I grew despondent at the idea that anything I learn here is going to need to be re-learned or un-learned whenever I get my Big Boy programming in gear - because some things will work and some things won't, and I'll probably have to learn which is which one by one.  Hmm... let me think for two seconds here.

OK, I'm not doing that.

So has all this been a waste of time?  Absolutely not.  I've learned a lot in the last eight days, not only due to the reading I've been doing but also by playing around with things.  I now have a much clearer picture of what goes into a video game.  Look, here it is:

Green means "I get it."  Purple/Blue means I'm fuzzy on it.
Red & gold mean I'm fucking clueless.

So yeah.  There's this big, mysterious hurdle right there in the  middle, and it turns out it's the part that actually holds everything together.

I don't know how to untie this Gordian knot - at least not in any way that I would consider to be an effective use of my time - so I'ma straight-up cut the fucker in half.  I'm just gonna learn how to program.  It's a valuable skill, it will help me accomplish my goals, and it's bound to be less time in the long run.  I feel farther from finished game, but I know I'm closer to good game, and that's better to my mind.  However, this means that my daily progress is going to be much less interesting.  Actually, looking back... maybe not.

I'll probably also be able to research the things I'm interested in more directly, and take better advantage of Stack Exchange.  We'll see how this goes.

...ahem.

Doop a doot doo.

What?  You're still here?  Oh, right.  Progress.  Y'know, that thing I said I'd do a little bit of every weekday.


There was a minor tab explosion and I took a walk around the internet.  I learned a little bit o' FORTRAN way back when I was doing undergrad theoretical physics research (ugh, I let the professors write my bio and now it's stuck like that forever... that's what I get, I guess), so this shouldn't be too difficult.  Although I bet it'll be much harder than writing a program that brute-forces a square root approximation and laughs at you if you enter 1 or 0.  From poking around the 'tubes, it's looking like my best bet is C++.  Python seems easier, but I'll just have to learn C++ after it, anyway; and I bet I can learn Python faster after C++ than the other way 'round.  DarkBASIC could also be easy, there's a free version that runs only on ads, but I have little mini-versions of the same issues I've got with Python, and I don't want to wind up in any kind of legal limbo if I actually make something salable (or just have to do it all over in C++ anyway, which may or may not be worse).  Anyway, here's the best of what I've read today:

  • Stack Exchange:  What are good games to "earn your wings" with?  Several perspectives on how to go about learning game development from scratch.  Lots of agreement, and well-articulated disagreement.
  • The Game Programming Wiki:  Beginner FAQ.  More grounding on exactly what the Hell I'm getting myself into.  Getting many sides of the same issue is really helpful; repeatedly seeing the same ideas reinforces those ideas, and also "filters" some of the mere opinionating because it isn't repeated.
  • TGC:  Newsletter.  These guys sell software (they made DarkBASIC), which does not interest me.  But they have a newsletter, which does interest me.  So I signed up for it.  Hope that doesn't bite me in the ass... now I just gotta make sure I read it.
  • Nisan & Schocken:  The Elements of Computing Systems.  Zach once explained to me how computers work at the transistor level.  I understood that part.  I then asked him how you get from "physical logic gate" to "game on screen," and I was unable to comprehend his explanations (due in no small part to the fact that we were drinking that night).  This is a course on pretty much exactly that.  I now have great weekend filler for twelve weeks!  (Fourteen, if I stretch it.)  Here's a sweet video with one of the authors explaining what the book/course are about in more depth:


At Zach's behest, I also downloaded everything I need (I hope?) to use C# for xna.  That's gonna be my fallback if I suck so bad at C++ that I hate it.

Wednesday, February 22, 2012

Day 8: More book-learning.

Seriously, you guys.  I am thoroughly convinced that making a game takes forever and is impossible.

I got program vectors on the board, and I got NPC sprites on the board near the program vectors, but obviously they won't just go, I have to tell them to go and when to stop and blah blah blah.

I need to learn more programming, is what I'm saying.

So I looked up the section on vectors for more precise instructions, and it tells me to write things like "playerPath(variant handle, int flags, ...)" and "itemPath(variant handle, int flags, ...)" and expects me to know how to use RPGCode already (which borrows from programming languages I also don't know).  Fine.  I know when I'm in over my head, so I went to the RPGCode section to find something on "make sprite follow path vector."  This section is written by Occasionally_Correct, who you may remember from that useful tutorial I read on Day 4.  But the topic headings look like this:

  • Language Features
  • Basics
  • Program Flow
  • Creating Functions
  • Scope
  • Error Handling
  • Reserved Variables and Constants
  • Function Reference
  • Object Oriented Coding
  • Old vs. New
  • Methods and Using
  • Overloading Operators
  • Copy Constructors
  • Polymorphism

OK.  So.  None of those is on assigning an NPC to a path vector.  And in case you can't tell, this is not how I learn things.  I don't do well with things like "basics" and "principles" unless what I'm learning is something simple and limited, like playing cards, and I can immediately do a bunch of trial and error.  You get two through ten, then these three "face" cards (King beats Queen beats Jack beats Ten, and so on), and an Ace which can be high or low or both depending on the game.  That's it.  That I can learn with basics an' shit.  This is like nailing Jell-O to a wall:  you tell me something and I listen, but it's boring, and when I finally understand the second boring thing then I've already forgotten all about the first boring thing.  I can never learn exciting things this way, because I can't remember all those boring things all at once.  I need to start with an exciting thing, pre-formed and ready for dissection, and just use it first.  Then when whatever it does isn't good enough for me any more, I learn one boring piece of that exciting thing at a time, and tweak it into oblivion until I get what I want out of it (or at least have a more robust understanding of what I can/can't get out of it).  That way I can do something exciting, even if I'm doing it poorly, but I have practical knowledge straight out the gate and a way to branch out.  Then when I've amassed enough exciting things (or at least enough facets of the one exciting thing), that's when I'll grasp the basics in a broad-based way.

I want to be clear here that I'm not saying the guide is bad.  It's actually very good, but it doesn't fit me.  It's like a well-made tuxedo that's two sizes too small:  I can't fit it on and it looks like crap if I force it, even though it's evident that serious craftsmanship went into its design and manufacture.  What I'm saying is, this guide's start point is my end-point.  This guide wants to go backwards through my learning curve.  The cheek!


It's like I want the internet, but I have a textbook.  Yes, I can use the textbook; but the internet would work so much faster!  Whatever.  If this were easy, there's be zillions more shitty games out there.  There's nothing else really to do at this point, since I can't execute the other game features I want without learning everything about coding.  I guess I ought to keep working on the first game, then.  So fiiiiine, I'll reeeeead the tutooooorial, and probably like three others too.  Even though they put me to sleep because they start with things I don't care about and work up, rather than starting with things I do care about and working out.  Although I suppose it would be really hard to write a guide centered around "what I care about."

So that's what I've been doing today.  Found another good tutorial by this guy Marz, so hopefully that should mean "game updates" and not "learning updates" tomorrow.  I don't think you guys wanna hear about what variables and functions and arguments all are, anyway.