Posts Tagged ‘game development’

As said in my last blog post, I’m working on an inventory system. Before all Battlelance characters where just a bunch of stats, from now on they’ll be stats and items! Ain’t that cool.

I’ve already got some work into a proof of concept of the inventory system I discussed earlier, and I have the basics working in game.

Each unit has a “Backpack” and a few equipment slots (to be determined). Some items have effects if they sit in your backpack, such as the health potion in the next example. Others give abilities and effects if they are equipped, such as the warhammer and full-plate armour in the said example.

Here are some screenshots on demonstrate my meaning:

Items in backpack

Items in backpack

Items equiped

Items equiped

This blog is mainly me thinking aloud on how items should work. Non of this is either set in stone, or the best way to go forwards. It’s just writing down some ideas on how to use ingame items in the context of Battlelance.

Items add a new layer to the game, they can be placed by a level designer at a critical point to just give you that health potion at just the right time. For Battlelance I hope to implement just that, but also more. The different characters already start with a certain equipment (atm just stats and abilities), some of those stats and abilities, like the possibility to strike with a sword or the armour rating of a fighter should be coming from the equipment he’s wearing. This means that items give these abilities and effects, but they can give them at certain times. A health potion can be drunk from the backpack, but a sword can only be used when equipped. This means an Item has a 4 lists:

  • Backpack effects
  • Backpack abilities
  • Equipped effects
  • Equipped abilities

Once a played picks up an item, the backpack effects will start to take effect, and the backpack abilities should be added to the list of player abilities. Once an item is equipped to the right slot (should be an property of the item), the equipped effects and abilities come into play. Equipping items should cost time, if it would cost an entire action point (you get one of them per turn). It means the player has to think very carefully about when switching weapons.

Chest with healing potion

Chest with healing potion

While testing I found some nasty bugs, most of these are addressed in this release. Please let me know if you find others, this is after all just an alpha version, if you can even call it that 🙂 And with help I can find and fix them.

  • Fixed: End turn bug, end turn didn’t register with all the clients
  • Fixed: Selection/action when somebody was standing on a trap
  • Fixed: Update vision when opening a door
  • Change: Movement/Actions have different labels
  • Fixed: Disable device label didn’t vanish after end turn
  • Fixed: Can’t run into a trap if somebody is already standing on it

In this blog I don’t want to just ‘praise’ my games, but I would like to give some technical insights in how they technically work. Mind you, the solutions that I’m using are not in any way the perfect solution to certain problems. They work for my situation and if you’re looking to copying it, that’s fine but a different context might require a different solution.

Another warning, I’m neither a great writer nor is my first language English. So I might become a bit incoherent as I jump from one subject to another.

Today I want to talk about save games. There are different ways to implement saving/loading in your game. One way to do it is to save all the current agents (characters and other ingame objects), but this means you’ll have to save all the effects and the current state of them as well. Like an invisibility spell that wears off in one more turn.

Battlelance saves its games by first of all saving the initial setup, which is just an object with a few arrays to record per playable character the player ID, player name, class, team number and some game master attributes like spawns, traps and abilities. With this information and the map the game can be set to its start position.

Once the players start the game all kind of data is being transferred over the network, to make sure this all happens in the right order and no threads access the same resources at once, each event that the game receives (movement, damage, summons, end turn, etc. etc.) is being push into a queue and afterwards processed. I’ll go more into this in another blog about the multiplayer aspect of the game. Sufficient to say is that these events constitute the consequences off all the actions that have taken place. So if somebody attacks, only the damage (if any) that’s done is enough to reconstruct the events that have happened.

Once the event is processed it’s stored in a savegame queue and once the game is saved this entire queue with the initial setup, and by replaying each event in turn the game is progressed to the same state as before.

Here is a snipplet of code of how the Save game object is written to a file and how it’s retrieved.

public static void SaveGame(GameContainer container, ConcurrentLinkedQueue<Object> saveGame)
{
  try
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    SaveGame game = new SaveGame(saveGame, container.getInitialState(), container.getMap2(), container.getGameName());
    oos.writeObject(game);
    oos.flush();
    byte[] binary = baos.toByteArray();
    String text = Base64.encodeBase64String(binary);
    PrintWriter out = new PrintWriter("save/" + container.getGameName() + ".btl");
    out.println(text);
    out.flush();
    out.close();
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
}

public static SaveGame LoadGame(String file)
{
  try
  {
    String text = readFile(file);
    byte[] binary = Base64.decodeBase64(text);
    ByteArrayInputStream baos = new ByteArrayInputStream(binary);
    ObjectInputStream oos = new ObjectInputStream(baos);
    return (SaveGame)oos.readObject();
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
  return null;
 }