blog | Page 2

Pixel art Skeletor

Skeletor

Skeletor

(No Comments on Pixel art Skeletor)

Nito

Haven’t uploaded some pixel art in a while, so here is Gravelord Nito from Dark Souls! He’s my favourite boss from Dark Souls by a long shot I think. ;)

A pixel art version of Gravelord Nito from Dark Souls.

A pixel art version of Gravelord Nito from Dark Souls.

(No Comments on Nito)

Dark Souls fan art

Here’s some fan art I did for Dark Souls. The base line work is in the previous post. I coloured it digitally.

Havel

(No Comments on Dark Souls fan art)

Sketch

A  sketch of Havel from Dark Souls.

A sketch of Havel from Dark Souls.

(No Comments on Sketch)

I’m Sick Today

Here’s a short game I made when I was sick. You have to infect everyone with your ickyness.

PLAY IT.

Spread the germ-love..

Spread the germ-love..

(No Comments on I’m Sick Today)

The Hound

The Hound!

The Hound!

(No Comments on The Hound)

Pixel Swamp

A pixelly swamp based on Roger Dean's Greenslade cover

A pixelly swamp based on Roger Dean’s Greenslade cover

(No Comments on Pixel Swamp)

Sketch

A few creature sketches.

A few creature sketches.

(No Comments on Sketch)

Crash

Here’s a new game I made for the cyberpunk game jam over at itch.io. I made it over 5 days with Ben Weatherall doing the cyber-art and Tim Shiel cranking the cyber-music. It’s about hacking robots while plummeting to your doom, and it requires fast typing and hacking skills. Play it now. You can also listen to the official sound track over here.

Crash

(No Comments on Crash)

An entity system

Here’s a cross-post from my Moonman devlog.

Update: Well it’s been a while, but here’s my first update for 2014. I haven’t touched MM code for a month but instead have been designing and implementing a cleaner and simpler entity system. I’ve been meaning to do this for quite a while now, but after using Unity and looking at other bits of code like entityx I decided to finally attempt it. This is helped in part by the new c++ support in VS2013. The system is also data-oriented — all components and entities are tightly packed in memory. I use a similar free list setup as in MM. I also had to use some c++ techniques I haven’t used before, such as variadic templates and typelists. But that is all behind the scenes, this is what the API looks like:

EntitySystem es;

// Create an entity
// and add some components
Entity& e = es.create();
e.add(Transform(4,5));
e.add(Health(10));
e.add(Physics(0,-10));
e.add(ShortDescription("Ben"));
e.add(Description("An architecture-obsessed programmer."));

// Create another entity
// with different components
// this time using intializer_list shorthand
Entity& chest = es.create();
chest.add(Transform(-4.5f, 0.8f));
chest.add(Inventory{
  { Item::SWORD },
  { Item::POTION, 4 },
  { Item::POTION, 3 },
  { Item::ARROW, 64 }
});

// If we need to keep a reference to an entity
// then we use ID's (uint32s)
ID chestId = chest.id;

// Then later on somewhere we can get the entity
// and do something with it, e.g.,
if (es.has(chestId)){
  Entity& ch = es.lookup(chestId);

  // Shift the chest one unit horizontally
  Transform& tr = ch.get<Transform>();
  tr.x += 1;
}

// Iterating through all entities
// can be done with a range-based for loop
for (Entity& e : es.entities()){
  std::cout << e;
}

// Likewise, we can iterate through all 
// components of a particular type. For 
// example a PhysicsSystem might want to 
// process all the Physics components.

for (auto p: es.components<Physics>()){
  // Apply viscocity
  p.vy *= 0.9f;
  p.vx *= 0.9f;
 
  // Move entity
  Entity& e = es.lookup(p.entity);
  Transform& tr = e.get<Transform>();
  tr.x += p.vx;
  tr.y += p.vy;
}

// Everything is done with references
// if e doesn't contain C, then 
// e.get<C>() returns a blank component
// (which can be checked for validity)
Entity& e = es.lookup(id);
Health& health = e.get<Health>();
health.health = 666;
if (health){
  // It's valid
}


// Components themselves are just structs
// The CRTP gives them a unique class id
// that is used to store them in EntitySystem
struct Health: public Component<Health> {  
  float health;
  bool poisoned;
  Health(float health = 0.f, bool poisoned = false) :health(health), poisoned(poisoned){}

  std::string what() const; // human readable rep
  static const char* Name(); // name
};

// The logic of a component is implemented
// in a system. e.g., the HealthSystem might
// be responsible for decreasing a character's
// health if they are poisoned.

class HealthSystem : public ISystem {
public:
  bool implements(int componentIndex) override {
    return Health::Index()==componentIndex;
  }

  void setup(Entity& e) override {
    e.get<Health>().health = 100;
  }

  void update(EntitySystem& es, double dt) override {
    for (Health& h : es.components<Health>()){
      if (h.poisoned){
        h.health -= 0.1f * (float)dt;
        if (h.health <= 0){
          // Create KILL EVENT
        }
      }
    }
  }
};

Besides this I’ve also been thinking about having Script components. These will be a special type of component that uses traditional polymorphism and lambdas to offer a concise and easy way to implement special behaviours. For example, I could attach a custom c++ poison script to a entity like this:

Script* newPoisonerScript(Entity& e){
  // variables to be captured by the lambdas
  float* duration = new float(0.f);
  float* timer = new float(0.f);

  auto poisoner = new Script("poisoner");

  poisoner->destroy = [duration, timer](Entity& e){
    Health& health = e.get<Health>();
    if (health) health.poisoned = false;
    delete duration;
    delete timer;
  };

  poisoner->start = [](Entity&e){
    Health& health = e.get<Health>();
    if (health) health.poisoned = true;
  };

  poisoner->update = [timer, duration](Entity& e, double dt){
    *duration += (float) dt;
    Health& health = e.get<Health>();
    if (health){
      if (health.poisoned){
        *timer -= (float) dt;
        if (*timer < 0){
          health.health -= 1;
          *timer = 1.0f;
        }
      }
    }
  };

  poisoner->finished = [duration](Entity& e){return *duration>1.5f;};
  return poisoner;
}

Anyway, once I’ve finalised the new system it’s going to take a couple of days to incorporate it into Moonman, but I definitely think it’s worth the deviation. Basically it means that I’ll turn macro’ed code that looks like this (see devlog for explanation of how it works):

ATTRIB(e, x) += 0.1f;
bool isOnGround = ATTRIB_OR(e, is_on_ground, false);
bool hasPhysics = HAS_ATTRIB(e, is_physics);

Into nicely autocompleting code that looks like this:

e.get<Transform>().x += 0.1f; 
// or with shorthand
e.transform().x += 0.1f;
// and
bool isOnGround = e.get<Physics>().isOnGround;
bool hasPhysics = e.has<Physics>();
(3 Comments on An entity system)