I moved to a new URL! Check it out!

posts tagged with: otter

Dev Log: Event Queues Everywhere

Dev Log: Event Queues Everywhere
I've been working on a little prototype involving turn based combat. I'm not quite 100% ready to dive back into Stratoforce yet, and I had this idea gnawing at me and I just have to get it out of my system. What exactly is the idea? Well I can't say what it is yet, but if it works out then I'll talk more about it!

Since it is based around turn based combat I had to figure out how exactly that works. I'm so used to programming things that happen all in real time that suddenly going into a turn based game makes absolutely no sense to my brain. At first I had these huge state machines that were incredibly clunky, then I transformed it all into events that can be placed into a magical event queue.

Here's a simple class that can be dropped into Otter that is an event queue manager. It was whipped up very quickly so there might be some slight issues to debug. Check it out:
/// <summary>
/// A Component to manage and process queue of events
/// </summary>
class EventQueue : Component {

public List<EventQueueEvent> Events = new List<EventQueueEvent>();
public EventQueueEvent CurrentEvent { get; private set; }

bool isFreshEvent = true;

public EventQueue() {

}

public bool HasEvents {
get {
return Events.Count > 0;
}
}

public void Add(params EventQueueEvent[] evt) {
Events.AddRange(evt);
}

public void Push(params EventQueueEvent[] evt) {
Events.InsertRange(0, evt);
}


public override void Update() {
base.Update();

if (CurrentEvent == null) {
NextEvent();
}

while (CurrentEvent != null) {
if (isFreshEvent) {
isFreshEvent = false;
CurrentEvent.EventQueue = this;
CurrentEvent.Start();
CurrentEvent.Enter();
}

CurrentEvent.Update();
CurrentEvent.Timer++;

if (CurrentEvent.IsFinished) {
isFreshEvent = true;
CurrentEvent.Exit();
CurrentEvent.EventQueue = null;
Events.Remove(CurrentEvent);
NextEvent();
}
else {
break;
}
}

}

void NextEvent() {
if (Events.Count > 0) {
CurrentEvent = Events[0];
}
else {
CurrentEvent = null;
}
}
}

class EventQueueEvent {

public EventQueue EventQueue;
public int Timer = 0;
public bool IsFinished { get; private set; }

public void Start() {
IsFinished = false;
Timer = 0;
}

public virtual void Enter() {

}

public virtual void Update() {

}

public virtual void Exit() {

}

public void Finish() {
IsFinished = true;
}
}

This is sort of similar to just a very simple behavior tree (see Kodo for more advanced stuff!) Basically what happens is there's a list of events that all need to be run. The current event is run during the Update, and if it's finished then it's removed and now the next one starts up. You can both Add and Push events into the Queue. Push will insert an event at index zero so it will be the next thing to run. To make events just make classes that extend EventQueueEvent!

So I have events like "Damage" "ActorDefeated" "ChooseTarget" "TakeActions" and more. It becomes very easy to manage when things are broken up into separate classes like this! This is actually also giving me ideas on how to run cutscenes in more real time action type games as well. Maybe it will be of some use to you!

Dev Log: Otter Updates

Dev Log: Otter Updates
Over the past week or so I've been doing some various changes to Otter as I'm still trying to figure out the best way to add Entities to Scenes, and Components to Entities. Currently in the dev branch an Entity's Added function is not called until the Entity is actually added to the scene at the beginning of the next update, and now for Components their Added function is not called until it is actually added to the Entity which can occur at the start of each update.

For now I just did some minor updates and changes

* Changed how Entity.IsInScene works. Now IsInScene will return true if the Entity is in a scene, or queued up to be added to a scene.

* Added SetColor to the Color class. This is useful for changing all of the values on a color especially when using another color as the source values. Mostly used in cases where you don't want to Copy and create a new Color instance.

* Finally figured out how to get colliders to have separate constructors when using Enums as tags. Now you should be able to specify Enums as tags in the constructors of all colliders.

Dev Log: Jam Game Stuff

Dev Log: Jam Game Stuff
I've been doing pretty bad on blog posts this month so far, but I've been getting a lot of cool stuff done lately. I've been mostly focusing on my game jam game from a few weeks ago. I want to get that into a good playable state and do some testing at a local indie gathering and hopefully push it out to the public after that. This is another game that I'm making using my 2d .net framework Otter.

During the game jam I started to use the idea of components a lot more. The entity component system is the new hotness in video game programming as it seems many developers are starting to favor it over the old school hierarchy tree of classes. Here's a pretty good write up explaining how it works.

Image


So far all of my games depend very heavily on the whole class hierarchy tree. Like I would have a base Entity, and then maybe a game specific Actor which extends Entity. Then I would have a MovingObject which extends Actor, and then a PlatformerObject which extends MovingObject. Finally the player would be a class (like the momma from Offspring Fling) that extends PlatformerObject. It seemed like a good idea at the time!

Now with this jam game I'm working on I'm trying to use components as much as possible. It may be a little overkill, but I'm using this as a learning opportunity.

Image

For example here's what the Heart component looks like. I use the Heart for everything that can be involved in combat in some way, like anything that can take damage and all that stuff.

There's also something as simple as the RenderAllColliders component, which is handy for just slapping into an Entity if I want to see all of it's colliders during runtime. It will only render colliders on its parent Entity if the game is running in debug mode which is pretty neat.

So what does an Entity look like with all this component stuff? Here's a quick snippet from my main player class:
AddComponent(new CameraTarget());

// Add the movement and pass the axis from the controller.
var movement = new MovementTopdown(7, 0.3f);
movement.AxisMovement = c.Movement;

// Add the weapon, and pass it the shoot button from the controller.
var weapon = AddComponent(new AngelWeapon());
weapon.Button = c.Shoot;

var special = AddComponent(new Components.SpecialAttacks.Shotgun());
special.Button = c.Special;

AddComponent(movement);
AddComponent(new ClampInsideScene());
AddComponent(new SpriteEffects());
AddComponent(new RenderAllColliders());
AddComponent(new PushAway(2, Tag.Angel, Tag.Orb));

Later if I need to I can use GetComponent to retrieve any of those components if I need to change anything on them.

So far I'm really liking this approach, and it seems like it's the way things are heading in the video game programming world as far as I can see. I'm a little concerned with the performance of using a lot of components with GetComponent() running all the time, but it's probably not going to have that much of an effect.

Dev Log: Otter Updates

Dev Log: Otter Updates
Some crazy updates happening in the dev branch of Otter recently! Here's the scoop on what's been going on:

* Changed how Entities are Added to the Scenes. The Entity's Added() method now fires when the Entity is actually added to the Scene at the end of the current frame. The Added method also fires after all Entities in the adding queue have been added.

This means that if you're adding a player object, and then an enemy object afterwards, and the player object needs to reference the enemy object in its Added() method it should be possible to do so.

* In a similar fashion the Components have been changed in regards of when their Added() method is called. Components in the add queue are added at the beginning of Added, UpdateFirst, Update, and UpdateLast, and their Added method will fire when they are actually added to the Entity from the queue.

* GetComponent can now return Components that are still in the adding queue if none are found on the Entity itself.

* GetComponents() returns a list of Components of a certain type.

* Axis now has access to Up Down Left Right buttons. Very handy for having to check for button presses on an Axis and not having to create 4 separate buttons to do so.

* Repeat has been changed to two bools RepeatX and RepeatY.

* Util.Log() now behaves like a format string call (similar to Console.WriteLine())

* BitmapFont support is coming along and now supports data for three different bitmap font generators, as well as support for standard monospaced fonts.

* RichText characters can now be accessed and manipulated individually. This means you can do stuff like animate properties of characters yourself instead of relying on the mark up in strings.

* Other minor clean up and fixes that should make stuff better overall.

In other Otter updates be sure to follow the journey of Otter Pup 681!

Super Sky Sisters Timelapse

Super Sky Sisters Timelapse


Make sure to watch it in full 1080p at 60 frames per second, yeah!

The game isn't out yet, but you can watch me make it at hyper speed over the course of 48 hours. The game ended up getting a bunch of awards at the game jam, including second place overall which is pretty cool!

Dev Log: Game Jammin

Dev Log: Game Jammin
Whoops I've totally neglected my blog for the past week or so. I spent last week working on some minor Otter things, as well as getting ready for a local game jam. Then I jammed for 48 hours last weekend!

Image


Image


Here's some shots of what I ended up making:

Image


Image


Image


Image


I also recorded a timelapse, and that'll be coming pretty soon!