Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    18
  • comments
    12
  • views
    19369

Entries in this blog

 

Station 6 + Box2D physics

Welcome back!

In this week's post I'll be talking about the Box2D physics engine, why I've used it and how I've used it. I'm not going to go into the specifics of how to set it up and use it, though. This isn't a tutorial. For that I recommend you check out the Box2D manual.

So the game is about rewiring things. You run up to an object, pick up a cable, run up to something else, plug in the cable, and then hopefully something exciting will happen. One small but important feature is that the cable you pick up should snake behind you over the floor and on top of obstacles as you carry it around. It's something that will (hopefully) give the wiring-while-platforming experience a little bit more substance.

Initially, I used this algorithm to model the wires. It seemed to work quite well, until I got to the 'snake on top of obstacles' bit, and started to scratch my head as to how it could be achieved. Then I thought "I know! I'll be lazy and use a physics engine to take care of it for me!"

Soon afterward, but before I actually got started with including a physics engine, I played the game LIMBO. It's a fantastic game by the way, I highly recommend it. The realistic physics it has really enhances the puzzles and I think it made the game much more enjoyable than it would have been if it hadn't used some sort of physics engine. It inspired me to try and implement physics in not just the wires, but in the entire world as well. It uses Box2D. I read about Box2D a little bit and it seemed quite good, so I decided to go ahead with it.

I had to think about how on earth I was going to overhaul the entire engine to make it work with Box2D. It seemed like a bit of a mammoth task initially. But wait! I thought of the perfect solution. Why don't I use my existing component based entity system? I could make a specific physics component that, when attached to an entity, would simulate physics on it using Box2D. And that's exactly what I did. The component system made implementing Box2D extremely easy.

Here's the (slightly reduced) class declaration for my physics component:

class Physics : public Component {
static std::vector instances;
static b2World * world_; // The Box2D physics world that simulates physics

entityComponentTypeEnum type() {
return PHYSICS;
}

b2Body * body; // The physics body that is simulated in Box2D
public:
// Constructor for polygon shaped physics bodies
Physics(iVec2 position, unsigned vertexCount, iVec2 * vertices, b2BodyType bodyType = b2_dynamicBody,
float density = 1.0f, float friction = 0.0f);

// Constructor that generates a rectangle shape physics body based on the sprite passed to it
Physics(iVec2 position, SuperMaximo::Sprite * sprite, b2BodyType bodyType = b2_dynamicBody, float density = 1.0f,
float friction = 0.0f);

// Constructor that generates a circular physics body
Physics(iVec2 position, float radius, b2BodyType bodyType = b2_dynamicBody, float density = 1.0f, float friction = 0.0f);
~Physics();

// Updates the Box2D physics world, and then moves all of the relevant entities accordingly
static void update();

// Functions for dealing with Box2D initialisation and finalisation
static void init();
static void free();

static b2World & world(); // In case other classes need to access the physics world

// Game measurements and coordinates need to be converted to ones that work well with Box2D (SI units, i.e. metres, kilograms, etc.)
static float toWorldScale(float number);
static float toBox2dScale(float number);
// And other scale conversion functions for different types...
};



I'll be adding more constructors and functions for more complex systems as and when I need them, for instance if I need to attach two physics components together with a joint.

For the floors, I simply needed to change my Flash level exporter so that it exports the four corners of each floor block, which is then loaded into the game so that floor polygons can be created and put into the Box2D world. It works perfectly with various floor shapes, not just rectangles, but I still need to work out a good method of drawing out these shapes in Flash to be exported.

I've also rigged up the player to use physics. Player movement definitely isn't perfect at the moment, but it's getting there.

As for the wires, I've made it so that they are made up of many small physics bodies joined together. It works brilliantly! They're basically the same as the chain example in the Box2D Testbed program. Here's a video of said program (not by me). Skip to 4:15:
[media] [/media]

That's all for this week, thank you for reading! We'd really like to hear your comments, so please feel free to use the comment box below or send me a message.

See you next week!

supermaximo93

supermaximo93

 

Team Station 6 enters Ludum Dare

[color=#7D7D7B]Hi again![/color]

[color=#7D7D7B]Sorry I didn't post last Friday, I was busy preparing for Ludum Dare, and I didn't have any Station 6 updates to post anyway. This post will be about my experiences during Ludum Dare last weekend.[/color]

[color=#7D7D7B]For anyone who doesn't know what Ludum Dare is, it is a competition whereby contestants have to create a game based on a theme, from scratch, by themselves, in just 48 hours. Any tools and programming languages are allowed to be used, but all content needs to be created within the 48 hour timeslot. The source code needs to be submitted with the entry. After 48 hours, the three week judging stage commences, where the competitors rate each other's games on various categories such as Innovation, Fun, Graphics, Audio, etc. At the end of the judging period all the games are ranked for each category so everyone can see which games came top in which category. There are no prizes given out; your prize is your game.[/color]

[color=#7D7D7B]There's also a 72 hour competition that runs along side, called the Jam. This is a more relaxed version, as it allows you to work in teams, use existing assets, and keep your game closed source. Ben and I entered this competition.[/color]

[color=#7D7D7B]Usually people show their intent to enter by posting an "I'm in!" post on the Ludum Dare blog... We went a step further:
[/color]

[color=#7D7D7B]The theme for this Ludum Dare was 'Alone'. We quickly came to the decision that the game would be about some kind of forest creature (which we nicknamed 'Mike') that wanted to be alone, but the Evil Dr Cuddles wants to get him so that he can give Mike love and attention. As you can see, Mike doesn't like that at all:
[/color]

[color=#7D7D7B]The actual gameplay was supposed to be a cross between Canabalt and VVVVVV. Mike would flip gravity to jump over gaps in the floor and ceiling to run from Evil Dr Cuddles as long as possible. Mike would run through various themed worlds, each with their own boss at the end. We decided there would be four worlds, Evil Dr Cuddles' Lab, the city, the forest, and the sky. The boss for each would be a UFO that shot rockets at you, a bus that tried to run you over, a robot worm that tried to eat you, and a flying pirate ship that shoots at you, respectively. To make the game I was using ActionScript 3 with the Flixel library.[/color]

[color=#7D7D7B]The first two and a half days went way too quickly, and I coded way too slowly. Ben got loads of art done, which is brilliant, but I wasn't able to get into the 'zone'. Also, my code was just a mess. It wasn't really going well for me. Maybe it was my unfamiliarity with Flixel that slowed me down. Maybe it was some wrong early decisions about how to code what.[/color]

[color=#7D7D7B]I had gravity flipping, random level generation, hoops you could jump through that increased a score multiplier, and the first boss, among other bits and pieces. But I was still a long way off from completion, and when I hit a problem that caused a half-second stutter every few seconds due to a fundamental flaw in my level generation and dynamic extension system (I used tilemaps when I, well, shouldn't have), I couldn't take it any more. I threw away the whole thing and started from scratch. I wasn't going to use the overly complicated random level generation system I'd concocted and decided simply that obstacles would randomly appear that you had to jump over.[/color]

[color=#7D7D7B]Now with a mind clear of the old rubbish that I'd been writing over the past two and a half days, I was able to get to work properly. Things went quite smoothly and everything was straight forward this time. I uploaded my entry just 20 seconds before the deadline. There were only two bosses (the UFO and the pirate ship, but they were almost identical) and the game was very unpolished, but I was happy with what I was able to do within the extremely short time frame.[/color]

[color=#7D7D7B]We ended up calling the game 'Gravity Cat ...Thing'. Here's some screen shots:
[/color]

[color=#7D7D7B][/color]

[color=#7D7D7B][/color]

[color=#7D7D7B][/color]

[color=#7D7D7B]You can play Gravity Cat Thing here. Beware, it's a difficult game. I didn't have time to tune the difficulty, I'm afraid. I'll be making an enhanced version soon when I have time, which will fulfil the original vision of the game. If you have any suggestions (other than 'make it easier'... I know ) please let me know![/color]

[color=#7D7D7B]I was thinking of maybe changing it up so that instead of a continuous arcade game style marathon, it's split up into little levels that each require a small burst of dexterity with maybe a sprinkling of puzzle solving. I'd really like to hear your thoughts on this.[/color]

[color=#7D7D7B]And that's all I have to say! We'd really like to hear your thoughts, so please leave a comment or send me a message.[/color]


supermaximo93

supermaximo93

 

Yet more Station 6 artwork

[color=#7D7D7B]Hello again,[/color]

[color=#7D7D7B]I haven't had time to work on Station 6 again this week, due to a lot of work needed to be done before the upcoming two week Christmas school holiday. I was also preparing for the British Informatics Olympiad, a three hour exam where you're given three really tough questions to answer through the use of programs that you need to code, which I took on Wednesday.[/color]

[color=#7D7D7B]Anyway, I'm still not letting up on doing the weekly blog post! All I've got this week is another drawing Ben did today. As soon as the holiday starts after next week (i.e. after Ludum Dare 22 weekend ), I'll be able to put much more time into Station 6.[/color]

[color=#7D7D7B]So, art:
[/color]


supermaximo93

supermaximo93

 

Development of the Station 6 concept

[color=#7D7D7B]Welcome back![/color]

[color=#7D7D7B]Due to the recent influx of school work that Ben and I have had to attend to, we haven't actually been able to work on Station 6 this week. I'm still going to do a blog post though! This week I've decided to talk about where the idea of the game came from, and how it developed.[/color]

[color=#7D7D7B]During the last school summer holiday, I participated in Ludum Dare, an online game development competition where participants have to create a game from scratch in just 48 hours. I created a game called 'Fred the Astro-Miner', where you're an astronaut who's trapped in an asteroid and needs to escape from an alien. You have a drill which you can use to dig so that you can travel down different paths and also collect valuable metals. It wasn't really a good game though. I made it on an extremely busy weekend, and it was also my first time attempting a proper tile rendering system, so that sucked up a large portion of my time. You can download it here.[/color]

[color=#7D7D7B]Ben, on the other hand, drew a comic book, which also happened to be about astronauts, who were floating in space, having their last conversation before their deaths. If I remember correctly, there were two of them, and they were drifting apart from each other, one of which falling towards the Earth. I might ask Ben to scan it in so I can show it to you some time.[/color]

[color=#7D7D7B]Before that holiday, Ben and I were planning to do a game, which was originally supposed to be something a bit like Metal Slug. It was a bit vague really, and we didn't really know what we actually wanted to do. I also toyed with the idea of using XNA, because of it's ease of use and the ability to have it on both PC and XBox.[/color]

[color=#7D7D7B]When we got back to school after the holiday, we discussed about the game and decided to go with a space theme as we had both done projects that involved astronauts during our summers. I also quickly decided against XNA, as although I think it would be pretty cool to have a game on a console, I would rather the game be PC only but be playable on Linux and Mac as well as Windows. I also knew C++ and OpenGL, as well as developed my own library, which I am currently using for the game. If I went with XNA I'd have to learn C# and XNA itself, which isn't hard, but it's just another step away from actually getting started on the game.[/color]

[color=#7D7D7B]We quickly decided that the game should be a puzzle game. We came to the idea that it would be a top-down game where you had to place machines on the map to solve puzzles, and that you were exploring a space station. There would be machines already placed on the map, and the player would have to work out which machines to build in order to make the overall mechanism work to solve the puzzle. I started work on this and eventually I got the idea of some machines that needed to be powered by a source of electricity. In addition to the machines you could place, I made it so that you could also place wire. Electricity would flow through the wires from a power generating source to any machines connected, and those machines would come to life.[/color]

[color=#7D7D7B]I was enjoying using the electricity mechanic quite a lot, and then another idea hit me. Why don't I make the wiring of the machines the main mechanic? And that's what I did. Now, all of the machines were already placed on the map, but you could go into a 'build mode', where you could wire connect the machines together with wires using the mouse. I felt that this was an improvement on the original idea and was able to come up with a plethora of different machines. I also made a few puzzles that centred around just crates, pistons, and buttons.[/color]

[color=#7D7D7B]But there were problems with the design. You might disagree with what I say here, but this is just how I feel. I felt a bit disjointed with the character in the game. The build system was centred around the player being able to be a sort of god who could see the whole map, or a large area of the map around the player, and wire up things as they pleased. The player was just a guy you had to get from A to B. I wanted to have a better sense of 'ooh, I'm exploring this big place, and I don't know what's around the next corner'. When you're looking from a top down perspective, you can already see what's round the next corner before the character you're controlling does. Okay, maybe I could set up a system whereby the player could only see a small circle of the map around them, but I really don't like those kind of games. Ben was also having trouble with drawing the right kind of perspective and wasn't able to find something he liked the look of.[/color]

[color=#7D7D7B]I'm a really big fan of platformers. All of my favourite games are platformers. I don't foresee that changing any time soon. I had a brainwave. Why not make it a platformer? Okay, okay, everyone does a platformer. But in my opinion changing it to a platformer was a good decision, regardless. Instead of pointing and clicking to where you want your wires to be, you get to pick up an oversized mains cable, run up to another machine with the wire dangling behind you, and jam it into another machine to make it work. You can now jump. Before, you were basically defenceless. Now you can bop enemies on the head with your feet! Bosses will be a heck of a lot more interesting as the best thing I could think of for the top down version is just wiring up the machines in a way that corresponds to the boss' movement patterns to shoot lasers or something (you're defenceless, remember). Now bosses (and the rest of the game, for that matter) actually require some sort of dexterity, so wiring up that super laser to blast the boss isn't quite as simple as jumping into build mode and clicking the left mouse button a few times. You now also feel like a smaller person in a big world, which is exactly what I want the game to feel like. You're just this little astronaut in a big space station which you need to get out of, and I think a platformer allows me to convey this feeling in the best way I can. Ben also finds it much easier to draw this way. You may disagree with my decision, and that's fine, it's just that I love platformers [/color]

[color=#7D7D7B]Now to finish off let me remind you what the game will look like with the picture from Ben that I posted a couple weeks ago...
[/color]

[color=#7D7D7B]Thanks for reading! If you have any comments, questions, criticisms, anything you want to say, please leave a comment or send me a message.[/color]


supermaximo93

supermaximo93

 

Station 6 Level Editing

[color="#7D7D7B"]Hello again, welcome back to the Station 6 development blog! This week is going to be a short one as I'm not feeling too great at the moment. I've decided to show you the level editing system I've set up.[/color]

[color="#7D7D7B"]To create levels, I'm using Flash. Yep, that's right, I'm using Flash. Well, the IDE at least. Rather than trying roll my own intuitive level editor (I have done my own in-game level editor, but it's definitely not intuitive!), I was inspired by this article that I stumbled upon when I Googled 'level editor gamedev'. The general gist of it was that you import your art assets into Flash, and then use JSFL (which basically allows you to script macros for the IDE in Javascript) to export the data, as demonstrated in part 2 of the article.[/color]

[color="#7D7D7B"]The difference with mine is that instead of using JSFL, I'm using ActionScript 3, because I wasn't able to find a way of embedding more data into objects into the scene that JSFL could export for me. As far as I can tell, it only allows you to export positions and basic transformations of objects. I have a few base classes that objects in the scene derive from, such as Entity, Scenery, Light, ParticleEffect, etc. which export different data. To add more objects to use, I just put the art asset into Flash, convert it to a Symbol and create a class for it (deriving from the relevant superclass), and adding override methods as necessary. Then I run the Flash movie, copy the traced output, stick it in a text file, and boom, it's in the game.[/color]

[color="#7D7D7B"]Time for a demonstration! By the way, all the art assets that you are about to see are only temporary!It's just some stuff I did to make everything look prettier than coloured blocks Ben's art will be in there soon.[/color]

[color="#7D7D7B"]First off, I load up the level editor base file with all of the objects and layers in place. If you look in the top left corner of the canvas, there's a few objects there. They basically act as containers for each layer of scenery. Objects in Flash can't actually get what layer they are on, so they need to be placed in a container object which has the layer number hardcoded into them, which can then be prescribed to its own layer. The game engine accounts for which layer scenery is on, and renders it accordingly.
[/color]

[color="#7D7D7B"]Now I place down some instances of Block, and resize them to make up the collision mesh for the level. I've also put in a spawn point as reference for the height of the player.
[/color]

[color="#7D7D7B"]Some walls and pillars...
[/color]

[color="#7D7D7B"]Adding some details to the next layer up...
[/color]

[color="#7D7D7B"]Blacking out the floors...
[/color]

[color="#7D7D7B"]And let's finish off by turning down the ambient lighting, putting in some spotlights, and adding some particle emitters.
[/color]

[color="#7D7D7B"]Now run the Flash animation, save the debug output to a text file and load up the game!
[/color]

[color="#7D7D7B"]That's it for this weeks blog post. We'd really like to hear your comments, so feel free to use the comment box below, or send me a message![/color]

supermaximo93

supermaximo93

 

Station 6 technical side: Component based entities

Hi again!

This week I'd like to give you a look at some of the technical details of Station 6. I'll be making numerous posts on how the game works as it develops, to give you an insight into the inner workings of the game and to show you my thought process when it comes to code. I'm using C++, with OpenGL for graphics and SDL for input, audio, etc. I'm using the SuperMaximo Game Library, created by myself, to help with this and handles a lot of the rudimentary code, such as creating an OpenGL context, loading shaders, handling matrix transformations, drawing sprites and 3D models, and a whole load of other stuff.

This week I'll be showing you my component based entity system. For those who don't care about my technical ramblings and would prefer to look at Ben's drawings, scroll down to the bottom of the post.

What is a component based entity?
An entity is an object in the game world that the player interacts with. These entities are constructed of numerous parts (components) that make up the whole functioning object. Each component has a very specific function, and can be mixed and matched to form various different types of entities. If at any time we needed a new piece of functionality for an entity we have in mind, we just create a new component that will handle that functionality, and then just plug it into our entity. If we take a car as an example, the wheels, engine, chassis, etc. are the components, and they come together to create the car; a fully functioning entity. Now that we have an idea of what a component based entity is, lets take a look at some code.

The Entity class
As this is a blog about Station 6, and not just a blog about technical game development stuff, I'm going to show you the exact code that's in the game and explain it, although slightly condensed as not all of it is necessary to the current topic (i.e. we're talking about components, so there's no need to delve into the rendering side of things). So here's the entity class:
class Entity : public SuperMaximo::Object {
static std::vector instances;

std::vector components;

protected:
Entity(std::string & name, int x, int y, SuperMaximo::Sprite * sprite) :
SuperMaximo::Object(name, x, y, -200.0f, sprite) {
instances.push_back(this);
}
~Entity();

void addComponent(Component * componentPtr);
void removeComponent(entityComponentTypeEnum entityComponentType);
bool hasComponent(entityComponentTypeEnum entityComponentType);

public:
Component * componentPtr(entityComponentTypeEnum entityComponentType);
};
Going from top to bottom, the Entity inherits from the SuperMaximo::Object class from my library, and there's a static vector (for those who don't know what a C++ vector is, think of it as a fancy array) that contains pointers of entities, so they can all be looped through, if necessary. We then see a vector of pointers to components. Notice that there isn't some sort of 'update components' method; the components manage themselves and the entity itself doesn't interfere. We'll have a look at that in more detail later.

After the constructor and destructor there's some component methods. addComponent simply pushes a pointer onto the end of the components vector, and gives the component a pointer to the Entity so that it can perform various operations on the Entity. The removeComponent takes an enumerated type representing the type of component that needs to be removed. It searches for the component that corresponds to the enumerated type in the components vector and if it's found, deletes it and removes it from the vector. There's a small gotcha with that which I'll explain later. We then have methods that return whether an entity has a certain component, and a pointer to a component.

The Component class
class Component {
Entity * entitySelf_;

protected:
Entity * entitySelf();

virtual entityComponentTypeEnum type() = 0;

public:
virtual ~Component() {}

static void updateAll();
};
In the Component class there is a pointer to the Entity that it is attached to, so that the component can manipulate the Entity. We then have an abstract method, type, which returns the enumerated type that the component corresponds to, and a virtual destructor, which is a fix for the gotcha I mentioned earlier (explained later). There is then a static class method, updateAll, which updates all of the components in turn, in a specific order. All of the component updates have their place in the cycle of the game and interactions between them are very well defined and predictable, which makes debugging a heck of a lot easier.

For example, all of the Pushable components are updated before the HorizontalVelocity components. The Pushable components check whether their Entity is being pushed by something, and then updates the Entity's HorizontalVelocity component (if any) with the velocity that the Entity now has due to the push. Then the HorizontalVelocity components are updated so that they simulate the motion and update the Entities' position in the world accordingly.

A component example
Let's have a look at the Gravity component. Entities that have this component are obviously subject to a pull down towards the floor.
class Gravity : public Component {
static std::vector instances;

float yVelocity;

entityComponentTypeEnum type() {
return GRAVITY;
}

void collisionTestBelow();
void pushOutOfFloor();

public:
Gravity();
~Gravity();

void setYVelocity(float amount);

static void update();
};
You can probably guess a lot of what this component is doing! On construction the component adds itself to a static vector, and on destruction removes itself. It has a yVelocity data member that is updated when the Gravity components are all updated in the static update method, and the Components' Entities' positions are updated accordingly. The type method is an implementation of the abstract type method in the Component class. The collisionTestBelow and pushOutOfFloor methods are self explanatory.

Here's the gotcha. Why did we use a virtual destructor in the Component superclass? Consider this code that we might use for the Entity class' removeComponent method:
void Entity::removeComponent(entityComponentTypeEnum entityComponentType) {
for (unsigned i = 0; i if (components->type() == entityComponentType) {
delete components;
components.erase(components.begin()+i);
break;
}
}
}
See a problem? Well, the problem lies in 'delete components'. components is a vector containing pointers to instances of Component. So, if we simply use the above code, only the destructor of the Component base class will be called, and not the destructor of the component that we want to delete. So, if we wanted to remove a Gravity component, it's destructor won't be called and therefore it won't be removed from the list of the Gravity components. We'll have a dangling pointer, and when the Gravity update method is called, there'll be a crash when it tries to dereference the pointer to update the (now deleted) Gravity component instance.

You could solve this problem by either using a switch statement that will compare against the component's type enum and then cast the Component pointer to a pointer of the relevant type before deleting it, or by making the destructor virtual. The Component class destructor doesn't do anything anyway, so we don't need to worry about it being called, and instead the Gravity component's destructor will be called.

A concrete example of an entity
Now for the fun bit. Let's say we want to make a crate. We want to be able to collide with it, have it subject to gravity, and be able to pick it up. Here's the resulting Crate class:
class Crate : public Entity {
static SuperMaximo::Sprite * sprite;

public:
Crate(int x, int y) : Entity("Crate", x, y, sprite) {
addComponent(new Collidable);
addComponent(new Gravity);
addComponent(new Pickupable);
}
};
That's it! Nothing more is needed. We have a fully functioning crate that we can put into the game world and it'll work perfectly. We can jump on it, pick it up, and throw it off a cliff and watch it fall. After all the effort of implementing a component system, it pays off when you actually start making entities for the game. It makes creating new objects so much easier and if I want some new functionality for whatever reason, I just code in a new component to handle it. The only downside to this system is that for each entity that is created, a bunch of other objects (the components) are created as well. There are four objects created when instantiating a new Crate, one Entity and three Components. But for a game of this scale, it doesn't really matter!

And that's about it for my post on component based entities!

Art time
Here's a concept for a boss that I thought of today, which Ben kindly drew for me. It shoots lasers from it's pupil and retracts it legs to roll around in an attempt to squish the player.


Thanks for reading! If you have any comments, I'd really like to hear them!

EDIT 19/11/2011: Changed so that Components have a virtual destructor. I have no idea why I forgot about them

supermaximo93

supermaximo93

 

Station 6 art style finalised!

[color="#7D7D7B"]Welcome back![/color]

[color="#7D7D7B"]I'm excited to say that we've decided on the art style for the game, as well as the design for the astronaut. Earlier this week, I asked Ben to draw up a picture of what he imagined the in-game art to be like, similar to the one he produced last week, and he came up with this:

This is what we want the game to look like. I really love the style of this picture, and having the entire game look like this - hand drawn, like an animated, playable comic book - would make it really unique. Ben will be drawing and colouring in the characters and scenery by hand, and then I'll be scanning them in and constructing levels with them in the (currently unintuitive) level editor.[/color]

[color="#7D7D7B"]Here is the final astronaut design, nice and simple:
[/color]

[color="#7D7D7B"]And here's a preview of the astronaut walking animation sprite sheet:
[/color]

[color="#7D7D7B"]Ben's current task is just to get to work on drawing the sprites, while I'm currently working on some rope physics for cables. I want to make it so that when you pick up a cable from a machine, it snakes behind you as you walk around with it. Other than that, there's not really anything else to add to the engine, other than tweaks and increasing efficiency of some areas of the code.[/color]

[color="#7D7D7B"][font="arial, verdana, tahoma, sans-serif"][size="2"]Thank you for reading! If you want to be kept up to date with the latest developments of Station 6, please keep checking back at this journal, at my website ([/font]http://supermaximo.com[/color][color="#7D7D7B"][size="2"]) or follow [/color][color="#7D7D7B"]@supermaximo93 on Twitter.[/color]
[color="#7d7d7b"]
[/color][color="#7D7D7B"][font="arial, verdana, tahoma, sans-serif"][size="2"] We'd really like to hear what you think, so please don't hesitate to post a comment, or send me a Twitter or private message. [/font][/color]
[color="#7D7D7B"][font="arial, verdana, tahoma, sans-serif"][size="2"]See you next week! [/font][/color]

supermaximo93

supermaximo93

 

Introducing Station 6

[color="#7D7D7B"]Hello again! I'm back with more progress on the game I mentioned in my last post. It's called Station 6. So, what is Station 6?[/color]

[color="#7D7D7B"]Station 6 is a puzzle platformer, set on an abandoned space station. You play as an astronaut who's been separated from his colleagues while looking for fuel for their spaceship. They were forced to land on the space station because they were running out of power. It's a Metroidvania, so there'll be great emphasis on exploration.[/color]

[color="#7D7D7B"]The main concept of the game is that you need to rewire the space station in order to solve the puzzles. It's better explained with an example: You have a button, a door you need to open, and a crate. Wire the button up to the door, put the crate on the button, and the door opens! Ben, the game's artist and musician (his Soundcloud page is here), has done a quick comic strip to demonstrate this:[/color]

[color="#7D7D7B"][/color]

[color="#7D7D7B"]Now take this idea, and then add pistons, lasers, mirrors, engines, moving floors, lights, giant crushers of death, aliens, turrets, cannons, epic bosses, etc. (Ben says "Hats"). You can wire up the machines on the station in whatever combination you want, with different combinations creating different results, opening up different areas to explore![/color]

[color="#7D7D7B"]We ('we' being just Ben and I) started this project in late September. The engine is nearly complete, and we will be creating levels very, very soon. We're hoping to get a demo released for Windows and Linux in December (and Mac if I'm able to get hold of one), where you'll be able to play up to the first boss.[/color]

[color="#7D7D7B"]Now here's some concept art:[/color]

[color="#7D7D7B"]This could be the first boss
[/color]

[color="#7D7D7B"]This is what the game will look a bit like
[/color]

[color="#7D7D7B"]Some astronaut designs
[/color]

[color="#7D7D7B"]Thanks for reading! Please keep checking back at this journal, at my website (http://supermaximo.com) or follow @supermaximo93 if you want to be kept up to date with the latest news about the game. We'd really like to hear what you think, so please don't hesitate to post a comment, or send me a Twitter message, or whatever.[/color]

[color="#7D7D7B"]Thanks again, and see you soon![/color]

supermaximo93

supermaximo93

 

VaW: to the backburner for now

Hello again,

I've decided to pause development of Vegetables at War for now. I've been developing another project along side this one, in collaboration with another person doing the art, both graphically and musically. It's started to gain momentum and I thought it would be best if I chose just one project to work on and finish first before the other (and when you factor in school coursework, juggling all of the projects becomes quite hellish). It's a simpler, 2D, top down adventure/puzzle game set in space. And it's just in C++, not C++/Ruby/Javascript for the UI/etc. or any other weird and wonderful combination of languages. I won't go into too many details right now, but it'll take a lot less time to complete than VaW, mainly because in VaW there's so much stuff I want to do!

Thanks to everyone that's been reading these entries! Hopefully VaW will be back soon

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 8

Welcome back!

This week's a short one. Looking back on this week's commits it seems I only worked on the level editor UI a bit more

Oh well, screenshot time:


What got done this week:
I added buttons to toggle snap and nodes (trying to get away from loads of hotkeys!). Click on them to make the assets snap to grid and to start and stop placing pathfinding nodes, respectively. I added save and load dialog boxes that appear when clicking the save/load buttons. Anything behind these boxes get greyed out, thanks to JQuery UI's 'modal' dialog box option. These buttons actually work now, saving and loading from the 'assets/maps' folder. The buttons are now white, and glow when they are either being hovered over or have been selected. They glow orange when the mouse is hovering and blue when they are active. You can toggle between rendering the entire map and only rendering one depth layer. To switch between depths to place objects on, you press the up/down arrow keys or hold Ctrl and scroll the mouse wheel. Choosing to render objects that are only at the current depth can be useful when working on details that might be obscured by objects on depths closer to the screen. Some bugs were fixed.
And that's all. Not very exciting, but I was pretty busy and that's all I got done. At least it's better than nothing! Next week I'm going to take a break from the level editor and experiment with rendering. Should be fun!

Thanks for reading! Any comments are highly appreciated!

See you next time

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 7

Hi again!

This week I've been mainly working on the level editor. So, without further ado, it's time for the customary screenshot!



Let's get all of the small features out of the way first. I've added hitbox rendering, which can be toggled with toggle_hitbox_rendering. When hitbox rendering is enabled, it renders all of the objects' hitboxes that are on depth 0. We don't care about other depths because there won't be any gameplay taking place on them, so there isn't any collision checking at these depths. Also, if you look closely at the fan, you'll see a tall box with nothing inside. That's the hitbox for a force pushing upwards from the fan.

Another small addition is that you can bake the scale of a model when you load it up. The actual game world is extremely small, i.e. one unit in 3D space is one grid space. When using a 3D modelling program, this proves to be extremely small and hard to work with. So what I would normally do is create a 3D model as normal, and in the asset's on_create event, do this:

class Foo # by the way, you derive from classes other than Asset now. This is to help with some Ruby trickery in the map editor.
ASSET_ID = new_asset SCENERY, "foo.obj"
# You still need to specify the asset type in the new_asset though

def asset_id
ASSET_ID
end

def on_create
scale = 0.1
set_x_scale scale
set_y_scale scale
set_z_scale scale
end
end



This would scale the hitboxes automatically when a new instance of the asset is created, and would scale the model every time the model is rendered. I didn't like this approach, as it was a bit cumbersome having to do set_*_scale for every asset, so I decided to make it so that you can specify the scale of the model in new_asset. When the engine loads the specified model, it scales all of the vertex coordinates before dumping it in graphics memory.

Now on to the more interesting stuff! I'll start with the pathfinding nodes. When you enter the map editor, you can press the N key to toggle between placing nodes and placing assets (I still need to add a button to the UI to do this). The nodes are represented by the green circle sprites. So you can stick them around the map my point and click, with right click to delete, as you'd expect. To join nodes together, you click on a node and drag to another node that you want to connect it to. A yellow line connects the mouse and node together while you are dragging. The line turns red when a connection has been made, and then the pathfinding algorithm will be able to use that connection. To break a connection, just click and drag between two nodes that have a connection. You can toggle the node rendering by using toggle_node_rendering. When you enter the map editor, node rendering is enabled by default, and then turns off when you leave. You can also tell the AI to render a path that it has chosen to follow after pathfinding. So the node infrastructure has been set up; now I need to code some AI to use it!

Finally, onto the UI, which still needs work, but it's getting there. I really like the look of the UI Wolfire did for their game Overgrowth. A quick search of their blog revealed that they're using Awesomium to manage the UI. Awesomium basically allows you to embed web pages into your applications by using Webkit. This is really great as it allows you to create a UI using HTML, CSS and Javascript (which is especially good for me because I used to be really into web design a little while back), and then hook it up to your game by loading it from a local file. It's cross platform, and has APIs for C++, C and C#. It can also be used in Unity.

The pseudo code for using it is

Initialise by creating an instance of WebCore
Create a WebView (which renders the page) from the instance of Webcore
Toggle background transparency
Bind handlers for various events, to be notified of events such as when the page has loaded, when a Javascript function is called on WebView objects, etc.
Load page

while you want to render your UI
Send mouse and keyboard information to the WebView
Call Update on the instance of WebCore

If the WebView's display has changed put the WebView's renderbuffer into a texture

Render the UI texture
end

Delete WebView and WebCore instances



I don't really have much else to say about it, other than to check out the samples with the SDK (which is free for indies and evaluation purposes). It's really simple to use and I highly recommend it! At the moment, there is an 'Asset Viewer' window that allows you to choose assets to place into the scene. To open and close it, you click the spanner icon on the top toolbar. At the moment the save and load buttons don't do anything

That's it for this week. Any comments are appreciated!

See you next time

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 6

Hello once again!

This week, I've dabbled in a bit of scheduling, path finding, and map-editor-making...

Screenshot time:



It looks a bit more interesting this time! I've started to make a map editor, which at this moment in time is very primitive. The only thing you can do with it at the moment is put assets around the place. And when I press the reset button, it all disappears and we're left with the same thing you've been seeing for the past few weeks. But it's a start! To get into the map editor, just hit the '`' key (the one to the left of the '1' key), which allows you to enter Ruby commands via the terminal, and type 'start_map_editor'. To stop, do the same thing with 'stop_map_editor'.

I've added a scheduling system to the AI, inspired by Source Engine's thinking system. At a basic level, you can delay the AI run method from executing for a time using the delay method, passing the amount of time to delay in seconds. More interestingly, you can schedule functions to be called at a later time, by using the schedule method, passing the function to call and the time to delay the execution in seconds. You can use Ruby Procs, Lambdas, and class methods, like so:


class ExampleAi def this_works
puts "This works!"
end

def init
# scheduling the class method this_works to be called in three seconds
schedule :this_works, 3.0

# using a Proc
this_also_works = Proc.new { puts "This also works!" }
schedule this_also_works, 4.5

#or just
schedule Proc.new { puts "This also works!" }, 4.5

# basically the same thing with a Lambda
schedule lambda { puts "This works too!" }, 6.0
end
end
An example of where this would be useful is when you might be running a bunch of stuff that needs to be done per frame, like moving along a path, in the run method, and then scheduling a function that checks the world conditions and modifies the current state of the AI depending on those conditions, so that the code in the run method will do something different. Or maybe you could schedule pathfinding every so often so that you can chase some guy who's running away without bogging down the CPU with pathfinding every single frame!

Speaking of pathfinding, that's another thing I've added. This is the first time I have actually dabbled with it! Before touching VaW, I decided to implement an A* algorithm in Pascal. I chose Pascal because the CRT unit is so useful for basic terminal graphics! I haven't found a C++ equivalent yet (although I can't say I've tried looking ). The first time I saw it work, even with a tiny wall separating the start and finish, was a big 'wow' moment for me! Here's a quick screenshot of the finished program:




Then I started implementing something similar for VaW. Rather than using grid spaces as nodes I've created a Node class so that I can put instances of them in optimal positions around the map. The only heuristic at the moment is the distance the current node is away from the end. I haven't really given it a proper test yet but I want to get the map editor up to a reasonable standard first, so that I can intuitively place nodes around the map rather than guessing and sticking them in various places via a script.

That's it for this week! Thanks for reading, and any comments are appreciated!

See you next Wednesday

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 5

Welcome back!

Same story, busy weekend, lots of homework, not much done, blah blah blah. This entry is going to be pretty short.

Screenie!



This week I've been doing a bit more on collision detection. I created a program that allows you to open up a model in either Wavefront OBJ or my own 3D file formats (SMM (SuperMaximo Model) and SMO (SuperMaximo Object)), and simply click and drag rectangles over the model which will act as the hitboxes for when the game does precise collision detection. It uses GTK 3 for the little side window.

As you can see from the screenshot, the hitboxes are quite rough, but the game is going to be fast paced, so it doesn't really matter. The game engine generates an even rougher hitbox on load time for super-quick collision checking, so there's no need to create one here. The hitboxes created with this program are actually rotated by the engine by multiplying each vertex with a rotation matrix when the asset rotates, so that the collisions don't screw up, but the auto-generated rough one is big enough so that it doesn't need to be rotated.

Here's a snippet from my game library that handles 2D point-in-polygon collision (I did this a while back, but it doesn't hurt to have it here). This is done for each vertex of asset A's hitbox against the hitboxes of asset B (and then vice versa), during the precise collision checking stage. If the dot product of the vector of the first vertex of a polygon edge to the point and the perpendicular vector of the polygon edge are less than 0, then the point is outside of the polygon.


bool vec2::polygonCollision(unsigned vertexCount, vec2 * vertices) {
for (unsigned i = 1; i if ((vertices[i-1]-(*this)).dotProduct((vertices-vertices[i-1]).perpendicular()) }
if ((vertices[vertexCount-1]-(*this)).dotProduct((vertices[0]-vertices[vertexCount-1]).perpendicular()) return false;

return true;
}


And that's it for this week. Not much, I know, but at least it's one more thing crossed off my checklist!

See you next week

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 4

Welcome back!

Once again, I haven't had a great deal of time to work on VaW, as I came back from a trip to France on Sunday and started school the following day. But I've got a few bits and pieces done.

Customary screenshot:


As you can see, I'm playing as a tomato. What's great about the Asset-Player relationship is that humans and AI can step into the shoes of any Character asset they want with the set_player method for Assets and the set_ai method for Players (though the instance of Player with an ID of 0 is the human player regardless). But this isn't anything new.

I've created a new fan asset (complete with spinning fins! ) that basically manages a Force that pushes upwards (just 'cause I can). I've renamed the Beam force to Push and also created a Pull force. They just push/pull in one direction. When a fan is created, it creates a Push force that is directed upwards (and destroys the force on fan destruction). Jump above the fan and you'll be propelled into the air!

I've created a new Asset type: Projectile. At the beginning of the project I felt I didn't need this kind of Asset as you could just create one by using a Generic type. But I created this type because bullets needed to selectively collide with objects, i.e. they should not collide with Assets of the same team as the Asset that shot the bullet. I don't fancy friendly fire, to be honest. To create an instance of Asset with type Projectile, you just do this in the Item Asset code:

def on_fire
myBullet.new rotation, x, y, team
end


An instance of myBullet is created, firing in direction rotation at the specified coordinates and with the team of the Item it is fired from (which the corresponding Character Asset it is attached to gives to it). The Projectile's speed, gravity, etc. is defined in the class definition in the new_asset method which loads up the Asset data into the dictionary. Projectiles are also rotated to their direction by the C++ engine, so if they are affected by gravity or a Force, they won't look weird.

Lastly, I've optimised the collision algorithms. Before, I was using the quick to implement but nasty 'loop through every instance and then loop through every other instance and check if they collide' algorithm. This wasn't really a problem in terms of speed, because there weren't a great deal of objects to collide with. But I felt I should optimise it now in this early stage, just to get it out the way, and so that I don't need to do it later when there is more code to potentially break. I used a simple spatial partitioning system that splits the scene into a 2D grid (no need for full 3D collision detection in this game!), and then all of the assets decide which grid spaces they occupy, and stick themselves in the relevant grid spaces' lists of assets it contains. Moving Assets such as Generics, Characters and Projectiles are relocated when they move, but static assets like Scenery only do grid calculations on construction. Any Scenery at a depth other than 0 or are not collidable are not included.

There is actually a separate list in a grid space for each type of Asset, so that they can selectively collide with other types. For instance, Projectiles need to collide with Generics, Characters and Scenery, but not Items or other Projectiles. Actually, Projectiles never get their own collision detection stage in the collision handling part of the game loop. Scenery collision is handled earlier in the loop, at the stage where Assets are moved according to their velocity. I decided (for no reason) to check for collisions with Generics first, which involved other Generics, Characters, and Projectiles. Then Characters are checked for collision against Scenery and Projectiles (we've already done Generics!). Scenery, Generic and Character collision has already been handled, so no there's need to do any more checks.

And that's all the main bits this week! There were some other bits and pieces and tweaks, but they aren't particularly notable. On my to-do list I've got some pretty chunky things to be getting on with, so next week should hopefully be a little bit more exciting!

Thanks for reading, and I appreciate any comments

See you next week!

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 3

Hi again!

So, what have I been up to this week? Well, I was a little bit busy with other things not related to programming, and I also spent a day creating a C wrapper and corresponding Pascal DLL loader for my game library, which I mentioned a couple weeks ago as something I should do.

So it's time for a screenshot, yet again:


You'll notice there's another veggie on the scene! I started doing a little bit of AI work. I created a Ruby AI class for different types of AI to be derived from, which only has two base methods to be overwritten: 'init' and 'run'. Init is obviously run when the AI is created and run is called every frame. It also stores the ID of the Player instance (which I mentioned last week) that it is controlling. My intention for this minimalistic base is so that I can implement any sort of AI system I feel like, because there aren't any hard and fast rules implemented. As I experiment the base AI class might expand though.

For a laugh, I decided to quickly implement the AI of the original VaW; enemies mindlessly walk toward you, aiming to your exact coordinate and firing as fast their weapon could shoot:


class TestAi def run
# Find the target asset, which is the asset the player is controlling, and the asset this AI is controlling
target = $assets[$players[0].focus]
me = $assets[$players[@player_id].focus]
# Break if either are nil
return nil if (target == nil) || (me == nil)

# Move towards the target, in the same fashion as the original VaW: slowing down the closer it got
right((target.x-me.x)/50.0)

# Aim towards the enemy with deadly accuracy
aim(direction_to_asset(me.instance_id, target.instance_id))

# Fire as fast you can!
trigger
end
end

Simple. Although I surely don't intend to keep the AI like this forever

It's also fun to switch round and play with the tomato, having the AI control the carrot!

Next up was sorting out velocity on Character assets. Before, when the player pressed left and right, they would instantly travel in that direction. The assets had an X and Y velocity beforehand, but for the horizontal plane it may as well have not been there. You could also change your direction in mid air in any way you pleased. This was a problem for a feature which I'll mention in a minute. I changed the code from this (in pseudo code):

if left pressed {
x velocity = -speed
} else if right pressed {
x velocity = speed
} else x velocity = 0

to

if left pressed {
x velocity += (difference between destination velocity (-speed) and current velocity) * (interpolation value)
} else if right pressed {
x velocity += (difference between destination velocity (speed) and current velocity) * (interpolation value)
} else x velocity -= (current velocity) * (interpolation value)


This interpolation value changes depending on whether the player is in the air or not, with a lower value if they're in the air. Now the player smoothly starts and stops moving when on the ground pretty quickly, but when in the air it's harder to change direction, which I prefer. I've also made it so that you can control the distance of your jump with the jump button. For longer jumps hold it down for longer, and for small jumps, just a quick press is needed. This is also done by changing the interpolation value. To make sure that this still happens even when left and right are pressed, the left pressed/right pressed branches just do a goto to the final else branch if the player is in the air.

The final thing I want to mention (which I'm still tweaking), is the Force class I've added (well, it's a struct on the C++ side). Forces can either be Explosions, Implosions, or Beams. Explosions and Implosions obviously push outwards and inwards, respectively, in a circle. Beams are rectangles of pushing force, like a fan blowing (or a Star Wars Force Push ). Forces keep acting on objects until they are destroyed. I was able to implement rocket jumping by simply creating an Explosion force when a bullet was destroyed! It wasn't perfect though as the force needed to be destroyed a few frames after it's creation. I'll probably make an explosion asset, to deal with this, which would manage the creation and destruction of the force with a particle effect thrown in.

So that's all for this week! Again, I won't have a great deal of time to work on the game this coming week as I'll be in France until Sunday, and then I'll be starting school the day after.

See you next time!

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 2

Welcome back!

I haven't had much time to work on Vegetables at War this week. I was in Ludum Dare #21 this weekend! I was busy making sure my game library was ready, then busy actually making my game, and then after the deadline, busy trying to compile the damn thing for Windows. I wasn't able to actually able to do it successfully until about an hour ago!

You can see the game here: http://www.ludumdare.com/compo/ludum-dare-21/?action=preview&uid=4920

I tried Visual Studio first, but it didn't like some of my (perfectly valid) code, so I spent ages rewriting a lot of it, only to spend even longer trying to get the program to link. Then, when I finally got it compiled, it just didn't run! So I thought, "Why don't I just use the Windows versions of Eclipse and G++, like I do in Linux?". So I downloaded Eclipse and Mingw which had the G++/GCC compiler. It didn't complain about my code, which was a good start! Long story short, I still spent a long time trying to get stuff to work, but eventually I got it working by compiling GLEW from source with the game and making sure I had the Mingw SDL libs instead of VS ones (doh!).

Oh, and I bought Super Meat Boy. That took up a lot of my time

So, screenie:



It's almost the same as last week. I've updated my shaders so that there is a fog effect which becomes more intense as objects move into the distance. Originally, I wanted to have a blur effect, (which, again, would become more intense as you move back), but I think this looks good and was a lot easier. To achieve a blur effect, I would've had to render to a texture the objects I wanted to blur, then render that texture with a blur effect implemented in the fragment shader which would smudge the each pixel with adjacent pixels. I did get the rendering to a texture working actually. Then I tried the fog effect to see what it would look like, and then proceeded to scrap the blur idea

Each asset of type Scenery has a 'depth', which is independent of the Z value in space. It's the Z value according to a grid, with positive Z going into the screen, negative coming out. A depth of 0 is where the action of the game takes place, as you can see by where the carrot is standing. I used this in my fragment shader to determine how much the colour of the object should be blended with the background colour to produce the fog effect. I also needed to make sure that anything that is not Scenery or anything that has a depth less than or equal to 0 has no fog effect added to it.

The code to implement this (in the fragment shader) looks like this:

//'depth' and 'maxDepth' are floats (but they may as well just be integers) passed in by a shader uniform, which are grid depths.
//'z' is the z coordinate in space calculated by the vertex shader, which takes into account transformations so that the fog shading doesn't get screwed up

fragColor.r += (backgroundColor.r-fragColor.r)*((depth-z)/maxDepth)*clamp(depth, 0.0, 1.0);
fragColor.g += (backgroundColor.g-fragColor.g)*((depth-z)/maxDepth)*clamp(depth, 0.0, 1.0);
fragColor.b += (backgroundColor.b-fragColor.b)*((depth-z)/maxDepth)*clamp(depth, 0.0, 1.0);


What this code does is it takes the difference between the background colour and the current fragment colour (taken after texturing, lighting, etc.) and multiplies it by the percentage of how far away it is from the depth where every fragment becomes the fragment colour. Then it's multiplied by whether the depth is greater than 0, which acts as an IF statement. GPUs aren't good at branching, remember! Then this value is added to the fragment colour.

I can change the maxDepth value and background colour via script, which is very handy and only took a minute to implement! Yay for the super easy to use Ruby extension API!

Thanks for reading! Hopefully I'll get a lot more done this week than in the past week.

I'll see you next time

Max
@supermaximo93

supermaximo93

supermaximo93

 

VaW progress: Week 1

Hi again!

So, Vegetables of War has now been in development for one week. So before I start getting into the details, let's have a look at a screenshot!

Yay, programmer art!


Well, it's better than a bunch of grey blocks

It may not look particularly exciting, but there's a lot going on behind the scenes. I'll try and keep it to the main bits in this entry.

Rather than implementing the whole game in C++, I've decided to implement scripting, using my favourite scripting language, Ruby. It's working really great already, even at this early stage! The game engine itself is a Ruby extension, which is loaded from a script. After the script initialises the game's script-side classes and assets (more on this later), control is then transferred to the C++ game loop in the extension. The various scripts are then called from the game loop, triggered by events. That's basically it.

Ruby's extension API is extremely easy to get to grips with. Let me give you a quick example, where we get Ruby to say "Hello world!" from C++:


//VALUE is a data type that Ruby passes to C/C++ functions. Ruby also expects you to return this data type.
//The Ruby extension API gives you functions to convert to and from VALUEs.
//For example, to convert from a Ruby number to an int, you can use FIX2INT(VALUE) and to convert an int to a Ruby number, use INT2FIX(int)
VALUE helloWorld(VALUE) {
printf("Hello world!");
return Qtrue; //We can return a C/C++ data type converted with a conversion function, or a Qnil, Qfalse or Qtrue
}

extern "C" {

void Init_my_extension() {
VALUE module = rb_define_module("myExtension"); //We use the value returned from rb_define_method to interface with Ruby from C/C++

//Define our helloWorld function, which takes 0 arguments.
//The first VALUE parameter of our function is required, but not included in the number of arguments that we tell Ruby that we want our function to be passed
rb_define_method(module, "hello_world", (VALUE (*)(...))helloWorld, 0);

//We can now call 'hello_world' in our script, or (pointlessly) call it like this (but the procedure is the same for calling any method in Ruby from C/C++)
ID helloWorldMethod = rb_intern("hello_world")

//We can pass arguments to the method by specifying the number to pass and converting them to Ruby VALUE types. In this example there is nothing to pass
rb_funcall(module, helloWorldMethod, 0);
}

}



Now just replace that helloWorld function with a game loop

All the assets in the game are scripted. To add a new asset, all you need to do is write a Ruby script that contains a class derived from the 'Asset' class, and dump it in the assets folder. The game will load the script and hey presto, your new flying unicorn with lasers is in the game! Assets can be one of four different types: Generic, Character, Item or Scenery. The engine takes care of some general behaviour of the asset, depending on the asset type. For example, Generics and Characters are affected by gravity, and Characters are affected by events called by a Player (more on this later!). So if you make your flying unicorn with lasers a Character, he'll be given the ability to walk around and jump for free. You can still do this with other asset types, but you'll need to script them in Ruby yourself. Items are attached to Characters, and are aimed towards the mouse automatically. I refrained from calling Items 'Weapons', as they don't actually have to be weapons. They can be whatever you script them to be. Scenery makes up the world, don't have to collidable, and can be placed at different depths (you can see this clearly with the flowers at different depths in the world, with the carrot at depth 0).

Assets contain event methods, that are called when different events happen in the engine, as long as the asset is listening to that event. Let me give you a quick example:


class Foo # Tell the engine about this new type of asset and stick it in the asset dictionary
# This includes passing the events we want to listen to in an array

ASSET_ID = new_asset CHARACTER, "foo.obj", [ON_TRIGGER, ON_COLLISION], 10, 1, []

# This is needed to make things actually work when you insert an instance of this asset into the world with Foo.new
def asset_id
ASSET_ID
end

# We don't need to pass ON_CREATE or ON_DESTROY to new_asset
def on_create
set_player(0) # Make it so that this asset is controlled by a human
end

# Called when the player presses the trigger key
def on_trigger
puts "Bang!"
end

# Called when we collide with another object
def on_collide(other_asset_id)
puts "Ouch, I just hit another asset! It's ID was #{other_asset_id} and it was a #{$assets[other_asset_id].class}"
end
end



What's this 'set_player' method all about then? To call events that are naturally bound to user input, such as ON_LEFT_PRESS, ON_TRIGGER, etc. I've created a Player class. This player class gives an abstraction between the asset and the thing controlling the asset. This 'thing' can either be the human player or (eventually) AI. This means assets can be scripted without the worry of tailoring it to some sort of AI. The asset can be bound to a Player, and this player can then be controlled by the AI, as if the AI was pressing buttons on a keyboard just like the player.

Lastly, you can create and destroy lights via script. Use 'my_light = Light.new', passing the position, colour and intensity you want, to create a light, 'my_light.get(something)' or 'my_light.set(something, data)' to get and set light data and 'my_light.destroy; my_light = nil' to destroy the light.

I (think) that's about it. I got quite a lot done this week, especially considering I was very busy over the weekend with other stuff.

Thanks very much for reading, I'll see you next week!

Max
@supermaximo93

supermaximo93

supermaximo93

 

What is Vegetables at War?

Welcome to my journal! Every Wednesday, I'll be posting updates to the development of my next game, Vegetables at War (yes, it's Sunday today, but I want to get this introduction out the way ).

So what is Vegetables at War? Well, in the late Spring of 2007, when I was 13, I came up with an idea for a game I wanted to make whilst walking to school. I was using Game Maker at the time, and had just got bored with my last half finished project and was looking for something new. Something that wasn't too difficult to make, and something I could finish! The basic concept was vegetables fighting over bowls of soup to win some sort of soup contest. A pretty crazy and frankly dumb idea, but it's fun And I've been making stupid but fun ideas for games ever since. Leprechauns throwing rocks at Romans unleashing havoc with 'Rainbow Power', A cat defending his giant sack of catnip from hordes of cans of spam with legs (AKA Spambots), you get the picture.

Anyway, back to VaW. Three months later, I finished the game! It looked like this (sorry for the horrible jpeg artefacts):



You can play it at http://sandbox.yoyogames.com/games/16472-vegetables-at-war, if you really want to.

The game was a massive hit in my school. I don't know how and I don't know why, but everyone loved it. To this day, people in my school still play it. I'm still known as 'the guy who made Vegetables at War'. It was a great learning experience actually; when I started, I was still doing drag-and-drop Game Maker, but during development I got to grips with GML, which started me off on 'proper' programming (I might have had done a bit of PHP by then, but I don't think so)

The concept was simple: You play as a carrot, who has to destroy bowls of soup, guarded by enemy vegetables. As you progress through the game, you meet different vegetables (9 in total) with different weapons, including tomatoes with bazookas, sword wielding leeks and chillies that shot fireballs from their magical staffs. Once you take down one type of vegetable's 'Grand Cauldron' - which was sort of like a boss - at the end of each stage (each stage consisted of four levels), you could then buy that vegetable's weapon to use. There were 40 levels in total (the last four levels consisted of every vegetable fighting against you, with a massive war at the end with a golden cauldron and carrots that spawned to help), and a multiplayer mode that was played between two people over one keyboard.

You were also able to dress up your carrot with a variety of hats, glasses, and noses! And there were golden spoons to collect hidden around the game, peaking out of clouds, inside destructible floors, etc. Once you collected them all, you got 10 times the amount of money (AKA nutrients) from each enemy killed. I kind of wish I hadn't put them in, because it's really annoying having this conversation over and over again:

Them: "Can you tell me where all the golden spoons are?"
Me: "No, I don't know where they are!"
Them: "But you made the game!"
Me: "I've forgotten where they are."
Them: "... ... ...Can you tell me where all the golden spoons are?"
Me: *sigh*

I made a couple of small spin-offs (again made with Game Maker). The first was a top down RTS, and that failed. The next went well though. It was multiplayer game that could be played over a LAN, which featured updated weapons, clothes and graphics. There was a central server program that had to be run that stored details of all the players (wins, losses, etc.) and served as a match maker. When two players where connected they could fight each other for three minutes. It wasn't as successful as the original VaW. I think it might have been because it didn't have the 'jump in, play for 10 minutes, jump out' factor. You needed to have the server program to be running on the LAN to be able to actually get into the game, and I was the only one that had it. And when the server was running, logging in and out took an age ("I clicked 'log out' and it's not logging me out!" "Don't worry, it'll be done eventually...").

I've been promising a sequel to the original VaW for years now. I started something a couple years back (once again, in Game Maker), which ended up being pretty cool, you could pick up, drop, and switch through weapons, (which had cool little recoil animations, some had laser pointers, some were hit scan, etc.), open doors, shoot at a punch bag, sprint, blah blah blah. It was nothing more than a small play area demo thing, though.

So that's the history of Vegetables at War. So where am I now? Well, for a start, I don't use Game Maker any more. I'm a much better programmer than I was. I'm using C++, SDL, and OpenGL (up to date OpenGL, mind. No fixed function here!) comfortably. I've created my own game library (source here: https://github.com/supermaximo93/SuperMaximo_GameLibrary). I'm not sure what in the library constitutes as a 'cool feature', except for my skeletal animation system (which you can see in action here: ). I really enjoy developing it and it's extremely rewarding to complete a game using all your own code (one such game was the catnip one I mentioned earlier, using the Pascal version of my library, which isn't as up-to-date as the C++ version... Wait a second. I just had a thought as I'm typing right now. How about I create a C wrapper for the C++ version, and then it can be ported to all sorts of languages rather than maintaining separate projects for each language I wan't to support? Duh! ).

So this sequel. Well, there isn't going to be a sequel. I don't want this game to be the continuation of Vegetables of War. I want this game to be Vegetables at War (that, and I don't really want people to go "so what was VaW 1 like? ... ... ... Oh." ). I've put some designs on paper over the past couple of weeks (which will be expanding constantly as I reach certain milestones in development, but there's always ideas, plans and algorithms swirling around in my mind), and I've got a clear vision in my head. Now I just need to realise it! It will probably take me a long time to get to that vision, but I'm determined to finish!

A few quick details about the game: It's going to be in 3D, but a side scrolling platformer (think New Super Mario Bros.). It's going to be class based (each class is a vegetable, naturally) with teams fighting against each other. There'll be a campaign/story mode and an online multiplayer mode. Maps will be centred around the original soup bowl (i.e. tower) defence mechanic, hopefully leading to some interesting gameplay. I've got a few ideas written down about different map types but that's for another day! And of course, you're going to be able to customise your veggies with all sorts of clothing!

Coding started on Wednesday, which is why the next entries will be on Wednesdays. You'll be able to see the development of the game week by week. Development will slow down a bit when school starts again, but I intend to stick to the schedule.

So, that's all for this post. Thanks for taking the time to read this introduction!

See you on Wednesday

Max
@supermaximo93

supermaximo93

supermaximo93

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!