Monday, October 19, 2015

Starting a smaller project... an ASCII Rogue-like!

Let's make an ASCII Rogue-like Part 1!

I wanted to make this Rogue-like to practice my C/C++ whenever I get a little overwhelmed by Handmade Hero. It's a good way to reinforce skills I've learned while providing a guidepost for my own game development.  This project is based on the awesome YouTube channel of Making Games With Ben. You should check it out!

Step 1: Read in a map and print the map

We're going to read in our maps for this Rogue-like from a text file.  So let's get organized.  

  1. We should set up our entry point for Windows (aka your main.cpp)
  2. We should have an entity that controls the game flow and logic. 
    1. Let's call the class GameSystem.
  3. And finally, we should have a class that assembles our map from the file and prints it out. 
    1. Let's call this class Level.

Step 2: Setting up main.cpp

  • We're going to come at this problem top down as a means to connect concepts together, so bear with me!  
  • As described about, GameSystem will handle the game logic and flow, so we'll need to include it (I know, it's not created yet)
  • Create a GameSystem type and we'll send the constructor the name of our file.
  • Our GameSystem class will, at least for now, handle our main game loop called playGame()
  • And finally, return a 0, to let the compiler now everything executed fine.
  • From here, let's make that GameSystem class! 

Step 3: Setting up GameSystem.cpp & GameSystem.h



  • GameSystem is going to act as the nexus for our game.  
  • So let's include "Level.h" (which hasn't been created yet!) in our header file.
  • Just like we declared in our main.cpp, the GameSystem constructor will make the level with the text file named in the ().
  • Let's make void playGame(), like we had promised in main.cpp.
  • And finally, we need to make a reference to our Level class.  
    • Remember, Level will do everything level related.
    • GameSystem is simply the conductor calling on all the pieces.

  • And now, we get to implement the header file!
  • For now, the constructor will load our textfile & then print it.
  • The system pause is a Visual Studio thing, nothing to worry about.
  • And finally, implement playGame(). Nothing need to be there just yet!

Step 4: Setting up Level.cpp & Level.h



  • We need to forward declare all the Level function we promised in GameSystem.
  • public will hold the print() and the load(string fileName).
  • Under private, we'll make our string vector that will hold the data we get from our files.

  • In our load function, we need to use the fstream library to bring files in.  
  • Create the file, open the file, and declare a local string variable to hold the line.
  • Set up a while loop that will continue to read lines as long as they exist. 
  • Use vector's pushback function to add them to our vector.
  • And close the file.
  • Don't forget to use perror for useful debug messages.
  • And finally, the print function will just loop though levelData to print our level to our screen.

Step 5: Make you ASCII file and test it out!

Mine looks like this... And when you run this, it should print out your level. Have fun!

Tuesday, October 13, 2015

Mac OS X El Capitan Update: Apple System Integrity Protection keeps you out of root.

Fortunately, it can be disabled! 

Updated the ol' Macbook today and found out that root is now denied access by default.  I couldn't copy SDL2.framework to /System/.  Fortunately, OSXDaily has a great link on how to turn it off.  Requires a restart.

Link to OSXDaily to disable System Integrity Protection

Thursday, October 8, 2015

Unity Side Project: Implementing a dash

Top Down Shooter: How to Add-in a Dash Mechanic

Intro

I started working on a portfolio piece in the Unity Engine.  It's been a lot of fun figuring out this popular engine!

I wanted to write up a quick tutorial on how to implement a dash mechanic in this top-down shooter game I've been working on.  I don't know how to add on an animation, but the Mechanim system should be able to handle it.  I just don't have the art system knowledge just yet to put it in myself. Anyways, on with the tutorial!

Infrastructure of my Scripts

In terms of plumbing, I set up a Player script and a PlayerController script.  The difference is that the logic and hard work are done by the Player script and the PlayerController is called to execute it. This is supposed to have the benefit of modularity, where some other entity can use the Player script for its logic and members, but execute in a different, unique matter.  A good example of this would be an enemy AI.

Note, this is not the best way to handle the problem nor is it the most efficient.  This is a solution I came up with studying the Unity references, Unity answers, and other tutorials.  If there's a better way or if something is completely wrong, let me know! I'm doing this to learn.

Step 1: We gotta limit how much we can dash!

We have to make sure players just can't spam dash!  To do this, we want to keep track of the Time.time in a variable.  Then, in your FixedUpdate (I'm using rigidbody physics, so...) you'll want something like this...


Time.time is Unity's time object and dashCooldown will hold our time stamp every time we dash.  I will then minus Time.time - dashCooldown to get a value of how long it's been since I dashed.  If the value is greater than 2.0, it's now okay to start the Dash() co-routine!

Step 2: What the deuce is a Coroutine?


But I wound up using it because while I was experimenting, any changes to the velocity of the rigidbody were instantaneous and confined just to one frame.  Coroutines give me the ability to wait for a specified amount of time using... 

yield return new WaitForSeconds(some float value);

So now, all I have to is write the coroutine with the following steps:
  1. Check to see if the direction button and the dash button were pressed.
  2. If they were, create a new Vector3 with the dash value we're adding to the velocity.
  3. Call the PlayerController's Dash method
  4. Play particles/art stuff
  5. Record the current Time.time (so player's can't spam it!)
  6. Call our WaitForSeconds() function
  7. Then, create a new Vector3 that sets the dash to 0
  8. Finally, send the new Vector3 to the PlayerController's Dash method.

Step 3: Putting it all together now!

On my side, it looks something like this...

I just did it for one button. It's pretty straightforward from this point.

Step 4: But what about the PlayerController?

It should look something like this, if you've also taken the PlayerController/Player route.
Hopefully that was somewhat useful. I assumed a lot of things in terms of teaching. If you have any questions, let me know!



Thursday, October 1, 2015

Day 4: Hexadecimal, Endian, Structs, Casting, Array Indexing, Reference/Deference, & #pragma

Addendum to Video 3

  • To use hexadecimal code in the debugger windows, you have to prefix it with 0x

Endianness


  • But what happens if we ask for more than 8 bits?
  • For example, the number 500 in binary is...
    • 0000 0001 1111 0100
    • The first byte is just one (higher order byte)
    • The second byte is 244 (lower order byte)
  • But why in memory, does 244 appear first, then the 1?
  • This is because of Endianness
    • Little Endian (low order byte comes first): x86, ARM, x64
    • Big Endian (high order byte comes first): PowerPC (PS3)
  • This matters in file formats!
    • For example, Photoshop made on Mac, which used Motorola 68k, and it was Big Endian based
    • File formats were Big Endian of their source architecture

Structs

  • When programming for reals, we don't want to have to constantly declare everything as parts of little bytes and those sorts of things.
  • C allows us to declare composites of many different types, all of which may have different byte counts
  • A struct is a collection of variables that go together.
    • You're referring to a memory layout that's sequentially ordered and usually stored back to back (but sizes can be different due to padding and alignment)
  • struct is the backbone of C programming
  • Struct Example:
  • And then we can access the members of the struct like this...

But why is my struct not the right size? (11 bytes vs 16 bytes)

  • In this struct, it should be a total of 11 bytes.
  • Compiler is not under any constraint to lay out a struct as compactly as possible
  • Although it adds up to 11 bytes (1+4+4+2) in reality, compiler has boundaries and will (in this case) assign 4 bytes to each
  • You can use sizeof() to get the size of a variable

Hexadecimal

0 - 0
1 - 1
2 - 2
3 - 3
4 - 4
5 - 5
6 - 6
7 - 7
8 - 8
9 - 9
A - 10
B - 11
C - 12
D - 13
E - 14
F - 15
  • 0xA = 10
  • 0xAA 16 * 10 + 10 = 170
  • 0xAAA = 16*16*10 + 16*10 + 10
  • Hex is used because it more concise than binary, and it lines up nicely byte-wise

Casting

  • Treat Test as if it were a bunch of shorts
  • Look at memory occupied by Test as if it were a bunch of 16 bit values.
  • C is statically typed. 
    • This means that C keeps track of what you said the type of a variable/struct/etc was
  • Compiler spits out error if you try to use something differently than the way it was declared.
  • For example...

In the Memory debugger, why are byte values listed at 204?

  • In hex, 204 is 0x000000cc
    • 0xcccccccc would be 204 204 204 204
  • When you compile in debug mode in VS, something says"clear all values to write cc (204)"
    • This is because a lot of errors originate from uninitialized values
    • So 0xcc means "uninitialized"
  • In a release build, this doesn't happen since it's inefficient!

Array indexing

  • In C, arrays are just a memory layout
  • Array is a collection of objects that is indexed by a value (usually a number). 
  • They are placed sequentially in memory
  • They also arranged in memory reliably. 
  • It's spaced using a known number.
  • Example:

More on C and Arrays

  • C is a little wonky because of...
  • Projectiles is just a pointer to ProjectTilePointer. 
  • C knows this as well, BUT it understands that it is a much bigger thing! 
    • They are NOT the same type.

In other words....

  • So all three of these ARE THE SAME THING!!!!

Reference vs. Dereference

  • To put it simply  -> (Dereference). is used for pointers
  • . (Reference), is used to access the actual variable
    • Error is C2228 left of '' must have class/struct/union...
    • Solution is almost always to switch . to -> or -> to .
  • Functionally, there is no difference between these 2.
  • Same thing, only difference is that one's isn't a pointer and the other isn't

#pragma

  • __attribute__
  • You can use these to wrap any struct in a pay to tell the compilers that is has to be packed.
  • This will force C to pack it tightly, and not auto-assumed to a certain size.

Progression and Status Update

  1. I want to find a solution for displaying code samples on blogger.  I was hoping for a built-in solution, but I need to find something.
    • Found a neat solution! GitHub has something called Gists that can be embedded into blogger. This should work nicely.
  2. It's amazing how much information can be packed into these 3 hours of Handmade Hero. I'm not really sure how fast I can go with these super dense sessions. 

Day 3: Memory as first class citizen, Pointers, Virtual Memory, the Stack, Computer Architecture & Design

Casey-isms

  • THINKING ONLY IN TERMS OF EFFICIENCY FOR THE ABSTRACTION LEADS TO SLOW, BUGGY CODE 
  •  In general latency will be bad, but we can design programs to take advantage of throughput!
  •  Programming always comes back to what is happening with CPU and memory.

Handy Dandy Visual Studio Tools

  • Handy window for budgging Debug -> Memory
  • You can look for a specific location in hex!

Memory

  • CPU, GPU, audio, all take data from memory, rearrange, and replace into memory so the hardware component can read the information and execute correctly
  • What is the CPU and memory actually?
  • First, whether it be CPU or GPU (whatever you're programming)
    • Take information into memory, modify, put out back to memory
    • Al information takes, modifies and puts back out so other things can use that data & turn it into a correct signal

FUNDAMENTAL What is CPU doing to change memory?

  • Basis of design of all code
  • Basis of optimization
  • Basis of all debugging
  • In C/C++, memory is a first class citizen!

Pointers

  • Boiling it down, it's a number that holds an address
  • It boils down to this...
  • Example: char unsigned Test;
    • You're saying "I want what's in 8 bit memory" (WHAT)
  • Example: char unsigned *TestPointer;
    • I want to talk about the location of the 8 bit memory (WHERE)
  • Example: TestPointer = &Test;
    • & (address) I want to know where Test is in memory and assign to TestPointer
  • This can be represented all on the same line using inline declaration
    • char unsigned *TestPointer = &Test;
  • char unsigned Test; (From watch)
    • Value: 255
  • char unsigned *TestPointer; (From watch)
    • 0x003cf9af (number of bytes from bottom of memory aka first piece two where it stores Test. In decimal is 3996079
  • TestPointer = &Test;

Small Overflow Example


  • *TestPointer is pointing at the address of Test, therefore, they are the same and updating one will update the other.  
    • They are functionally the same thing!!!

But what's the catch? VIRTUAL MEMORY

  • In the old days, the memory address would be the actual location on the hardware. 
    • Nowadays, that is not true because machines use virtual memory.
  • Virtual memory allows processes to cooperate with each other.
    • There are a lot of concerns like memory location, security, memory amount usage, etc.
    • Allows running code what appears to be the memory of the machine, but not the real machine in terms of location.
  • It does this using pages, which are chunks or ranges, that exist in physical memory.  
    • But each process actually has its own concept of pages and thinks memory is laid out in a particular way.  
    • Pages exists only when it accessed necessarily
  • OS is in charge of shuttling physical memory to hard drive or rearranging layout using a table maintained on CPU that allows each processes view of pages to be dynamically mapped to where they actually are in physical memory
    • One example is the TranslationLookAsideBuffer, Translation map table
  • But when we code, we can think we're accessing physical memory
    • But it's very important to keep virtual memory in mind so we can manage it properly.
  • Pointers tend to be displayed in HEX due to its size.

Welcome to the Stack

  • When did we ask the OS for memory?
    • Who gives us the memory? Presenting...
  • THE STACK, it a special location in memory given to us by the OS
    • We don't explicitly ask for the stack! 
    • System automatically asks the OS for it.
  • This functionality is built into the compiler.  
    • This is not true to super low level memory, where manual control is needed
  • How does it work?
    • Things go deeper, and then shallower....
    • Grabs memory at the end of stack, and then grows
    • Then at the end, it's removed
    • Think of it as an audio bar. It's grows and shrinks
    • The middle of the bar almost never disappears
      • Since we're constantly calling, returning, calling, returning, calling, etc etc

Address space layout randomization

  • Randomizes where your program runs in memory for security reasons
    • Code, stack are in different locations
    • This makes it much harder for hackers & more difficult to debug.
  • We can turn it off to make it easier to debug
  • Pages can be marked as readable, writable for security reasons
    • This can be turned off and on
    • CPU has flags that can mark makes as executable, but not writable

Basics of Computer Architecture & Design

  • Speed of light / clock speed (i.e. 3.2 ghz) = 9.235234643 centimeters
    • Which is approximately the distance from CPU to memory!
  • In other words, going from CPU to memory, even at the speed of light is EXPENSIVE!
    • Going out and getting things from memory is huge! 
    • This is because of the limitations of wires and the actual location.
      • Next-gen: Stack DRAM or RAM on CPU
  • Similar problem with GPU/CPU/Memory triangle
    • Latency- how long it takes one thing to start and finish something
    • Throughput - how fast things can go through at peak congestion
    • Bandwidth of memory related closely to Throughput
  • In general latency will be bad, but we can design programs to take advantage of throughput!
  • Because of latency, CPU's use L1, L2, and L3 cache right on chip to combat latency to minimize the time we have to talk to memory. It'll ask the cache, then memory (via the memory controller)

Wednesday, September 30, 2015

Day 2: A Primer on Debugging & Assembly

I'm going to separate my status from the notes and stuff learned, so I can pump these logs out in a more efficient matter.

Casey-isms

  • Everything in computers is just numbers.
  • As a general theme of Handmade Hero, we want to know what the machine is doing.
  • It gives us a connection to the computer and is not that much more slower or complicated.

OutputDebugStringA() vs OutputDebugStringW()

  • What does the A stand for?
    • Windows used to work only with standard ASCII strings (or ANSI?)
    • But the ASCII system didn't work for languages like Chinese, so Unicode became the standard, so Windows had to expand
    • So Windows started using wide character strings called UTF-16

Debugging & the Breakpoint

  • You set a "breakpoint" and run code, but when program reaches this point, it stops!
    • It will freeze everything, the memory, variables, etc so i can look at it
    • Press F9 in VS to set a breakpoint
  • Breakpoint freezes RIGHT before the line that executes
  • Step Into and Step Over
    • Step Over, F10, do whatever's on the current line
    • Step Into, not covered just yet
  • Useful Debug Windows
    • Watch: type in the name of something we want to see and show up corresponding value
    • Registers: to see the assembly language CPU operates on

Assembly

  • Appears to read right to left!
  • This is important, BECAUSE WE ALWAYS WANT TO KNOW WHAT IS HAPPENING ON THE MACHINE
    • In VS, Right click and select goto disassembly
    • For debugging, bring up registers. you can right click and display in hexadecimal
011A1BCE                    mov                                  byteptr [Test], 0FFh
(location in memory)    (register mnemonic)        (moves FF in code into byte pointer )

  • By watching the registers, we know this is a memory to memory move and does not reach the  registers)
  • Hexadecimal notations 
    • VS will translate it for you if you hover over hex
    • 0FFh : Assembly Notation
    • 0xFF (0xcc) : C notation

  • Even though EAX can hold 0000 0000, we can reference smaller parts of a register. we can pull out the bottom 8 bits...
    • This is what "al" (references to EAX to pull only a byte) does!


Monday, September 28, 2015

Day 1: Crash course in C/C++ & computer architecture

Step 2: Crash course in C/C++ & computer architecture (continued)

Comments: The amount of detail in this stream is amazing and quite honestly, overwhelming. I might have to work out some sort of system to absorb the sheer amount of information.
Progress: I grokked a large portion of it.  Will review before next video. Onwards!
Notes (This isn't a log of the entire video, rather, the parts that I felt were relevant to me):

What is Linking?

  • The back half of the compilation process.
  • Gathers all references to link together to make executable
  • What is the Unresolved external error?
    • External to the compilation unit where it was being used
    • unresolved means it couldn't find an actual definition!

How does windows, the linker, and your program know where to start?

  • The predefined name  WinMain
  • Use MSDN, don't bother with memorizing

WinMain() prototype

  • Lots of Windows only stuff here.
  • LPSTR(a pointer to string), HINSTANCE (a running program) 
  • hInstance
    • it refers to ourselves!
  • hPrevInstance
    • old, not important
  • LPSTR lpCmdLine
    • what got sent to us when we were run
    • arguments and stuff from the command line
  • int nCmdShow
    • Run in normal window or minimized windows

What is that letter before Instance / PrevInstance / etc

  • This comes from Hungarian Notation (an old standard where you prefix everything you type)
  • p for pointers, l for long, h for handle, etc

What's _In_ for?

  • Tells you what direction the data in flowing
  •  __In__ means it's passing information TO Windows.
  •  You typically want to remove this before compiling / running.

Function

  • Something that holds code for us that we can reuse
  • void: does not return anything when the function is called
  • <return value, aka what comes back from function> foo (<parameters>)

What's the ; (semi-colon) for?

  • End-of-line delimiter, it defines the end of a C++ statement

What is CALLBACK for?

  • A C Macro, it expands to some special decoration this is used from Windows
  • Decoration that tells compiler and linker that it's special
  • There are constraints that needs to be met!

When we removed foo() why was is a compile error and not a linker error?

  • This happens because C/C++ are languages that do NOT allow you to use thing that have not been defined yet
  • But if you can't actually call something unless it's defined, how are there ever unresolved external symbols at link time?
    • C allows forward declaration
    • Functions are divided into declaration and definition

Tidbits from Video 1 Q&A

  • Sysinternals, if you want a tool that grabs OutputDebugString into a log?
 

Welcome to the first post!

I decided I need to learn more about the technical aspects of game development.  I can probably make a game now, but I want to make gameplay experiences I think will be awesome.  To do that, I need to master my tools like any other artisan.  This blog will be an exercise in discipline as well as a log for myself.  I hope to reach milestones and learn a damn lot. There's probably no more excuses left with the materials available today.

I'll be following Handmade Hero and be making smaller projects as I learn the joyous in's and out's of C/C++. Maybe even slap together a Unity project in my off-time!

Step 1: Setup up Sublime 3 

Link used: Setting up Sublime with M VanDevander
Comments: Pretty straight forward.  I didn't want to use vim or emacs since I was already pretty comfortable with Sublime.
Status: COMPLETED


Step 2: Crash course in C/C++ & computer architecture

Comments: I'm familiar with C/C++ and some computer architecture.  However, I'm quite rusty since I've been using C#, Python, and other interpreted languages. Probably the roughest part will be thinking about memory, which modern languages handle for you.  
Status: IN PROGRESS

Sidestep 1: Unity!

I played a small, fun top-down shooter called Last Invader and really wanted to make one myself. Just good ol' fashioned, arcade fun.  As a side project, I think I'll whip together a a TDS for Kongregate/Newgrounds.