Skip to content

Commit

Permalink
Merge pull request #9 from keisetsu/part3-cleanup
Browse files Browse the repository at this point in the history
Cleanup most of the tutorial (spotty after part 11)
  • Loading branch information
tomassedovic authored Aug 10, 2016
2 parents 8b4b144 + 911498f commit 11e50b1
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 92 deletions.
16 changes: 8 additions & 8 deletions doc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ https://github.com/tomassedovic/roguelike-tutorial/
Rust is a systems programming language targeting roughly the same
space as C{plusplus}. That means it's fast and is generally used for things
where you need a fair bit of control over how are things structured in
the memory, etc. Rust is a good candidate for writing a browser,
memory, etc. Rust is a good candidate for writing a browser,
database, operating system, web server and... games.

What attracted me personally to Rust was the fact that it was
reasonably low-level (i.e. I could use it for things where I'd
normally go for C or C{plusplus}), with a good support for calling into
normally go for C or C{plusplus}), with good support for calling into
libraries written in C/C{plusplus} but feeling much more modern.

It has a real module system, closures, powerful macros and it protects
Expand All @@ -62,8 +62,8 @@ As a *wonderful* cherry on top, it doesn't have null pointers or references.

`libtcod` is a library specifically designed for writing roguelikes.
It deals with rendering ASCII characters in a grid, mouse and keyboard
input and provides useful utilities for path finding, field of view,
noise toolkit and a name generator.
input and provides useful utilities for path finding and field of view,
a noise toolkit and a name generator.

In other words, it provides a good chunk of what a typical roguelike would need.

Expand Down Expand Up @@ -107,7 +107,7 @@ All in one file::

The original Python tutorial is all one file. That's not something you
want to end up with -- especially when you're collaborating on the
project -- but the final result is still not _that_ big and it's makes
project -- but the final result is still not _that_ big and it makes
writing and following the tutorial easier when you don't have to worry
about where each code snippet goes.

Expand All @@ -123,10 +123,10 @@ Sameness::
The original Python tutorial is a bit infamous because games that
people do after going through it all look samey. That's not a reason
to shun the tutorial, though. Just don't get caught in the game
desighn of it. The purpose of this is to teach you how to write a game
design of it. The purpose of this is to teach you how to write a game
using libtcod. There's little of game design here. What I'd recommend
is: go through this, absorb the concepts but then start from scratch
when actually writing your game. And think about how to make it
when actually writing your game, and think about how to make it
unique.

== Start the tutorial
Expand All @@ -139,7 +139,7 @@ Start your game right away by setting up the screen, printing the
<<part-2-object-map#,Part 2: The object and the map>>::

This introduces two new concepts: the generic object system that
will be the basis for the whole game, and a general map object that
will be the basis for the whole game and a general map object that
you'll use to hold your dungeon.

<<part-3-dungeon#,Part 3: The dungeon>>::
Expand Down
10 changes: 0 additions & 10 deletions doc/index.html

This file was deleted.

30 changes: 15 additions & 15 deletions doc/part-1-graphics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ $ cargo new --bin roguelike
$ cd roguelike/
----

It will create two files: `Cargo.toml` and `main.rs` in the `src`
This will create two files: `Cargo.toml` and `main.rs` in the `src`
directory. `Cargo.toml` contains metadata for the project and any
dependencies you're going to need (such as libtcod).

Expand Down Expand Up @@ -62,13 +62,13 @@ Hello, world!
....

Rust will first compile `main.rs` and any other files it needs (there
are none yet). The resulting binary program will called `roguelike`
are none yet). The resulting binary program will be called `roguelike`
and placed in the `target/release` directory.

Cargo will then run the program which will print `Hello, world!`.

NOTE: Rust (and Cargo) can compile programs in two modes: _with
optimisations_ and _without_. Code compiled without opmimisations is
optimisations_ and _without_. Code compiled without optimisations is
*really slow*, but it's easier to work with under a debugger. We will
be using the optimised mode in the tutorial (with the `--release`
option), to make sure no one is making speed claims without
Expand Down Expand Up @@ -120,7 +120,7 @@ the asterisk (`*`) as the name means to import everything under
`BackgroundFlag`, etc.


Now we'll add some constants so we're don't end up littering the
Now we'll add some constants so we don't end up littering the
source code with a bunch of opaque numbers:

[source,rust]
Expand All @@ -145,7 +145,7 @@ the `println!` macro with code that sets up the libtcod window and
renders a character on it.

To create a window we call `Root::initializer(). ... .init()`.
In-between go custom settings. Default values are going to be used for
In between go custom settings. Default values are going to be used for
any option that's not specified.

[source,rust]
Expand Down Expand Up @@ -179,7 +179,7 @@ let mut root: Root = Root::initializer(). ... .init();
Now let's have a look at the window options we're passing in.

First, we're setting up a font. Libtcod uses bitmap fonts of various
formats. Calling the `font` methods let's us set our own font using a
formats. Calling the `font` methods lets us set our own font using a
file name and a font layout. `font_type` is another option for loading
a font.

Expand Down Expand Up @@ -224,15 +224,15 @@ The next line sets a default _foreground_ colour to white. This is the
colour everything will be drawn with unless specified otherwise.

The `tcod::colors` module contains values for common colours as well
as the `Color` struct that let's you use your own.
as the `Color` struct that lets you use your own.

Next we draw the `@` character at the coordinates `1, 1` on the
screen. The `0, 0` coordinate is at the top left corner of the window.

Using `BackgroundFlag::None` says to ignore the default _background_
colour.

Calling `flush`, which will draw everything on the window at once.
Calling `flush` will draw everything on the window at once.

And finally, we also need to call `wait_for_keypress` even though
we're not processing keyboard input yet. This is because libtcod
Expand Down Expand Up @@ -282,11 +282,11 @@ fn handle_keys(root: &mut Root, player_x: &mut i32, player_y: &mut i32) -> bool
----

A function signature in Rust is `fn function_name(parameter:
type, ...) -> return_type`. Here we call our function `handle_keys`,
type, ...) -> return_type`. Here we call our function `handle_keys`;
it accepts three parameters -- the root console (of type
`tcod::console::Root`), the x coordinate and the y coordinate (of type
`i32`) and it returns a boolean value. `true` says "exit the game",
`false` means "keep going"
`i32`) -- and it returns a boolean value. `true` says "exit the game",
`false` means "keep going".

The &mut` bits before the types are borrowing operators. You can read
about them (and the ownership they're strongly tied to) in the Rust
Expand All @@ -304,7 +304,7 @@ could only read their values but it could not change them. Since we
want to update them based on the key the player pressed, we'll get
them as mutable references. Then we can assign a new value using the
dereference operator (e.g. `*player_x = 10`) and that will show up
back in the caller code.
back in the calling scope.

Right now, the function's body is empty, except that it always returns
`false` (which means, keep the game going). Let's add the keyboard
Expand Down Expand Up @@ -338,7 +338,7 @@ there are others for `alt`, `ctrl`, etc.

The two dots at the end mean "I don't care about the other fields".
If it wasn't there, it would not compile until you specified values
fore every field of the `Key` struct.
for every field of the `Key` struct.

Rust requires that `match` arms are _exhaustive_. That means you have
to specify all the possible values. However, as we don't care about
Expand Down Expand Up @@ -375,7 +375,7 @@ use tcod::input::KeyCode::*;
----

Now, we could put it on top of the file next to the existing imports,
but: Rust lets you place them in individual functions as well, which
but Rust lets you place them in individual functions as well, which
will make them available only for that function. Since we'll contain
our keyboard-handling code in `handle_keys`, let's make it the first
thing there.
Expand Down Expand Up @@ -404,7 +404,7 @@ Now update our drawing function to use the player coordinates:
root.put_char(player_x, player_y, '@', BackgroundFlag::None);
----

And we also need to clear the _previous_ position position --
And we also need to clear the _previous_ player position --
otherwise we'd leave a trail of `@` on the screen! Put this right
before the `let exit = handle_keys(...)` call:

Expand Down
12 changes: 6 additions & 6 deletions doc/part-10-menu-saving.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct Game {
}
----

So right it'll just hold the map, the message log and the inventory.
So right now it'll just hold the map, the message log and the inventory.
We'll add more things later on, but let's start small.

Now let's move our initialisation code under this struct. In `main`:
Expand Down Expand Up @@ -196,7 +196,7 @@ wraps the underlying `Vec<(String, Color)>` and has the `add()` method
(_BORING_) or *we put the method the vec type directly*. I know,
right?

Rust let's you implement traits to types you don't control (e.g.
Rust lets you implement traits to types you don't control (e.g.
because they come from the standard library like our `Vec`) assuming
you control the trait.

Expand Down Expand Up @@ -228,7 +228,7 @@ impl MessageLog for Vec<(String, Color)> {
----

This is basically the same thing as our `message` function does,
expect it's a method (so it takes an explicit `&mut self`) and we
except it's a method (so it takes an explicit `&mut self`) and we
don't bother with the message count check.

And now, we can just add messages to the log by calling:
Expand Down Expand Up @@ -306,10 +306,10 @@ fn new_game(tcod: &mut Tcod) -> (Vec<Object>, Game) {
}
----

We return use a tuple to return two arguments: the vec of `Objects` and
We return a tuple with two elements: the vec of `Objects` and
the `Game` struct.

`new_game` is calling `initialise_fov` so we need create it and move
`new_game` is calling `initialise_fov` so we need to create it and move
the FOV-related code to it:

[source]
Expand Down Expand Up @@ -730,7 +730,7 @@ failure is `Err`.

There's also the {error}[Error trait] which represents an error and
lets you get its textual description. All the file-handling
serialiastion errors in our save/load code implement Error.
serialisation errors in our save/load code implement Error.

So, looking at `save_game`, the `json::encode` call returns either
`Ok(String)` with the encoded value or
Expand Down
2 changes: 1 addition & 1 deletion doc/part-11-dungeon-progression.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ pub fn take_damage(&mut self, damage: i32, game: &mut Game) -> Option<i32> { //
}
----
<1> May return a number of XP if `take_damage` killed the monster
<2> We did kill the monster, return it's XP
<2> We did kill the monster, return its XP
<3> We did not kill the monster, don't return anything


Expand Down
4 changes: 2 additions & 2 deletions doc/part-13-adventure-gear.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ and so on?

We need equipment. It differs from the items we have in two ways: you
can only equip it in limited slots and it enhances your abilities
while it's being worn. Unlike our items which are one-use-only (though
while it's being worn. This is unlike our items which are one-use-only (though
they don't have to be!).

== Basic equipment
Expand Down Expand Up @@ -132,7 +132,7 @@ Game` here instead and you'll see the problem when we get to

How do we equip our items? We can rely on the existing `Item`
mechanism -- when you try to "use" or "cast" an equipment (which you
can do since it's an `Item`, too), we'll equip or dequip it.
can do since it's an `Item`, too), we'll equip or unequip it.

First, let's add a new Item type:

Expand Down
18 changes: 9 additions & 9 deletions doc/part-2-object-map.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ifdef::env-github[:outfilesuffix: .adoc]

== Off-screen consoles

Before we continue, let's talk about _consoles_. In libtocd, console
Before we continue, let's talk about _consoles_. In libtcod, console
is where we _draw stuff_. We've only used one so far -- the root
console. It is connected to the game window and anything you want to
show must eventually make its way there.
Expand All @@ -32,7 +32,7 @@ instead of `root`.

And finally, blit the contents of the new console to the root console
to display them. The `blit` function takes a lot of parameters, but
the meaning is straight forward. We take the console we want to blit
the meaning is straightforward. We take the console we want to blit
_from_ (i.e. `con`), the coordinates where to start and the width and
height of the area we want to blit (we'll blit it all). Then the
destination (`root`), _where_ to start blitting (we'll use the
Expand Down Expand Up @@ -116,8 +116,8 @@ let mut objects = [player, npc];

Now we'll need to do a few changes to make it work. First in
`handle_keys` we'll use player's `move_by` method to change the
coordinates. This means we'll need to pass (mutable reference to) the
player object in.
coordinates. This means we'll need to pass in (a mutable reference to) the
player object.

[source,rust]
----
Expand Down Expand Up @@ -174,7 +174,7 @@ const MAP_HEIGHT: i32 = 45;

Next we'll define colours for the tiles. We'll have two tiles for now:
_wall_ and _ground_. Let's define their _dark_ variants. When we add
field of view, we'll have add set for when they're lit.
field of view, we'll have to add a set for when they're lit.

[source,rust]
----
Expand Down Expand Up @@ -215,7 +215,7 @@ The `#[derive(...)]` bit automatically implements certain behaviours
there. `Debug` is to let us print the Tile's contents and `Clone` and
`Copy` will let us _copy_ the values on assignment or function call
instead of _moving_ them. So they'll behave like e.g. integers in this
matter.
respect.

We don't want the `Copy` behaviour for `Object` (we could accidentally
modify a copy instead of the original and get our changes lost for
Expand Down Expand Up @@ -265,11 +265,11 @@ map[30][22] = Tile::wall();
map[50][22] = Tile::wall();
----

(you can also access the tile's properties directly like sof:
(you can also access the tile's properties directly like so:
`map[30][22].blocked = true`)


Next we need to draw the draw the map on our window. Since we need to
Next we need to draw the map on our window. Since we need to
draw both the objects and the map, let's create a new function that
renders everything and call it from the main loop.

Expand Down Expand Up @@ -325,7 +325,7 @@ if !map[(self.x + dx) as usize][(self.y + dy) as usize].blocked {

We'll have to pass a reference to the map to `move_by` and
`handle_keys` which calls it. This may look annoying now but as the
code grows, it will be gook to know which functions can see (and
code grows, it will be good to know which functions can see (and
change!) what.

Finally, since the `con` console is for objects and the map only, we
Expand Down
10 changes: 5 additions & 5 deletions doc/part-3-dungeon.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ ifdef::env-github[:outfilesuffix: .adoc]

Having a painstakingly handmade room with artfully placed pillars is
all well and good, but roguelikes are about procedural generation! How
about adding some randomness to the mix.
about adding some randomness to the mix?

We're going to carve rooms and tunnels in an underground rock. In this
We're going to carve rooms and tunnels in underground rock. In this
section we'll build some helper functions which we'll then use to
generate the whole dungeon.

Expand All @@ -36,7 +36,7 @@ impl Rect {
The rectangle stores the coordinates for the top-left and bottom-right
points.

This function will take a rect and place it in the map, by making sure
This function will take a rect and place it in the map, making sure
all the tiles are empty.

[source,rust]
Expand Down Expand Up @@ -201,7 +201,7 @@ use rand::Rng;

With that out of the way, let's actually implement the algorithm in
`make_map`. Remove the previous code that created the example rooms
and tunnel and instead make a loop goes through the maximum number of
and tunnel and instead make a loop that goes through the maximum number of
rooms, assigning random coordinates and size to each one as we go.

[source,rust]
Expand Down Expand Up @@ -295,7 +295,7 @@ tunnels between the rooms.

For every room except the first one we connect it to the previous one.
Now, sometimes we can't connect them with a straight line (horizontal
or vertiral) but we need two tunnels.
or vertical) but we need two tunnels.

We could start with a horizontal tunnel to reach the same level as the
new room and then connect it with a vertical one or we can do the
Expand Down
Loading

0 comments on commit 11e50b1

Please sign in to comment.