My blog has been somewhat neglected for the past few days. I suppose one of the reasons is my work on a really big school project.
In place of a final exam, the Language Arts course at my school offers something called a Language Arts portfolio, consisting of three projects. The creative portion of the portfolio is quite free-form: you were to pick a novel and do pretty much anything you wanted on it.
For this project I chose the novel Siddhartha by Herman Hesse:
I chose to create a Java game for this assignment. The game was a sort of role-playing platformer, and in my own words, ‘a combination of Runescape and Maple Story’.
This project took up most of my time for the last week or so. Planning began about four weeks ago, and I began coding and writing the dialogs about three weeks before. I nevertheless scrambled to complete all of the graphics and put it all together on the weekend.
Unlike most Language Arts assignments, I actually quite enjoyed making this game, and I’m proud of my work. I’m going to release the game along with its source code:
On windows, the game can be run by double-clicking game.bat. Java 1.5 or later is required to run this game.
Here’s what the game looks like:
I was given an opportunity to ‘present’ my project to the class today. The school laptop had a problem with some java dll’s, but a classmate had a working laptop so the presentation went fairly well. I discovered one or two bugs in the presentation that I never noticed when testing the game.
I also tried to get my girlfriend to playtest the game, which kind of failed miserably.
Technical details of the game
Before starting coding for the game, I searched for existing, similar, open source, java alternatives. Finding none, I was forced to make my own.
If anyone else ever wants to make a similar game, my work here might be useful. If I myself were to make something like this again in the future, I wouldn’t have to write the game from scratch again. Of course by then I would have forgotten how the code works; it would benefit me to write about it here to refer back to in the future.
The following section is probably too technical and would be only useful when trying to understand my code. Anyways.
The game is written in about 1300 lines of Java code (although about 60% of it was configuration so only about 600 lines of it was game logic). The images are mostly drawn in MS-Paint, since I’m not very skilled at using Photoshop. I only used Photoshop to change all of the white pixels to transparent pixels (impossible in MS-Paint).
I chose JGame for the game engine. This is a decent game engine, although I think it’s a bit buggy and very unprofessional (the sample games look like they’re from the 1980’s). It’s backed by OpenGL, not because the game uses any OpenGL features, but because the non-OpenGL version of the library has a certain bug in one of its functions that I wasn’t sure how to circumvent.
This particular bug was about the
setBGImage() function, which seemed to not work on the JRE version of JGame. I asked a question on Stack Overflow, but didn’t really get an answer.
The most complicated portions of the game was handling transitions between maps, and handling dialogs. The handling of maps was done completely in Java code, while the dialogs were handled in an ad-hoc scripting language I created for this purpose.
To transition between maps, I had the idea of a portal, which would activate at certain points and replace the existing map (and all its objects) with a new map, and adjust the game state accordingly. In essence, a portal has a one-way connection to another portal. To make such a connection, a portal keeps a reference to its connecting portal, so that it can change the game accordingly when needed.
The portal has an off state, an on state (when the player is touching the portal), and an active state (when the transition between maps is taking place). If a portal has a connecting portal, it is ‘activated’ when the up key is pressed, otherwise it cannot be activated.
A map in the game takes up exactly one screen, has one background image, can have multiple portals, and at most one NPC (non player character). There are 28 maps in this game (some sharing the same background).
A NPC is a character in the game that’s not the player. A NPC has a still (non-animated) sprite, and holds a constant position in exactly one map. The same NPC appearing in different maps may have the same sprite, but are otherwise completely different. A NPC has a name, which is shown above the NPC’s head on mouse over; when clicked the player enters a conversation. A NPC has exactly one conversation attached to it.
The conversation data in the game is defined in a file:
speech.dat. The first part of the file contains a sort of scripting language describing how the conversations flow, while the second part is a dump of all the actual String data to put for the dialogs. Each line in the String data section is assigned a number starting from 0, to be referred to in the rest of the game.
A conversation always starts with the player. From there, whoever is speaking can continue to speak (the
same command), or the other person can start speaking (the
chgspk command). Either that, or we can present the player with a list of choices (the
choose command). When the conversation ends, we direct the next line to
END_DIALOG, which is defined on line 0.
The flow of the conversation is contained in arrays or maps of the
SpeechCode object. This object contains the line number of the source string, the line number of the target string, and the opcode. When drawing the message, we look up the String from a table using the source key, and when the player clicks the continue part, we look up the new
SpeechCode using the target key, and adjust the speaker according to the opcode.
Hopefully this is enough high level documentation for the project. I don’t think I’ll be working on this game again.