Mega's RPG4D Devlog - Part 1

Posted by Astryl on May 3, 2012, 9:29 a.m.

Well, I seem to recall promising a devlog of sorts. So here we go. I know it's only two and a half days into the comp, but I already have a lot going on.

Surprisingly, though: No artwork. Odd, for me.

Anyway: Days progress in pictures

This one is of fifty animated sprites place randomly into the room, with collisions being processed (And colliding objects removing themselves from the room).

Take the time to zoom in and check the CPU imprint on the process (Selected in Task Manager on the right). Occasionally jumps up to 1%, usually when I drag other windows in front of it (Handling the overdraw, and that's SFML's job :P)

And this simple looking little screenshot is actually something quite nifty: A tile-blitter. That loads an image that contains a grid of tiles, and allows you to draw individual tiles to the screen very quickly.

At the moment I'm working on creating a level loader, so I can load levels I've created in Tilestudio (Including Map Codes, Bounds information and the three layers).

The tileset in the window there is a quick one I did just now that uses the original NES NTSC colormap (AKA: Palette).

Engine information

The 'engine' is Object Orientated, and works with a heirarchy somewhat like this:

Object---> Exception	Assets (Separate class)
  |------\
Engine   |-> Room
         |-> GameObject
         \-> Sprite

Object is the root of the whole heirarchy, with Assets standing on it's own. The Object class has a static long variable that is used to assign an ID to each instance of it and and subclasses. This becomes useful during debugging, and when attempting to create a system that can reference objects by ID (GameObject instances can be removed from a room by ID).

In addition to that, each Object has a name field (Which defaults to Object), that is set in each inherited class; these two fields are used by the Exception class, which prints information that looks like this:

Exception thrown by instance of 'Object' (ID: 22)
Message: (Message provided by calling object. Optional)

And it appends that to the file Exceptions.log.

Next up is the Assets class, which would be a static class in other languages. It's primary goal is to maintain several lists of resources and nametables.

The resources involved are primarily SFML related (sf::Image, sf::Audio*, etc).

It's static nature requires the methods Assets::Initialize() and Assets::Cleanup() to be called manually, but in the long run this makes things so much easier.

And it saves memory. Imagine if I had to load a 5kb PNG for each instance of a tile on the screen? Now turn that into a level's worth of tiles.

Something I'm going to implement in a couple of days for the Asset manager is a Packed File Format (Like the good ol' Quake PAK files). This isn't so much to 'protect' my resources, as to make things a bit neater in my working directory.

I'm going to use a Chunk based format, working something like this:

Quote:

MK2 FILE FORMAT

The first three bytes of the header provide the MK2 identifier (For an early-out check). From then on, the chunks are read (Linearly).

The chunk layout:

BYTE 1 - Identifier (Used internally by the loader to quickly identify files)

BYTE 2+2 (16-bit value) - Filename length

BYTE 4+N - Filename + Path

BYTE N+8 - File length (64-bit unsigned integer)

BYTE N+N - Data

This is based in concept on WAD files (From Doom), with a rather slow search time. But for the most part, the assets will be loaded on game start; if I really need to load data at some other time-crucial phase, I'll use a pregenerated index (Which can be created after reading the MK2 file once).

This actually marks the fourth packed file format I've designed :3 (CHB, MPK, MK1)

Anyway…

Sound engine

I'm going to be needing one of these later on. Luckily, SFML uses OpenAL, so for WAV sound effects I'll be fine. But music. I'm going to have to rewrite my NSFStream library from scratch again (Forgot to back it up).

The game itself

Ideas have been battling in my mind for the top-spot, but I came up with one that I particularly like. I'm not going to say much until I have some (Nice) screenshots, but it's a platformer. A platformer, with enough RPG crammed in it to count (Actually, quite a lot of what defines an RPG (According to a few surveys I took amongst my friends) has found it's way into the idea. Except for the usual Stat system (I'm using something a little different)).

Art style is going to be decided when I start testing the waters later on today. Precise retro style? Mega style? <insert style here> style? :P

An interesting statistic about the code so far

I was curious, after I committed the final framework a few hours ago, as to the number of lines of code I had written.

So I copy-pasted each piece of code into a blank NP++ window, and checked the word count. 1301 lines (not counting whitespaces), and a mere 1200~ words (And that's counting operators). I came to the realization then that my average blog is way longer than that.

Oh, about 30% of that happens to be commentary (I'm practicing good programming habits more often than not these days :3)

So, I'm going to test a few final things before getting started on the game itself. Any extensions to the basic framework can be made later (The way I made it means it's extensible without causing dependancy breakages. Yay OOP).

This is going to involve testing the collision detection system in a simple platformer style game (Using temporary art, of course).

And that reminds me, time to finish writing my Level Manager…

Note

I tested the game as it stands on Windows 7. Working perfectly. (I'm going to be tracking compatibility, with both Windows 7 and Wine, because I feel like it :3)

Comments

Polystyrene Man 12 years, 6 months ago

Damn, sounds like you should just give up.

Astryl 12 years, 6 months ago

Why? It's only three days in, and I've got an efficient system that can do more than GM can already. :P

And I still have around 90 days left :3

svf 12 years, 6 months ago

It's good to see you convert to the dark side. :)

SFML and C++ are lovely.

death 12 years, 6 months ago

Quote:
Damn, sounds like you should just give up.
lmao wut?

Anyway this looks good, i wouldn't worry about time, we got plenty of it to go around. so much that i'll probably spent much less time on my entry than i should =3

Rob 12 years, 6 months ago

Isn't there a sf::Music class?

Astryl 12 years, 6 months ago

Quote:
Isn't there a sf::Music class?
I don't want to use OGG. I want to use NSF/VGM/SPC. Or XM/IT/MOD/S3M. Therefore: Roll my own module player (Again).

Quote:
It's good to see you convert to the dark side. :)

SFML and C++ are lovely.
What do you mean 'convert to the dark side'? I've been programming in C++ for nearly a decade now, starting with DOS games (VGA, register hacking, etc. Now that is the dark side).

Quote:
Seems like you're off to a good start as well. I like the error handling especially :)
You won't believe how much it's been helping. I've added a timestamp (DD-MM-YYYY-HH-MM-SS) option for it now, just in case I want it.

Quote:
Anyway this looks good, i wouldn't worry about time, we got plenty of it to go around. so much that i'll probably spent much less time on my entry than i should =3

Three months is the longest time I've ever had to work on a comp. Also, I'm working back in my home territory: the platformer. So yeah, I'm not too worried about the time.

Yesterday I finally completed the level loader (Bugless, with very fast rectangle blitting). Collision detection confirmed to be working properly (Even the line detection algorithm which I pulled from memory, based on an old line drawing algorithm I used back in the bad ol' days).

Also figured out a nifty scaling trick when using SFML and OpenGL together. My OpenGL initialization code looks something like this:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,640,480); // Matches the SFML Window size
glOrtho(0,320,240,0, -100,100); // Exactly half the size

That piece of wrong looking code actually scales the view perfectly, with no blurring, tearing or aliasing. Also, whoever smoked up glOrtho's argument order deserves to be shot.