Category Archives: Programming

Knight Online, Repent Online, and the N3Base

Just wanted to share an interesting tidbit of information I stumbled upon. MGame, a Korean MMO developer, worked on two major projects around 2002/2004. One was Knight Online and the other was Repent Online. You can still play Knight Online today and it is possible to play Repent Online but you need a Korean social security number. Anyways, I played Knight Online (KO) a TON when I was 12 or so years old. Today I commonly work on Knight Online private server development in my free time. So while poking through the content files for both KO and Repent Online (RO) I noticed a common trend in the binary formatted content data. A while back I write a tool to help visualize KO game objects using OpenGL, and lo and behold (with minor tweaks) I could get the RO objects to render using my KO tool! Pretty cool!

This might not be too terribly useful but then again it might be neat to add some of the weapons and objects to the KO content as a throwback to Repent Online (a.k.a Legend of Ares).

New Project – “June”

So for whatever reason I recently went on a Youtube binge watching a ton of videos on game design and artistic design. Based on the videos I saw I feel motivated to mix things up a little and try something more creative. There are a ton of point and click adventure games out there but what I have planned is a bit more personal. I am prototyping the idea of turning my own day-to-day experiences into a point and click.

For this game I am also adding music which a lot of my previous projects have been missing, and all the images for the game were taken with my android phone. Music plays a much bigger role in this game because there aren’t really any “game mechanics”. The game mechanic is the experience and how well it draws the play in. Everything I have now has been thrown together quickly just to get a feel for the gameplay, and I’d have to say I like what the prototype has had to offer so far. The images are a bit blurry but linking image to image through an option list of activities is a lot of fun and has opened more of my creative side than any other project so far.

So I will keep with this for a while and see where it takes me!

Duktape to automate Ogre3D scenes

I have been playing around with the Ogre3D graphics engine. Ogre3D has been around for a while but only recently, after getting burnt out on OpenGL, have I started to learn more about how Ogre works. After making my way through their set of beginner tutorials (here) I was ready to start making my own scenes and start building a little prototype. I wanted an easy way to editor my scene without having to recompile everything every time I slightly move something within the scene. Typically this is where most people go out and learn 3Ds Max or Blender or even any of the custom Ogre scene editors. But after spending a day working through the Ogre tutorials I felt like I had experienced enough tutorials for one day.

So, if you are like me, you would like to have another option for manipulating a scene quickly without having to recompile. This is an excellent excuse to embed a scripting language within your C/C++ program! Here is an example of building Ogre scenes using a JSON file and Duktape. Duktape can do more than just parse JSON files, so it is a great addition to your codebase – especially if things like Google’s V8 Engine is overkill for what you are looking to do.

Let’s start by viewing a little test scene I’ve been playing around with.

So this is a basic scene I built using the sample meshes which come with the Ogre SDK. Below is the JSON file which builds this particular scene.


"SceneNodes": [
		"Name": "FloorNode",
		"Position": [0.0, -5.0, 0.0]
		"Name": "TestNode",
		"Position": [0.0, 25.0, 0.0]

"Entities": [
		"Name": "FloorEntity",
		"Mesh": "floor00.mesh",
		"SceneNode": "FloorNode",
		"CastShadow": false
		"Name": "TestEntity",
		"Mesh": "ogrehead.mesh",
		"SceneNode": "TestNode",
		"CastShadow": true

"Lights": [
		"Name": "TestLight",
		"Type": "Point",
		"Position": [250.0, 100.0, 250.0]


Ogre doesn’t know how to parse this file at all. All the conventions here I define within my code using the Duktape API. Once Duktape parses the JSON file I retrieve the relevant information I need to build my scene using Ogre. First we read in the JSON file as a string so we can later hand it over to Duktape, which will then use it to create a Javascript object.

int strLen = 0;
char* fileStr = NULL;

FILE* file = fopen("../../data/scene/test.json", "r");
if(file == NULL) exit(-1);

char c;
do {
	fread(&c, sizeof(char), 0x01, file);
	fileStr = (char*) realloc(fileStr, ++strLen*sizeof(char));
	fileStr[strLen-1] = c;
} while(!feof(file));

fileStr = (char*) realloc(fileStr, ++strLen*sizeof(char));
fileStr[--strLen] = '';


So now we have a string pointer, char* fileStr; , which points to the contents of our JSON file. Here you could do any “pre-processing” work that may be needed. Next we need to send this string over to Duktape. It is very simple to get Duktape up and running.

duk_context* mContextJS;
mContextJS = duk_create_heap_default();


duk_push_string(mContextJS, fileStr);
duk_json_decode(mContextJS, -1);


Here we decode the JSON object and free our previously allocated string. From here you can literally do anything with the JSON object. Below is one example but there is really no limit to how complex these scenes could get!

duk_get_prop_string(mContextJS, -1, "SceneNodes");

size_t i;
for(i=0; i<duk_get_length(mContextJS, -1); i++) {
	duk_get_prop_index(mContextJS, -1, i);

	duk_get_prop_string(mContextJS, -1, "Name");
	const char* nodeName = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "Position");
	duk_get_prop_index(mContextJS, -1, 0);
	Ogre::Real x = (Ogre::Real) duk_to_number(mContextJS, -1);
	duk_get_prop_index(mContextJS, -1, 1);
	Ogre::Real y = (Ogre::Real) duk_to_number(mContextJS, -1);
	duk_get_prop_index(mContextJS, -1, 2);
	Ogre::Real z = (Ogre::Real) duk_to_number(mContextJS, -1);


	/* === */

	Ogre::SceneNode* node;
	node = mSceneMgr->getRootSceneNode()->createChildSceneNode(nodeName);

	node->setPosition(x, y, z);

	/* === */



/* === */

duk_get_prop_string(mContextJS, -1, "Entities");

for(i=0; i<duk_get_length(mContextJS, -1); i++) {
	duk_get_prop_index(mContextJS, -1, i);

	duk_get_prop_string(mContextJS, -1, "Name");
	const char* entName = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "Mesh");
	const char* meshFN = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "SceneNode");
	const char* nodeName = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "CastShadow");
	bool castShadow = duk_to_boolean(mContextJS, -1) & 0x01;

	/* === */

	Ogre::SceneNode* node = mSceneMgr->getSceneNode(nodeName);
	Ogre::Entity* entity  = mSceneMgr->createEntity(entName, meshFN);



	/* === */



/* === */

duk_get_prop_string(mContextJS, -1, "Lights");

for(i=0; i<duk_get_length(mContextJS, -1); i++) {
	duk_get_prop_index(mContextJS, -1, i);

	duk_get_prop_string(mContextJS, -1, "Name");
	const char* lightName = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "Type");
	const char* lightType = duk_to_string(mContextJS, -1);

	duk_get_prop_string(mContextJS, -1, "Position");
	duk_get_prop_index(mContextJS, -1, 0);
	Ogre::Real x = (Ogre::Real) duk_to_number(mContextJS, -1);
	duk_get_prop_index(mContextJS, -1, 1);
	Ogre::Real y = (Ogre::Real) duk_to_number(mContextJS, -1);
	duk_get_prop_index(mContextJS, -1, 2);
	Ogre::Real z = (Ogre::Real) duk_to_number(mContextJS, -1);


	/* === */

	Ogre::Light* light = mSceneMgr->createLight(lightName);

	if(!strcmp(lightType, "Spot"))
	if(!strcmp(lightType, "Point"))
	if(!strcmp(lightType, "Directional"))
	light->setDiffuseColour(1.0, 1.0, 1.0);
	light->setSpecularColour(1.0, 1.0, 1.0);
	light->setPosition(x, y, z);

	/* === */



The one line that probably deserves explaining here is duk_to_boolean(mContextJS, -1) & 0x01; , which I did simply to avoid const warnings VC++ was giving about converting from duk_bool_t to bool .

As an added bonus, if we put this code within a void createScene(void); function we can hotload the scene with a single button press (i.e. without having restarting the program). Just add the following to your bool OIS::KeyListener::keyPressed(const OIS::KeyEvent& ke); function’s switch statement.

case OIS::KC_R: {
} break;

Here I’m using the “R”-key to reload my scene.

I much prefer this method to learning a bloated program like 3Ds Max, Blender, or any of the other programs out there. These programs can’t avoid the bloat because they need to be able to perform everything a user needs (and then some). But if you only need the basics they come with way too much overhead to warrant their use.

Hopefully I’ll have more 3D stuff in the future! I’ve never made a 3D game before so this is new territory for me – quite excited!

Arx Libertatis

I have been digging around lately for feature-length games with readily available source code. I really enjoy looking back over great source code and trying understand the underlying structure. Most recently I learned about Arx Fatalis, which is now being developed further by passionate hobby developers under the project name Arx Libertatis. I never even knew this game existed!

Arx Fatalis was originally developed by Arkane Studios, the developers for the more recently popular game Dishonored. I have been making my way through this game in amazement. I am a huge fan of the King’s Field series of game and Arx Fatalis seems to capture a lot of the feelings of isolation that are synonymous with the King’s Field series. The fact that this entire project is open source and under the GNU Version 3 license is just icing on the cake. If you have time, follow this video tutorial and get a version of the source code up and running for yourself! At the very least, get the game off Steam or GOG and enjoy this wondrous experience!

Obj Mesh Importer

Today I am sharing a bit of code I use to read very basic vertex and texture coordinate information from an obj file. The .obj format is explained in detail here. It is pretty well supported across most 3D-modeling software and is currently my go-to format for 3D mesh information.

In order to keep the vertex information file format agnostic (in case you decide to add other file formats later), I designed an intermediate layer of abstraction between the .obj file and OpenGL.

typedef struct {
	GLfloat* pos;   // (x,y,z)
	GLfloat* tex;   // (u,v)
	GLfloat* norm;  // (x,y,z)
	GLsizeiptr num; // total num of verts
} VertInfo;

typedef struct {
	GLuint* pos;    // 3 pos inds per
	GLuint* tex;    // 3 tex inds per
	GLuint* norm;   // 3 norm inds per
	GLsizeiptr num; // num of triangles
} IndInfo;

This works well for my current needs but there are a few simplifications I have made about the obj. An obj file may contain an optional coordinate (x, y, z [,w]) but I am ignoring that it might exist. Another simplification is that the texture coordinates have two variables, not three. These are reasonable assumptions to make since they basically ignore optional arguments that I won’t use anyways. The bigger assumption is that all the face definitions are triangles. This isn’t the case, even with the files I’ll be using, but OpenGL is really fast with triangles to I’m converting the quadrilaterals to triangles. This current iteration only accepts quadrilaterals but triangle faces would be trivial to add.

Here is the actually importer.

void loadObjFile(VertInfo** verts, IndInfo** inds, const char* filename) {
	if(*verts) {
		(*verts)->pos = NULL;
		(*verts)->tex = NULL;
		(*verts)->norm = NULL;

		(*verts)->num = 0;
	} else *verts = (VertInfo*) calloc(0x01, sizeof(VertInfo));

	if(*inds) {
		(*inds)->pos = NULL;
		(*inds)->tex = NULL;
		(*inds)->norm = NULL;
		(*inds)->num = 0;
	} else *inds = (IndInfo*) calloc(0x01, sizeof(IndInfo));

	size_t n = 0;
	char** lines = NULL;

	if(filename==NULL) return;
	FILE* fp = fopen(filename, "r");

	do {
		char c;
		int colInd = 0;

		lines = (char**) realloc(lines, ++n*sizeof(char*));
		lines[n-1] = NULL;

		do {
			fread(&c, sizeof(char), 1, fp);

			// NOTE: strip newlines
			if(c!='n') {
				if(colInd>0) {
					// NOTE: strip extra spaces
					if(!(lines[n-1][colInd-1]==' ' && c==' ')) {
						lines[n-1] = (char*) realloc(lines[n-1], ++colInd*sizeof(char));
						lines[n-1][colInd-1] = c;
				} else {
					lines[n-1] = (char*) realloc(lines[n-1], ++colInd*sizeof(char));
					lines[n-1][colInd-1] = c;
		} while(c!='n');

		// NOTE: end with a null terminator
		lines[n-1] = (char*) realloc(lines[n-1], ++colInd*sizeof(char));
		lines[n-1][colInd-1] = '';

		if(lines[n-1][0]=='#') {
			// NOTE: ignore comments

			lines[n-1] = NULL;

			lines = (char**) realloc(lines, --n*sizeof(char*));
		} else if(lines[n-1][0]=='') {
			// NOTE: ignore blank lines

			lines[n-1] = NULL;

			lines = (char**) realloc(lines, --n*sizeof(char*));
	} while(!feof(fp));

	fp = NULL;

	size_t numPos = 0;
	size_t numTex = 0;

	int i;
	for(i=0; i<n; i++) {
		// NOTE: parse the file

		printf("%sn", lines[i]);

		if(lines[i][0]=='v' && lines[i][1]==' ') {
			// NOTE: parse the vertex and add it to the array


			numPos += 3;
			(*verts)->pos = (GLfloat*) realloc((*verts)->pos, numPos*sizeof(GLfloat));

			GLfloat x = 0, y = 0, z = 0;
			sscanf(lines[i], "v %f %f %f", &x, &y, &z);
			printf("[%f, %f, %f]n", x, y, z);

			(*verts)->pos[numPos-3] = x;
			(*verts)->pos[numPos-2] = y;
			(*verts)->pos[numPos-1] = z;

		} else if(lines[i][0]=='v' && lines[i][1]=='t' && lines[i][2]==' ') {
			// NOTE: parse the texture coordinates

			numTex += 2;
			(*verts)->tex = (GLfloat*) realloc((*verts)->tex, numTex*sizeof(GLfloat));

			GLfloat u = 0, v = 0;
			sscanf(lines[i], "vt %f %f", &u, &v);
			printf("[%f, %f]n", u, v);

			(*verts)->tex[numTex-2] = u;
			(*verts)->tex[numTex-1] = v;
		} else if(lines[i][0] == 'f' && lines[i][1] == ' ') {
			// NOTE: parse the face elements

			int c, num = 0;
			GLuint* indices = NULL;

			for(c=1; c<strlen(lines[i]); c++) {

				// TODO: will have to handle the case when normals are left out
				// or when texture indices are left out

				// TODO: currently I am assuming 4 indices per face which makes
				// two triangles (i.e. 6 elements)

				if(lines[i][c]==' ') {
					num += 3;
					indices = (GLuint*) realloc(indices, num*sizeof(GLuint));

					GLuint vi = 0, vti = 0, vni = 0;
					sscanf(&lines[i][c], " %d/%d/%d", &vi, &vti, &vni);
					printf("[%d, %d, %d]n", vi, vti, vni);

					indices[num-3] = vi;
					indices[num-2] = vti;
					indices[num-1] = vni;

			if(num==4*3) {

				// TODO: currently only setting the position index but I need
				// to set them all eventually

				(*inds)->num += 6;

				(*inds)->pos = (GLuint*) realloc((*inds)->pos, (*inds)->num*sizeof(GLuint));
				(*inds)->tex = (GLuint*) realloc((*inds)->tex, (*inds)->num*sizeof(GLuint));
				(*inds)->norm = (GLuint*) realloc((*inds)->norm, (*inds)->num*sizeof(GLuint));

				int pos0 = indices[0];
				int pos1 = indices[3];
				int pos2 = indices[6];
				int pos3 = indices[9];

				(*inds)->pos[(*inds)->num-6] = pos0-1;
				(*inds)->pos[(*inds)->num-5] = pos1-1;
				(*inds)->pos[(*inds)->num-4] = pos2-1;
				(*inds)->pos[(*inds)->num-3] = pos2-1;
				(*inds)->pos[(*inds)->num-2] = pos3-1;
				(*inds)->pos[(*inds)->num-1] = pos0-1;

			indices = NULL;


	for(i=0; i<n; i++) {
		lines[i] = NULL;

	lines = NULL;

I added printf() outputs for debugging purposes. This function will build the structs and set the pointers so that we can then work on this abstraction layer to build the information OpenGL needs to render the object.

To create the structs just place the following calls.

IndInfo* inds = NULL;
VertInfo* verts = NULL;

loadObjFile(&verts, &inds, "test.obj");

The neat thing about this current setup is that the index information can be passed directly to OpenGL as an element buffer.

// NOTE: allocate a GPU buffer for the element data
GLuint eleBuffer;
glGenBuffers(1, &eleBuffer);

// NOTE: bind to the element buffer so that we may send our data to the GPU
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eleBuffer);

// NOTE: send our element data to the GPU and set as STAIC
glBufferData(GL_ELEMENT_ARRAY_BUFFER, inds->num*sizeof(GLuint), inds->pos, GL_STATIC_DRAW);

On the other hand, the OpenGL vertex information is highly specific to the type of effects you plan to render with your objects. Here I’m just using the position and texture information but if you plan to add lighting or some other type of rendering effect you’ll have to customize the OpenGL vertex information to fit your needs.

GLfloat glVerts[5*verts->num];
memset(glVerts, 0x00, 5*verts->num*sizeof(GLfloat));

int tempInd = 0;
for(; tempInd<verts->num; tempInd++) {
	glVerts[5*tempInd+0] = verts->pos[3*tempInd+0];
	glVerts[5*tempInd+1] = verts->pos[3*tempInd+1];
	glVerts[5*tempInd+2] = verts->pos[3*tempInd+2];

	glVerts[5*tempInd+3] = verts->tex[2*tempInd+0];
	glVerts[5*tempInd+4] = verts->tex[2*tempInd+1];

// NOTE: allocate an array buffer on the GPU
GLuint verBuffer;
glGenBuffers(1, &verBuffer);

// NOTE: bind to the array buffer so that we may send our data to the GPU
glBindBuffer(GL_ARRAY_BUFFER, verBuffer);

// NOTE: send our vertex data to the GPU and set as STAIC
glBufferData(GL_ARRAY_BUFFER, 5*verts->num*sizeof(GLfloat), glVerts, GL_STATIC_DRAW);

And that is pretty much it! Now you can create complicated meshes using something like Anim8or or Blender and render them with your own OpenGL implementation.

Arthur’s Grove: Update

So lately I’ve been working a lot with C++ to beef up my skills for possible future employment. Part of this work has involved me going back over Arthur’s Grove (AG) and writing it in an object structure. I’ve also started using Git version control for similar reasons. So the results of the week are as follows:


I added a non-hostile bug entity to the world. It walks around randomly and is destroyed in one hit. They are mostly there for amusement and to add to the environment.

I added the ability to sail across the ocean while riding a whale!

I also added the ability to shoot tsunamis across the sea, for future sea combat.

I added a basic worm enemy which will turn up dust in the player’s face. The movement for the worm enemy is a simplistic straight line but more intelligent enemies will come soon.