Coordinate transforms, still #
Last post was about my attempt at explaining coordinate transforms. Progress has been slow. I've implemented many of the diagrams but I'm still having trouble with the narrative. Last time I said this was my outline:
- Show a side scrolling game with some cool camera effects.
- Introduce world coordinates vs screen coordinates.
- Solve the problem of scrolling: subtract an offset.
- Introduce transforms. (may need to be later)
- Introduce inverse transforms, for mouse clicks. (may need to be later)
- Introduce cameras. More complicated than offsets, but can do more.
- Show some cool effects with cameras. (may need to be earlier)
- Introduce chaining transforms.
- Show some cool effects with chaining.
- Demo showing all concepts together.
I've been experimenting with different orders for the topics and now think there are two intertwined “tracks”: the concept track introduces mathematical concepts and terminology, and the problem solving track shows solutions to specific gamedev problems. These two tracks are paired up:
Problem solving | Concept |
---|---|
scrolling | world/screen coordinates, translate transform |
following the player | cameras, view coordinates |
tile grid coordinates | scale transform, chaining transforms |
mouse clicks | inverse transforms |
? | function composition |
? | transform matrices |
I think in each case I should start with the problem to be solved, then show the immediate solution, then explain the concept behind the solution. The concepts then lead to a reusable solution. Example:
- Problem: we want to scroll the screen
- Immediate solution: add an offset before drawing
- Concept: we're transforming world coordinates to screen coordinates
- Reusable solution: a translate transform is a function or object that converts coordinates
The next section is:
- Problem: we want to keep the player in the center of the screen
- Immediate solution: use the player plus half the screen size as the offset
- Concept: a "camera" points at the player, using view coordinates
- Reusable solution: a camera object is placed in the world, and we use that to build the translate transform
What order should I present these topics? I'm not sure. I know I want to put scrolling first. If I put mouse clicks second, then it's fairly easy to solve, and there's less motivation to learn inverse transforms. So I might put that later. If I put tile grid coordinates second, then it leads to chaining transforms together, which will be useful for following the player with a camera. Or if I put following the player second, then it leads to view coordinates, which might further motivate chaining transforms.
I think the main problem is that I'm not feeling particularly inspired right now, so I'm working very slowly.
Coordinate transforms, again #
Back in 2015, I had attempted to explain coordinate transforms in terms of matrices. In 2016, I started over, trying to focus on coordinate transforms without matrices. That didn't work the way I wanted either, and I wrote a blog post about that, saying that I was going to focus on game cameras. I started that, but lost motivation. The last line of that blog post is: Well, I failed. I lost motivation to work on this so I've put it on hold … again. I think I may take a long break from tutorials.
Reader experience with 404s #
There are many days when I don't feel like working on my project. I use this feeling to "productively procrastinate" on things that I've been wanting to do but haven't done yet. Earlier this week I decided to tackle two related problems:
- I want to know which pages are reachable from the home page. I can then review the ones that aren't reachable and consider adding them if they're finished.
- I want to make suggestions on the 404 page, but only to pages that are reachable from the home page. There are a whole bunch of random pages I have that aren't finished or useful, and I don't want to use those for suggestions.
Little details #
On each of my pages you'll notice the main element: interactive diagrams that visually explain a concept. But there are lots of other techniques I use too. Unfortunately, I don't remember all of these when I'm writing a new page. I decided to make a catalog of things I've used so that I can remember to use them on the new pages I write.
I've been working on this for a few months and it's still incomplete but I decided I should share it: https://www.redblobgames.com/making-of/little-things/
Are there other little details on my pages that I've forgotten about? Probably! I will update the document as I think of them.
Labels: making-of
Brainstorming with reversal #
In the previous two posts I described how I sometimes approach a problem by trying to arrange it into a matrix. Sometimes that doesn't work and I instead try to look at the problem backwards. As an example, consider procedural map generation. I often start with a noise function, adding octaves, adjusting parameters, and adding layers. I'm doing this because I'm looking for maps with certain properties.
Brainstorming with factoring #
In the last post I described how I sometimes describe a problem with a matrix, and then look at the matrix transpose to see if it gives me new ideas. Another technique I use is to look for a factoring.
In algebra, factoring transforms a polynomial like 5x² + 8x - 21 into (x + 3)·(5x - 7). To solve 5x² + 8x - 21 = 0, we can first factor into (x + 3)·(5x - 7) = 0. Then we say that x + 3 = 0 or 5x - 7 = 0. Factoring turns a problem into several easier problems.
x | 3 | |
---|---|---|
5x | 5x² | 15x |
-7 | -7x | -21 |
Let's look at an example: I have six classes, File
, EncryptedFile
, GzipFile
, EncryptedGzipFile
, BzipFile
, EncryptedBzipFile
. I can factor these into a matrix:
Brainstorming with transpose #
Sometimes I get stuck and look for a way to think about a problem a different way. There are some problems that you can view in the form of a matrix/table. The structure looks like this:
A | B | C | D | E | |
---|---|---|---|---|---|
1 | A1 | B1 | C1 | D1 | E1 |
2 | A2 | B2 | C2 | D2 | E2 |
3 | A3 | B3 | C3 | D3 | E3 |
4 | A4 | B4 | C4 | D4 | E4 |
5 | A5 | B5 | C5 | D5 | E5 |
There are rows and columns, and I'm trying to work on the cells. Let's try an example from a simple game:
Attack | Defend | Special | |
---|---|---|---|
Fighter | sword | armor | slam |
Mage | fireball | reflect | freeze |
Thief | dagger | dodge | disarm |
Improving hexagon map storage diagram #
Last week, I decided to improve the map storage section of the hexagon guide. This section had a diagram that suggested the use of a 2D array, but then it presented formulas that didn't look like what was shown. Reader feedback made me realize this section was confusing. I was mixing two separate steps here.
- Store the map in a 2D array.
- Slide the rows to the left to save space.

Labels: hexagons
Improving island shaping for map generation #
One of my goals for 2019 is to improve my existing pages. This week I improved the island map section of my noise-based map generation page.

Labels: maps
Improving the 2D Noise page #
One of my goals for 2019 is to improve my existing pages. Yesterday I decided to work on my old 2D noise page. We normally use Perlin/Simplex noise to make terrain heightmaps, but on that page I used Fourier transforms instead. Perlin/Simplex noise are a fast approximation of the things you can get from Fourier transforms.
The 3D renderer on that page always bothered me. It was one of my early experiments with WebGL. I had never been able to figure out exactly what I didn't like or how to fix it.
I decided to improve the renderer.