Tuesday, 28 May 2013
My current habit is to look at what I've accomplished so far and think, OK, in what way is it most obvious that this isn't a finished game? Whatever the answer to that question, that's what I work on next.
I still think this method is going to work if I stick to it. In fact, I have renewed confidence that it's the right way to work. But what I now think might not work is the current art style of the project.
I've been designing with a view to a semi-realistic 3D art style, but I'm going to look into dropping that for a simpler, more abstract look. Most of the graphics are still placeholders, so this won't mean much wasted work.
As Matt says, as an indie, you aren't going to compete with AAA studios in terms of graphics. I'd be better off spending that time on level design, game features, gameplay polish and the level pit.
Monday, 20 May 2013
If a friend is trying to convince me to try a new game, the first thing I always say is, "I dunno... how dirty are the floors? The corners, especially?" I'm sure you're the same. As we all know, the best games have dirty floors and filthy corners, which is why ambient occulsion was invented.
Ambient occlusion (AO) is a technique used to make CG scenes appear more realistic by darkening surfaces near corners. Used subtly, this can add realism as corners and crevices are less accessible to light, making them darker. Used less subtly, it gives a distinctive dirty appearance.
Modelling AO the physically correct way is still too computationally intensive for general use, so if you want it in your game, you have to fake it. I'm doing it with a precarious conglomeration of textures, render passes and stencil tests. I think it's looking pretty good. And it works on moving objects, too! You'll have to take my word for it for now, but you'll see in the next video.
Saturday, 11 May 2013
Blackshift's mechanics system is what I call the code that handles pushing blocks, deciding what is pushed by what, what gets to move, what doesn't, and what is crushed. It's not a full physics simulation, it's much simpler and more abstract, which ironically makes it more difficult to code. Why? Because fake, abstract physics is specific to your game, whereas more realistic physics can be achieved using off-the-shelf libraries with little or no modification. Neither is better, but each suits a different type of game. Of course, you're free to use the wrong sort of physics for your game on purpose...
|Not Tetris 2, Stabyourself.net|
Blackshift's mechanics are, in a nutshell:
- The player, enemies, arrow blocks, and anything on a force floor generates a force.
- Forces propagate through blocks.
- Clusters of sticky blocks always move together.
- Once all the forces are propagated, anything that can move does.
- Anything that can move in more than one direction moves in the direction of the strongest force.
- Normal block; can be pushed and can push other blocks along in long columns.
- Heavy block; can only be pushed by the player, not by other blocks.
- Arrow block; pushes itself in one of four directions.
- Sticky block; always moves together with adjoining sticky blocks.
Sunday, 14 April 2013
It's easy to throw together a quick and dirty editor where the user has to memorize 300 keyboard shortcuts and there's no undo, and for some games that's the right thing to do because it means you get to spend more time making a fun game.
But for Blackshift I want the editor to be a core part of the game, and to encourage users to make and share their own levels, so I'm taking the time to do a nice GUI (and boy does that take time!)
I've got a few ideas for ways to take what at its heart is a single-player game and give it an online bit. One thing I'm definitely doing is integrating a usable editor, and letting users browse and play others' custom levels from within the game.
If I've got the time, though, I'd love to experiment with some of these ideas:
The level pit — Watch other people beat your level or fall into your traps. Rate, comment & follow level creators.
An economy — Players spend coins to put unique and interesting things in their levels. Put a bounty on your level, giving other players money when they complete it, to attract punters. Or, require an entrance fee for them to try.
Deathmatch — Two, three or four players playing the same level at once, trying to kill each other instead of finding the exit.
Sunday, 17 February 2013
Sunday, 20 January 2013
The game's developing a bit of a lonely feel. Just you, in space, wandering around uninhabited space mazes. Let's make things more interesting by adding enemies.
I've gone into a bit more detail than usual on this post. Also, if you're using a recent Chrome, Firefox or Safari, there are animated diagrams!
So. The first thing to think about is how the enemies should move. There are a few obvious patterns:
- Move up and down
- Move from side to side
- Go straight and turn when hitting a wall.
- Follow the left wall or the right wall.
- Follow the player.
- Move randomly.
For the patterns that involve turning left or right, we can define two versions of that enemy, a "left-handed" one which turns left and a "right-handed" one which turns right.
So, let's think about how to implement these enemies. What do they all have in common? Well, they all need to decide where to go next as soon as they enter a new square. The difference is in how each enemy makes that decision. Let's start with the simplest, the up-and-down enemy.
Here is a first-draft "decision function" for this enemy:
- If you can go forward, go forward.
- If not, turn around.
Looking at this, you can see that it would work not only for the up-and-down enemy but also the side-to-side one; the only difference is the initial direction. So, we can consider both these enemies to have the same movement pattern; let's call it the Oscillator.
If we use ↑ to mean "go forward" and ↓ to mean "turn around", we can summarize this enemy's movement pattern as ↑↓.
The next enemy type is also pretty straightforward:
- If you can go forward, go forward.
- If not, turn left or right.
We can define a left-handed and right-handed version of this enemy by changing which direction it turns in the second step. In fact, we can define a third version that choses randomly. Collectively, let's call these enemies Flyers, and summarize their movement patterns thus:
|↑↱↓ — Right-handed|
|↑↰↓ — Left-handed|
|↑? — Random|
Now for the wall-followers. This isn't as obvious:
|↱↑↰↓ — Right-handed|
|↰↑↱↓ — Left-handed|
The obvious way to define a player-follower in this system would be to introduce a new command called "follow player" and have the player-follower's list consist only of that command.
We can do better, though. After all, it might be nice to be able to retreat from the player as well as follow them; or follow or avoid a different object, something other than the player.
With one small change, we can create enemies that behave like this using only the forward, backward and turn commands we've already defined.
First, we define a "relative axis" for each enemy type. All the enemies introduced so far have their relative axis pointing forwards, from their point of view. For the player-follower and the player-avoider, the relative axis points from it to the player.
Next, we interpret the results of the decision function differently: forward now means move in the direction of the relative axis; backward means go in the opposite direction, and left and right mean turn relative to the relative axis.
This way, the existing enemies' behaviour is unchanged, but we can define a player-follower with a decision function of ↑ and a player-avoider with ↓. We can also define enemies that follow or avoid any item we like. How about a moth-like enemy that's drawn to a light, or an enemy that's scared of other enemies?
It might be interesting to see how ↱ and ↰ behave in combination with the relative axis; perhaps it will yield some sort of orbiting behaviour?
Also, there may be other ways to play with the relative axis besides pointing it to some sort of target object.