Posts Tagged ‘making of’
I didn’t record a timelapse video but I wrote this post talking about the development of my Ludum Dare game The Monastery. This will be a rather lengthy story of the development process so find a comfortable position and have a cup of tea or coffee. I want to get this out of my system now that the horrors are still vividly in my brain!
The Monastery is a type of game I’ve wanted to make for some time. I happen to like old school games and one game in particular that I have fond childhood memories of is SSI’s Pool of Radiance from 1988. For those too young to remember, Pool of Radiance (or just POR to friends) is a fantasy roleplaying game that features tactical combat and resource management and was one of the first games to fully implement the complex Advanced Dungeons & Dragons rule system. I really liked the game then and even today the battle system and the setting is very good. Naturally POR inspired me to revisit the genre and make The Monastery.
From the get go the project was not smooth sailing. On Friday, a day before the compo, I woke up with fever. I had already cleared my calendar for the weekend and had been very pumped up for the compo the entire week so I cursed my bad luck. I had to stay the day in bed and decided to check how I felt on Saturday. Luckily I woke up on Saturday and the fever was gone. Phew! I checked the theme, which was Beneath the Surface. Well, at least it’s not Breaking the Rules or whatever. I began thinking about ideas, mainly background stories, that would fit the theme while eating breakfast and taking a shower. Initial ideas that popped in my head felt too easy: being underground or underwater. I decided to have a walk around the neighborhood while pondering more on the theme. Then suddenly I had a vision of a large frozen pond. Even though it was sunny and warm outside I dreamed of travelling in a frozen landscape passing by a large building… perhaps a wizard academy? No, too Harry Potterish. Let’s make it a monastery!
I got back home and started googling and I found the book Haunted Monastery by Robert van Gulik. It was some kind of eastern horror detective story which gave me some ideas. I started to think how to make the monastery an interesting place for a group of adventurers. The monastery should be an eerie place, maybe abandoned but not empty. There was a mystery that needed to be solved. And I needed monsters to fight… Undead Monks? Then I started thinking what bad things had happened in the monastery and how the monks had been transformed into horrible undeads. And what about the abbot? Why is he missing? Where is he?
I spent about 3 hours working on the setting and background story. It was already afternoon when I turned on my computer and was ready to start drawing the graphics. I hadn’t drawn any real graphics for a loong time so it took me a while to get accustomed to the software and the process. I used Aseprite, a tool which I had never used before, but to my delight it turned out to be a great tool for pixel graphics. I started by drawing the font and then proceeded to make the player sprites. I needed sprites for the player charcters, the Fighter, Cleric, Wizard and… I pondered on the fourth guy for a minute — of course, there had to be a fourth guy — before settling on the Ninja, which I thought was pretty funny. Then I realized that I wanted to have character creation in the game like in all proper RPGs so I made four variations for each character and separate standing sprite and attack sprite. That’s 32 tiles in total, but luckily the variations are only different coloring. (Those who have played the game may have noticed that character creation was a victim at the cutting table and the color variations are not used by the game.)
After the characters were done, I did the enemy sprites for about 10 different enemies. When they were done it was already about 6pm and I had a dinner break. I realized I didn’t have a single line of code written yet so I decided that I had to have at least something on the screen before I called it a day. So I started coding a turn-based battle system. I like the Lua programming language a lot and it was a no-brainer to use it for the project. I had made SDL bindings for Lua a couple of a days ago as preparation work for the compo. Starting from scratch when coding can be painful and no surprises there, I had some problems with Lua error messages and stacktraces not being shown properly. I had no time to tackle the issue properly so I carried on. In hindsight this probably was a mistake because I was suffering from some quirks with the codebase the entire weekend.
At the end of day 1, I had the basics of moving on the battlefield and attacking done, but all the fancy things like spells and stats were missing. But hey I could now move on the battlefield and kill monsters! And the monster could do some simple pathfinding my way too.
I woke up on Sunday feeling very worried. I had only 19 hours left and I didn’t have anything ready that resembled the game I had in my head yet. The remaining todo list was daunting: character creation, exploration mode, spell system, healing, items, winning condition, monster statistics, character statistics, dungeon props, intro, main menu, level design, scripted encounters, sounds, music, playtesting, packaging the game for release… I decided to somehow try not to think about it and just start working. But I felt that the mother of all crunches was ahead of me.
I decided to work first on the most crucial parts: exploration mode and encounters. Without them the game would not feel at all like those good RPGs of old. I first considered whether I should make a random level generator but I thought that tuning it would be slower than just drawing a few levels by hand. So I grabbed a sheet of graph paper and started doodling and writing down names and purposes of rooms: entrance hall, storage, dining room, kitchen, lavatory… Upstairs: bedrooms, library… a ritual room! I tried to imagine myself walking in the monastery and thinking what I would need if I was living there. Then I started writing room descriptions and notes that the monks had left behind. I thought about the frozen pond and what has buried beneath its surface. The notes would be crucial in telling the story that I had in mind.
I quickly wrote a system for describing the levels and rooms in Lua. I made a simple encounter system, which was essentially as simple as an anonymous function called per room. The function would be called when the player entered the room. The function would print room description to the screen but could also execute any Lua code for triggering battles, placing items on the map and so on. Later the system would be extended to handle searching the rooms.
When I had the levels and rooms done the clock was already 3pm. Then real desperation struck me. Only 12 hours left and the game had huge gaping holes, important pieces missing everywhere. I really thought more than twice about quitting. I felt that it was impossible to do what I wanted in the remaining time. Besides I needed at least an hour, preferably three to playtest and polish the game at the end. That meant less than 10 hours to implement all the features. Quitting was tempting… But failure was not an option! I had already publicly announced that I would do this game. Damnit! I bit my lip and started furiously coding, banging the keyboard like a madman (my spouse was getting really worried at this point).
I only stopped a few times, a minute or two at a time to catch fresh air or eat a sandwitch quickly. During the coding marathon I consumed several litres of juice and soft drinks. Feature by feature I went through the list, working always on what seemed the highest priority thing. The order was roughly: winning the game, character stats, monster stats, key items, dungeon props (doors, stairs, etc.) and spells. 9 hours later, at midnight local time and four hours before the deadline I finally had a working game. There was still work to do but I was now feeling confident that I could do this. The main menu, sounds and music were created only about two hours before the deadline. I used the excellent BXFR for the sounds and cgMusic for generating the theme music.
Less than two hours left, it was time to start testing and polishing. I was very exhausted from coding and luckily I got some testing help from my brother Erik, who kindly stayed awake late and tirelessly played the game even though he had to go to his studies the next day. Thank you Erik, without your help The Monastery would be much less balanced.
I kept on tweaked the game till the last minute. The last feature, casting healing spells outside of combat, also requested by Erik, was added just about 15 minutes before the deadline! I was nervous about making changes so late and so tired. I quickly packaged the game and submitted it only a couple of minutes before the deadline. I did not have time to play through the game fully before submission. I had only tested the encounters in isolation and made balancing tweaks “blindly” by following Erik’s advice such as “take 1-2 skeletons from this encounter”, “reduce hp of spiders by a few points”, etc.
Now that the game was submitted I finally had time to play it myself. My head hurt from all the coding, I had been coding 19 hours nonstop. My neck was about to cramp and even the muscles in my face were hurting. But it did not stop me from enjoying the game — I think this was the first time playing my own game just after release and it did not feel exhausting. I played through the first floor and the game felt pretty good. Completed the second floor as well. Then the ultimate end fight — hard as a coffin nail just as it should be! I just barely survived it with two of my guys dead and the remaining two barely alive with 2 or 3 hp and no spells left. It had taken me about half an hour to play through the game. I was happy, I was relieved. I was dead tired! Satisfied I went to bed.
End of story. Or is it? After working so hard on The Monastery, I would really, really like to hear what you think about it. I certainly hope you enjoy it, especially if you like tactical RPGs but I can also take brutal honest feedback. I know there are things that could be improved — the UI could use some streamlining. In fact I’m considering making an updated version. Even if you do not like the game, then I hope it at least stands out from the crowd like a relic from a strange forgotten age!
Petri signing off.
We would like to thank you for playing and rating our game!
For those who did not and would like to, here you go!
During the last night, CAPSLOCK and I put together a little clip from our livestream archives…
We dedicate this minute of sillyness to Juliette, the 3-days-old daughter of Mewine and Fleacontent, who was with us in a way during this LD!
Have a good time you three!
Enjoy! (and sorry for the webcam quality, that’s all we had to work with…)
I’d been meaning to write this a lot earlier, but I’ve been way too busy to do it until today. Anyways, I made an online persistent world game in 48 hours. I wonder if it’s been done before during LD? We really need a tag system for games or something, it’d be interesting to be able to look up games with
specific elements. This post will be a bit of a combination of a making-of and a post-mortem; I’ll explain how this game came to be and comment on it.
Before Ludum Dare
This was my second Ludum Dare, so I had a decent idea of what to expect. Last time I used Unity, which had both its advantages and disadvantages. But since I’m the kind of person who wants to be able to customize everything and doesn’t want unnecessary things forced into his game, I prefer not to work with Unity. Fortunately, since February I’ve been doing an internship where I’m working on an XNA game, so I got pretty familiar with it. In making that game, I wrote a simple sprite engine which turned out to be very useful, so a week or so before LD23, I took the engine, removed some game-specific functions, added a tiny bit of documentation and released it as VBXSE. A short while ago I’d also been working on a simple netplay engine named GNI in my free time, so I decided to release that as well.
The original idea
After waking up at around 9-10 AM (competition started at 3 AM for me, but sleep is very important if you’re doing a 48-hour solo project), I checked the site to find out the theme was unexpectedly ‘Tiny World’, a theme I hadn’t even considered a possible winner in the poll. After thinking about it, I decided to make a roguelike-ish survival game similar to UnReal World where you and a couple of NPCs were stuck on a tiny island and had to get food and shelter to survive. That’s right, the original concept was nothing like what the game eventually became. I wrote down the basic game design in a text file, if you want details. So, I started working on the survival roguelike…
World and Graphics
Since roguelikes tend to be played in console windows, I decided to keep the area size small enough to fit in one. After some thinking, I decided square areas would make the most sense considering you also need room for other game information, and I ended up at a 22×22 world with each tile having 22×22 subtiles.
After a rough interface sketch, some calculations and some guesswork I decided the tiles would graphically fit best at a 32×32 size. However, I’m terrible at drawing stuff, so I decided to turn ‘lack of skill’ into ‘style’ and went for a pixel art look; I drew every tile and item in 8×8 and then resized it to 32×32 to make it look ‘retro’.
I made all of the art in GIMP because the Paint that comes with Windows 7 tries to be too hard to be a real drawing program and in doing so actually becomes worse for making pixel art…and it still doesn’t have any transparency. Brushes were surprisingly actually very useful when making tiles like grass, sand and sea. Just keep using random brushes and you have good-looking grass. Definitely something I should use more often.
Sound and music
The music for the game was made in FL Studio 9 using only soundfonts from DSK Music‘s HQ Instruments set. Although the effect is very subtle, the game actually contains dynamic music; although throughout the entire game the same track keeps playing, there’s three slightly different versions of them. They play simultaneously, and the volume adjusts depending on where you are.
The music used the ‘Celtic Harp’, ‘Ney Flute’, ‘Percussion 1′, ‘Oboe’ (forest only) and ‘Harp’ (beach only) soundfonts. It was inspired by Paavo “Tarantula” Harkonen’s soundtrack for obscure MMORPG Dransik (now a shadow of its former self and named ‘Ashen Empires’) and a random street performer playing on a harp the day before LD23.
The sound was created by rubbing or hitting various objects around my desk against eachother in different ways, recorded with my laptop microphone and edited in Audacity (amplitude change, pitch change and echo). Like the music, it was mainly inspired by obscure MMORPG Dransik, where you would hear a simple but satisfying sound whenever you did things like cutting trees and mining.
But how did it become a persistent world game?
Development started out well. I started by making simple ‘world generation’ (filling the entire world with grass tiles). Then I made movement work, then proceeded to add sea and forests to world generation. I added the axe and item usage, so you could chop wood. Then I also needed support for dropping and picking up items, which also required a menu to let you choose between items. I also made sure you could save and load your world, so I made functions to serialize the entire world to a long string and load it again.
At that point, day 1 was already over (LD goes from Saturday 3 AM to Monday 3 AM here, so it’s 2 days instead of 3 as it is in some time zones), and there was no sign of crafting, construction, the hunger system, NPCs, wildlife, fishing and similar methods of food gathering, liquids, an age system, building recognition or pretty much anything beyond the very basics of the game. Whoops. So, what is the logical thing to do when your plans seem way to ambitious?
I went with the logical solution: I changed my game into a complete persistent world building game. Of course it’s a ridiculous decision to take halfway through development, and even more so when your project is in that state due to being way too ambitious, but all things considered, it ended up being not as unreasonable as it sounds. I had recently created a netplay library, and though network communication is always tricky and it was not tested much, it did seem to work perfectly from the small amount of testing it did get. As a game design decision it was more logical than anything; I was just a tiny bit of code away from making a game where you can build stuff, and games like Minecraft, Terraria, Active Worlds, a whole slew of BYOND building games and many more games have pointed out that just building things for other players to see can actually be fun in itself. Add to all that that I could already serialize any part of the world to a string, and the decision was made overnight to go all-or-nothing for an online persistent world game.
The first thing I did on the second day was finish the crafting and building system (otherwise even having a persistent world would be futile). Then I used my GNI library to write a server program and a client class. The client would ask the server for the serialized string representing the world map, and then for the serialized strings of each of the areas in the tiles (each tile on the 22×22 world map contains an inner area consisting of 22×22 ‘subtiles’, if you haven’t played the game). I found out the serialization had some errors, but after some bugfixing, it actually worked perfectly. Then, to make client changes affect the server and have the server keep the client up to date, instead of at the start the server would send the client the inner areas only whenever he zoomed in or walked to a different inner area, and the client would serialize the entire inner area and send it to the server whenever a tree was cut, an item was dropped or picked up and whenever something was built. It’s an inefficient approach (the reason it lags whenever you switch between areas or do something area-affecting), but it worked great for a 48-hour game. I then proceeded to add functionality for chat, player names, seeing each other, et cetera.
After the netplay features worked, I decided to add what little extra content I could still safely push in (mountains, stone, and anything that requires stone – yes, originally there was only wood) and release it.
What I like about the game
-It’s a persistent world game. That by itself is awesome.
-It’s my first succesful attempt at a non-BYOND online game. There was one other finished game were I attempted netplay, but its netplay was a horribly buggy mess that desynced for any players that were more than 2 meters apart.
-The world generation is nice. I’ve barely done any random world generation before, so the fact that I managed to get a properly shaped island with properly shaped beach and mountain areas out of it is pretty nice.
What I dislike about the game
-Lack of content. And I mean utter lack of content. There’s two kinds of walls to build, two kinds of floor plus four natural floor tiles, one tool to make and one decorative item. Ludum Dare games aren’t known for their extreme length, but it’s very minimal here; it’s a building game, but there’s hardly any variation in what you can build, so you get bored very easily. This is especially disappointing after my previous LD game, which could be played for significant lengths of time and still be interesting.
-It’s buggy and laggy. Whenever you zoom in, lag. Whenever you build something, lag. Whenever you cut a tree, lag. Whenever you move from one area to another, lag. And those 4 natural tiles I mentioned at the previous point? Good luck getting three of those without relogging a minute later, as they mess up something in the graphics (still not sure what causes it).
Things I should do again next LD
-Use VBXSE and GNI again. Especially the latter came as a surprise in how powerful it can be in just a small amount of development time. I was afraid of netplay functionality before considering the debugging hell it can cause, but now I think I’ll just plan for netplay from the start of the theme allows it.
-Use pixel art. I can’t draw, but ‘style’ turns out to work as a pretty good excuse to hide my lack of skill.
-Record random objects using my laptop microphone and edit them in Audacity for quick sound effects. I’m pretty satisfied with how they turned out; they subtly add a lot.
-Be overly amibitious. Partly because I’m just an idiot, but also because going beyond what you know you can do allows you to learn new things. It would be better for the game if I didn’t, but in the long run this is very useful.
Things to keep in mind for next LD
-I should make sure there’s enough content. LD is for games, not for tech demos.
-I should try to get the day after LD off work. Starting a week with a serious lack of sleep hurts your productivity for the entire week.
-I should update and improve VBXSE and especially GNI. They’re awesome, and therefore they must become even more awesome.
-I should make sure I’m used to the the tools and libraries I’m working with. I thought I knew XNA, but it wasn’t until halfway through the project that I realized I didn’t know even how to play multiple music tracks at the same time and change their volume. I also wasted a lot of time debugging an issue that happened because I didn’t take into account that using auto-poll GNI’s client class handles received data in a different thread.
I was initially considering updating the game a bit, adding some extra content and fixing some things I didn’t like, but there are so many things I’d like to change and so many things that need to be changed to make the game actually fun that it’d just take too much time. I think it would be interesting to one day make a complete game based on this, but that’s the kind of plan that will either never see the light of day at all or won’t be used until years later.
By the way, I forgot to do it initially, but I’ve slapped a Creative Commons license on the game so you have the right to mess with it in any way you want. Well then, see you all next LD!
Appendix A: Tools/libraries/etc used
C#: The language the game is written in.
XNA: Engine used for the game.
Microsoft Visual Studio 2010: The IDE I’ve used to make the game in.
VBXSE: XNA Sprite engine, used for all graphics stuff.
GNI: Netplay library, used for client-server communication
FL Studio 9: Used to make the music. I’m a fervent supporter of pattern blocks, even as Image-Line gets rid of its unique features.
DSK Music’s HQ Instruments: Set of amazing soundfonts I use for music. The music for this game was made solely using DSK HQ Instruments, using default FL Studio VSTs as effects.
Audacity: Pretty much the best audio editor around. Used for sound effects.
Appendix B: Network signals
If you’re interested in how exactly the server and client communicate, these signals are sent back and forth. Each signal has a ‘key’ denoting what the signal is about, and a ‘value’ containing other info.
Server to client
(None) – A signal with no information to check if the client is still connected.
identify – Asks the player for his appearance and location, in case some other players requests it later.
goplay – After version check and sending the necessary maps. Tells the client the player can start playing.
gspfinish – Indicates the server is finished sending inner tiles and the client can enter the subterrain the player was about to enter.
message – A chat or system message. Output the value to the displayed messages.
people – A list with the unique player numbers of all players that are currently online. If a known ID is missing, that means a player has disconnected. If there’s an unknown ID, the client sends a ‘who’ signal to ask for information on the new player.
person – Information on a player (ID, appearance, location) as a response to the ‘who’ signal. The client will then add the player to the list of known IDs.
pos|X – Where X is the unique player number of a different player. Tells the client where the specified player is right now.
subter|X|Y – Where X and Y are integers representing coordinates. Replace the inner tile at X,Y with the serialized inner tile in the value string.
subteru|X|Y – Same as above, but the change is vital, so if the player is in the area, it MUST update the inner area before letting the player continue doing whatever he’s doing.
versioncheck – Asks the client to send his version number, to make sure he isn’t using an outdated client.
versionmismatch – Tells the client he can’t play on the server because the versions don’t match. Which version the server is running is in the value.
where – Requests the client to send a ‘here’ signal, telling the server where the player is.
worldmap – Sends a serialized world map as the value. Allows the client to build the same world map client-side as the one that exists server-side.
Client to server
The server automatically sends these signals without the client saying anything to it:
Every 2 seconds – where – Ask for the player’s current location.
Every 2 seconds – pos – Tells the player where other players are.
Whenever a client connects – versioncheck – Asks the player for his client version.
The server can receive the following messages:
cmsg – Client wants to send a chat message.
getsubplus – Value contains X and Y coordinate. Client asks server for the inner area at (X,Y) as well as the 8 areas around it. Server sends them followed by a ‘gspfinish’.
here – Client tells the server where the player is.
ident – Client tells server information about the player (appearance and location). Server stores the information and sends ‘worldmap’ and ‘goplay’ signals to let the player start.
nick – Sets the player’s nickname.
usub|X|Y – Client tells server they updated the inner tile at (X, Y). Server updates world and sends a ‘subteru’ signal to all players.
version – Client tells server what version they’re using. If it matches, the server will return an ‘identify’ signal, otherwise it will return a ‘versionmismatch’ signal.
who – Client asks server for information on a player. Server sends a ‘person’ signal in response.