I’m currently writing a Ruby-like language (it’s less dynamic and offers some static analysis for better errors) for game development, and so currently I’m thinking about future features. Dispite what I have said in the past on this subject, in principal I like the idea of componetizing parts of your game objects into indevidual parts rather then through inheritance. An obvious thing to then add is Ruby mixins.
However I’d like to go further then this with more features to help with building component oriented systems. Namely the idea of being able to hook multiple pieces of behaviour together, like events, onto a game object to compose it. Here is the example I current have worked out. Lets say you have a Sprite class that is the base for everything in your game:
class Sprite
def new( level, img )
@level = level
@img = img
end
def update( delta )
// do nothing
end
def draw()
drawImage( @img, getX(), getY() )
end
// getX(), getY(), move(), setLocation(), getLevel(), etc
end
It holds onto the level, has a location and has an image drawn at it’s location.
Now you want to create two new game enemies: a missle and an asteroid. Both hurt the player, one moves towards the player and the other wonders randomly around the screen. These could then be implemented as seperate modules.
module RandomMove
after update( delta )
this.move( rand(-speed, speed)*delta, rand(-speed, speed)*delta )
end
end
module HurtPlayer
after update( delta )
this.getLevel().isCollision( :player, this ) do |player|
player.damage();
this.remove();
end
end
end
module TowardPlayer
after update( delta )
this.moveTowards( this.getLevel().get( :player ), delta )
end
end
Modules define methods, but can chose to be appended to existing ones using the after keyword (or before or around if they chose). To use them they are included to a class, just like in Ruby.
So creating a new Asteroid and Missile is now simple, you extend the Sprite class and add the appropriate components:
ASTEROID_IMG = new Image( "asteroid.png" )
MISSILE_IMG = new Image( "missile.png" )
class Asteroid < Sprite
include RandomMove, HurtPlayer
def new()
super( ASTEROID_IMG )
end
end
class Missile < Sprite
include TowardPlayer, HurtPlayer
def new()
super( MISSILE_IMG )
end
end
Obviously modules could also be used like normal Ruby mixing, like for drawing that image:
module Drawable
def setImage( img )
@img = img
end
def draw()
drawImage( @img, this.getX(), this.getY() )
end
end
class Missile < Sprite
include TowardPlayer, HurtPlayer, Drawable
def new()
setImage( MISSILE_IMG )
end
end
However with my modules you could also append another draw object to draw a shadow before draw is called:
module DrawShadow
before draw()
// draw shadow
end
end
class Missile < Sprite
include TowardPlayer, HurtPlayer, Drawable, DrawShadow
def new()
setImage( MISSILE_IMG )
end
end
It essentially boils down to Ruby mixins + after, before and around. But do people think this would be a bit useful for a game oriented language, or very useful?
An alternative would be to implement something totally different as my language is Ruby-like, not Ruby (feel free to offer your suggestions). A while back I had originally settled on full aspect orientation, but now I’m wondering if that is just too wild and crazy (I never liked how they just magically join onto bits of code elsewhere in your program).
Please just discuss, I’m really looking for as much input as I can find to help me make the right decisions before implementing anything like this.
Edit: something else I’ve been thinking about is being able to create objects purely from modules, removing the need to even have a MissleSprite (or even a Sprite). But I have no idea what this would look like.