Stuff blog

Posted by Astryl on July 26, 2012, 3:22 a.m.

Well, I promised myself and all of you I'd write another (kind of) large blog at some point, carefully edited and segmented into selectable portions.

Why bother promising myself to write something so long for the internet? Practice. If I don't, I'll slowly slip back and lose my ability to write long texts like these in (relatively) short spaces of time.

I'll cover a few topics, hidden between spoiler tags.

Mega the Mecha Otaku

I've mentioned it before. It's blatantly obvious after glancing at my DeviantArt profile and somehow ignoring the dragons. I love mecha.

Heck, I love sci-fi, but giant super-robots take the prime spot in my list of favorite non-existant want-for-christmas gifts.

That probably started with it's roots in the old Megaman games, and my… fascination with them; they introduced me to the whole Androids vs ApplesHumans plot line.

The first mecha anime I watched would be Transformers Armada. Being in South Africa and only having the terrestrial broadcasts at the time (Only four channels, all aimed at different cultural groups), that was incredibly 'lucky'. Other possible viewing at the time included Courage the Cowardly Dog, Dragonball Z (Got sick of that really fast), and Yu-Gi-Oh.

Oh, and then that was immediately followed by Transformers Energon and later on Transformers Cybertron (The whole Unicron trilogy). Then it all went to shit when the Transformers Animated came about.

But by then I'd already been introduced into the world of Gundam and it's various spinoffs.

Anyways… I was feeling kinda tired last week, having been both in crunch mode for the last of the competition, and having watched all 50 episodes of Gundam SEED Destiny (In Japanese to boot, with subs), while training for my job, practice on my guitar and somehow keep up my day-to-day life, all while getting at least 5 hours of sleep.

Great show, with very solid animation (Though they reused a few sequences, but not too often). The plot was kinda predictable, but still managed to throw a few curveballs. Also, why the hell did the Minerva keep siding with Chairman Dulindal? And why is Kira suddenly trying to be X7/X8 X? And WHY DID THEY HAVE TO INCLUDE THREE 'RECAP' EPISODES???

Meh. Doesn't matter. Giant robots. Space colonies. Giant Positron Cannons of Doom[super]tm[/super].

Something I just thought of; if I was able to get them, my room would probably contain shelves full of the official collectables from Gundam.

Luckily for my budget, I can't afford it. ^^

Designing simple game engines for the rest of us

OK, I'm going to talk a bit about the framework/engine I created for the comp. Interesting point: I used and developed the same engine right from the beginning; that includes Arbiter.

In short, the engine I created handles 2D and 3D quite nicely. :P

I'm going to waffle a bit about the process I followed in designing a certain part of the engine. Specifically, handling the game loop and an arbitrary number of objects with different properties.

I used basic OOP principles for this, and while it takes a bit of time to set up initially, it becomes easily extensible later on.

The first thing I defined was a generic Object class (as mentioned in one of my dev blogs). This object contains some generic properties, such as a unique ID, a depth value, an isDead flag, and a few virtual function declarations: OnStep(), OnDraw().

From there, I was able to create my 'Object Manager'. This class stores a std::vector containing pointers to the Object type.

These are insert-sorted by depth (Lowest value first).

The 'pseudo' definition of the class is something like this:

class ObjectManager
{
   private:
	vector<Object*> list_obj; 
   private:
	Step()
	{
	    for(iter i = list_obj.begin(); i != list_obj.end(); i++)
	    {
                // Perform removals
 	        if((*i)->isDead)
		{
			// Remove head from list, delete pointer.
			// Iterator is increased and checked.
		}
	        // Perform step
		(*i)->OnStep();		

		// An internal loop checks for collisions
		for(... (same as first loop))
		{
		    if(Colliding(i,j))
		    {
			// Double dispatch
		  	(*i)->OnCollide(j);
			(*j)->OnCollide(i);
		    }
		}
	    }
	}

	Draw()
	{
	    for(...) // Reverse iterator loop, from end to begin.
	    {
		(*i)->Draw();
	    }
	}
};

Simple. Very simple. Not so cost effective, but in most situations it's fine. I only used this setup in Arbiter. In Exile, I used a lot of arrays/individual lists. You'll be able to see the spaghetti I coded there when I release the source code (Which will be commented).

On a musical note

After completely wasting the little musical creativity I had for chiptunes on the seven tracks I created for Exile, I spent the week playing on my guitar. And I got carried away. Yesterday I inadvertantly spent three hours, just playing around, playing some bars from music I remembered, composing bits, etc.

Interesting thing to note: I can read music in the classic notation, or in tablature format, but I tend to prefer learning by ear. I listen to music, pick out the backing melody or the main melody, then duplicate with varying degrees of complexity with the guitar.

I still don't play in front of people much, mostly because I don't know if they'd appreciate my music (I play a lot of music I make myself), nor do I like being in the 'spotlight'. But maybe one of these days.

The reason I don't play in front of friends/family/the public much is because of the constant 'Why don't you sing?' I get from them.

I don't sing. I can sing, I choose not to. Because I prefer letting my music sing for me.

Otherwise, today I recomposed two of my older chiptunes into slightly more 'correct' and guitar-friendly versions. Working on playing those at their proper tempo, then I'm going to write them out on a sheet and file 'em.

I might try recording some of my practice with my MP3 player, which has a surprisingly high quality microphone. I'll have to wait for a convenient time when no noisemakers are in the vicinity (READ: My entire family. That mic on the player picks up the Television from the room over quite clearly).

Gaming

As mentioned before, I bought Dragon Age Origins and Mass Effect 2. Originally, when I tried ME2, it locked up when I tried to start a new game. I thought at first (And correctly, in some ways) that it was my crappy CPU preventing it from working.

But I searched the Bioware support forums for it a bit later, and it turns out that it can be circumvented by turning movies off. Weird. Anyway, I started playing that today, and enjoying it greatly.

In that vein, I've been progressing rather well in DA:Origins. Feels like NWN2 with a smoother control system. My only gripe is that the DnD system seems to be non-existant, or otherwise hidden for some reason. Damn you Bioware.

I have yet to test the latest Minecraft pre-release, but I'll do so. From what I've experienced so far with the last one, the performance increase on my PC was tenfold. And I mean that literally. From around 30-35FPS on average (A framerate I'm quite OK with, by the way), down to 2FPS with the first few pre-releases, and then up to 300~400FPS in the latest one.

I'm also getting pretty excited about the upcoming Mod API. It's being designed by the Bukkit team, and they know what they're doing when it comes to creating a stable plugin API. I use Bukkit on my LAN server, and it's able to handle an insane number of plugins without a hitch.

I might actually start modding the game a bit when this comes out.

Terraria… has been fustrating to say the least. Damn Redigit for giving up. Because that's what he did. He ditched it when it wasn't making Minecraft sized wads of cash for him.

The most obvious problem with Terraria is the endgame balance. All the hardmode enemies/bosses are waaaay overpowered, the Corruption/Hallow spread is haphazard, and getting the higher level equipment is sheer dumb luck (Surviving long enough underground with the Molten Armour and a Night's Edge to get Cobalt Ore, not to mention smash a few altars, was very difficult).

Oh well. It's still fun (for a while). But it still plays like a WIP in some areas. Hope the mod community can do something great with it.

Personal update

In short (And in list format):

I'm…

- employed (Provisionally. Starting on the 1st of August)

- fed up (Take that in the literal, not idiomatic, sense)

- politically neutral (Parliament + Wind Turbine + ??? == Profit!)

- studying music theory (On a low scale)[/noPunsHere]

- studying math

- still a Brony. [/biteMe]

- still a Megaman fan

- still vaguely interested in dragons

- definitely not a furry

- very much a Mecha Otaku

- perpetually tired

There.

Interesting thing I was wondering about; I constantly have music running through my head, no matter what time of day (Even when I'm sleeping, from the dreams I remember). Is that common or not? I wonder.

That's all I can fit in, right now. I have a lot I want to get done, like explore the galaxy, slay more high dragons, build yet another first shelter, and create the Hallowed Armor.

This blog is 1626 words long.

Comments

Rob 12 years, 1 month ago

Quote:
// Remove head from list, delete pointer.

// Iterator is increased and checked.

That kinda sounds more like lists than vectors… or maybe it's just me. I hope you're not just calling erase(it) on your vector… What's with the incrementation after removal though? If you're at i, then you delete i, wouldn't the old i+1 be at i anyways? I'd imagine you'd want to do some kind of check to not increment, and instead check if you're out of bounds and break if that's the case.

Is the vectors over lists for performance reasons? ie you could just swap i and the last one, then pop_back(), making deletion pretty much O(1) like lists, but with in general more iteration efficiency due to being contiguous in memory and no need to follow the list nodes. Although you'd also hit a nice, big O(n) every time the vector has to make itself bigger, but I guess as a side effect you don't have as many new calls for new nodes. You're taking advantage of reserve(), right?

But, then again, you've been programming for much longer than I have, especially in non-GML things, and I'm also half asleep.

Astryl 12 years, 1 month ago

Ah, no. I'm not incrementing. Should've mentioned that.

I always check for out-of-bounds after erase().

I use std::vector mostly because creating a Linked List these days is a waste of time in most cases. I'd rather focus the time spent on the trickier data structures.

And no, I haven't been taking 'advantage' of reserve().

Don't need to swap any elements, by the way. Also, I need everything in order, because the objects are insert-sorted, and rendered from the end of the list to the beginning.

I did some profiling on Arbiter (The first game I was working on for the comp), and even with over 1000 objects, this managers list was only taking a marginal percentage of time, with the most time being stolen by the file IO sections.

Rob 12 years, 1 month ago

Quote:
Don't need to swap any elements, by the way. Also, I need everything in order, because the objects are insert-sorted, and rendered from the end of the list to the beginning.

You're… making no sense to me. Insert-sorted? Does the order really matter for the rendering?

So you want deletion anywhere in the array, while keeping the same order then why don't you use lists? They're O(1) for that, rather than O(n) like vectors are. The reason I mentioned reserve is, let's say you've got a vector and you insert an object. Okay, you'd just reserved some memory. Now we insert another. Now we have to reserve 2 slots and then copy the 2 over. Then do the same for 4, 8, 16, 32, 64, and so on. So if you are going to have, say, on average 512 objects in your vector, then why not reserve that many in the first place, rather than having OS calls for 1, 2, 4, 8, 16, 32, 64, 128, 256 and then 512, when you could just do it for 512 to begin with. That's O(logn) vs O(1) for the memory calls… You'd also not have to copy them over every single time, so you wouldn't have 1023 copies on top of the normal inserts.

Quote:
I use std::vector mostly because creating a Linked List these days is a waste of time in most cases. I'd rather focus the time spent on the trickier data structures.

If you're talking about development time, which I think you are, then since you're using iterators for your vectors, it takes just as long…

just replace std::vector<T> with std::list<T>, and then std::vector<T>::iterator with std::list<T>::iterator when you iterate through, etc. Or are you not going to use STL-lists because of any possible performance overhead, since they're doubly linked? (Although there is forward_list which is singly linked, if you're gonna be that picky about time/space issues.)

Once again, I don't see why you're using vectors when you want random-access removal and insertion (since you said you were inserting based on depth) while keeping the order… just seems kinda, well, weird that you would use something that's O(n) when a O(1) alternative exists that requires almost zero code changes, considering that you're already using STL iterators for your iteration, which have the same syntax for both containers…

If you're using this system for things like bullets and such, things that get created and then destroyed quite frequently, then it just makes no sense at all not to use lists.

Cesque 12 years, 1 month ago

That blog wasn't very long.

P.S. I've always hated mechas.

JuurianChi 12 years, 1 month ago

Darn it all.

I forgot about Gundam Seed Destiny.

must watch.