The exciting technical news this weekend is that I've nearly finished the Generator program. As of Saturday afternoon, it's generating Message subclasses from the master XML document, and I'm not aware of any bugs in the generated code. [Edit: found one!] I still need to add some error checking and make it generate the HTML documentation and the dispatcher, listener, and adapter classes, but that shouldn't take more than a day.
The next step will be writing the XML for all the requests and data involved in getting the player logged in and into a game. Once I reach that milestone, I'll turn my attention to the game server and reference client. And when the client and server are roughed out, it will be time to invite other developers to join the project.
I hope to find at least one person interested in developing the client in parallel with my own work on the server. This may help me finish the project sooner, but that isn't the goal. The main reason I want to bring in other developers is to get some experience managing a team. I'm curious to see what happens when Subversion detects a conflict in one of my commits, but the challenge I'm truly interested in is effectively communicating design intentions and coordinating other programmers' contributions.
The first place I'll advertise will be the Java Forums. But I'd also like to draw the attention of the remaining Trade Wars crowd. The only problem is, where to reach them? Advertising on the EIS boards is probably out of the question, since my game will be in direct competition with theirs, which is a commercial product. But perhaps the developers of SWATH will see some value in helping me revitalize the market they serve. And who knows — perhaps Trade Wars 2002 will enjoy a resurgence of popularity if my game brings new attention to the genre.
Showing posts with label protocol. Show all posts
Showing posts with label protocol. Show all posts
Sunday, June 19, 2011
Monday, June 13, 2011
Talkin' 'Bout My C-c-code Generation
I'm still not as far along on the protocol library as I wanted to be last weekend. After volunteering, working, partying, thrift-store scrounging, and spending quality time with my lady, I haven't had much time for programming. But that's okay.
I've learned several new technologies while planning the protocol sub-project. First, I brushed up on my Subversion commands and put the beginnings of the protocol library up on SourceForge. I've used Subversion before to check out snapshots, but this is my first experience managing a Subversion repository, so bear with me if I do anything weird! The project on SourceForge includes all my Eclipse project files, so if you use Eclipse you can easily import it. In the future, I may export an Ant project and put that up as well. I compared the Subclipse and Subversive plugins, and chose Subversive because it seems to have the best integration with Eclipse. I spent a couple days learning to write XML Schemas, and then about a week developing a schema I was happy with. I compared a few validating XML editors, including XML Copy Editor (XCE) and the XML editing perspective for Eclipse. XCE is a great stand-alone editor, but I decided to go with the Eclipse plugin, despite the fact that each additional plugin increases the IDE's already considerable appetite for my netbook's limited memory. I studied the three approaches to reading XML that are built into Java's standard library — DOM, SAX, and XPath — and chose XPath for its clarity and simplicity. Finally, I began studying the CodeModel API for Java source generation. CodeModel was created by Sun, but it seems to have been abandoned when Java was sold to Oracle. It's poorly documented and lacks the polish of other Sun APIs, but it's working well for me so far.
The master documents for the library are the XML document and schema in the resource folder of the source tree. With the exception of two or three hand-coded files, the entire library (including its documentation) will be generated from these XML files.
One of the advantages of code generation is that I can refactor the library very easily. For example, I had a hard time deciding whether to extend the Message class for every message type, or provide a helper class with static methods to set the parameters of generic Message objects. With code generation I can do both, and with less potential for error. Not only am I freed from writing and maintaining hundreds of classes, but users of the library have the choice of two different performance options. If a program doesn't reference the type-safe message dispatchers or listeners, the JVM shouldn't load the multitude of Message subclasses, minimizing startup time and memory usage.
Then again, this may not even be a serious concern. Once upon a time, I read in one of Sun's official Java books that there is significant overhead for each class loaded by the JVM. However, I'm also aware that JVM performance is much better than it used to be, and hardware is much more powerful, so what was significant back in the days of Java 1.2 may not be so significant anymore. Using CodeModel, I wrote a program that loads a thousand classes. The startup time and memory use weren't too frightening, even on my 2010-vintage netbook. It might be worse with classes that actually do something, but the results still relieved my worries.
I need to learn more about CodeModel before I can finish the program that generates the library. We'll see how far I get doing it the "right" way before I give up and start taking shortcuts.
I've learned several new technologies while planning the protocol sub-project. First, I brushed up on my Subversion commands and put the beginnings of the protocol library up on SourceForge. I've used Subversion before to check out snapshots, but this is my first experience managing a Subversion repository, so bear with me if I do anything weird! The project on SourceForge includes all my Eclipse project files, so if you use Eclipse you can easily import it. In the future, I may export an Ant project and put that up as well. I compared the Subclipse and Subversive plugins, and chose Subversive because it seems to have the best integration with Eclipse. I spent a couple days learning to write XML Schemas, and then about a week developing a schema I was happy with. I compared a few validating XML editors, including XML Copy Editor (XCE) and the XML editing perspective for Eclipse. XCE is a great stand-alone editor, but I decided to go with the Eclipse plugin, despite the fact that each additional plugin increases the IDE's already considerable appetite for my netbook's limited memory. I studied the three approaches to reading XML that are built into Java's standard library — DOM, SAX, and XPath — and chose XPath for its clarity and simplicity. Finally, I began studying the CodeModel API for Java source generation. CodeModel was created by Sun, but it seems to have been abandoned when Java was sold to Oracle. It's poorly documented and lacks the polish of other Sun APIs, but it's working well for me so far.
The master documents for the library are the XML document and schema in the resource folder of the source tree. With the exception of two or three hand-coded files, the entire library (including its documentation) will be generated from these XML files.
One of the advantages of code generation is that I can refactor the library very easily. For example, I had a hard time deciding whether to extend the Message class for every message type, or provide a helper class with static methods to set the parameters of generic Message objects. With code generation I can do both, and with less potential for error. Not only am I freed from writing and maintaining hundreds of classes, but users of the library have the choice of two different performance options. If a program doesn't reference the type-safe message dispatchers or listeners, the JVM shouldn't load the multitude of Message subclasses, minimizing startup time and memory usage.
Then again, this may not even be a serious concern. Once upon a time, I read in one of Sun's official Java books that there is significant overhead for each class loaded by the JVM. However, I'm also aware that JVM performance is much better than it used to be, and hardware is much more powerful, so what was significant back in the days of Java 1.2 may not be so significant anymore. Using CodeModel, I wrote a program that loads a thousand classes. The startup time and memory use weren't too frightening, even on my 2010-vintage netbook. It might be worse with classes that actually do something, but the results still relieved my worries.
I need to learn more about CodeModel before I can finish the program that generates the library. We'll see how far I get doing it the "right" way before I give up and start taking shortcuts.
Sunday, June 5, 2011
The Protocol
I hoped that by the time I sat down to write this weekend's update, I'd have an incomplete but functional version of the protocol library up on SourceForge. Alas, it was not to be. Several times I was certain I'd produced the ultimate design, only to quickly think of some important shortcoming or opportunity for improvement. But the most recent version hasn't changed for two or three days, so I think I'm finally ready to press on. (Fingers crossed! Knock wood!)
I've already spent three weeks on the protocol, and though the blueprint has (hopefully) been drawn, I've barely broken ground on building the house. Yes, this does seem at odds with my commitment to using existing libraries wherever possible. So before I bore you with the technical details, I want to explain two things: why I didn't just use a common protocol for which clients are readily available, like telnet or HTTP, and why I chose to write a custom protocol from scratch rather than use something like object serialization to XML.
As I mentioned before, Trade Wars 2002 has retained a small but faithful following. I believe the one characteristic that unites these players is that they're tinkerers. Many of them are programmers. And from Telix to SWATH, these dedicated players have always loved their scripts. (I was one of them; some of my scripts from ten years ago are still available from the SWATH script library.)
Scripting in Trade Wars was once a subject of controversy. For those who weren't drawn to it, it seemed to spoil the competition. Some even called it cheating. But there was never any way to prevent it, so it was tolerated, then accepted, and finally became the norm — but only in Trade Wars. Most modern games use closed-source clients, and place severe restrictions on enhancing or scripting them, if they allow it at all.
From the outset, I've designed my game with scripting in mind. I want to keep the game enjoyable to casual players by incorporating features like global cooldown timers to give human reflexes a chance against scripts. But rather than merely acknowledge the inevitability of scripting, I'm officially encouraging it and making it easy. I want to entice the authors of Trade Wars helpers and scripts to play my version. I want scripting my game, or even developing an entire custom client for it, to be an opportunity for inexperienced programmers to write something exciting. Above all, I want every player to enjoy the fruits of a competition for the best ways to collect, analyze, and present the game data.
I came up with several criteria for the format of the protocol's messages. First, I wanted them to be human-readable, for easy understanding, logging, and debugging. This ruled out binary. Second, I wanted to maximize content and minimize bandwith. Bandwidth shouldn't be an issue in this century, but I envision my game being played on smartphones, and the telcos are still outrageously stingy with their data plans. So this ruled out XML. Third, I wanted the messages to be extremely simple to generate and parse in any programming language.
I eventually settled on a properties list crammed into a string of comma-separated values. Every message is terminated by a newline. A message might look like this:
Simple, right?
I've been working on an XML document describing the various message types. It follows an XML schema, which I suppose makes the schema meta-meta-data. From this master XML document, I'll generate the Java library for reading and writing messages. Details next week!
I've already spent three weeks on the protocol, and though the blueprint has (hopefully) been drawn, I've barely broken ground on building the house. Yes, this does seem at odds with my commitment to using existing libraries wherever possible. So before I bore you with the technical details, I want to explain two things: why I didn't just use a common protocol for which clients are readily available, like telnet or HTTP, and why I chose to write a custom protocol from scratch rather than use something like object serialization to XML.
As I mentioned before, Trade Wars 2002 has retained a small but faithful following. I believe the one characteristic that unites these players is that they're tinkerers. Many of them are programmers. And from Telix to SWATH, these dedicated players have always loved their scripts. (I was one of them; some of my scripts from ten years ago are still available from the SWATH script library.)
Scripting in Trade Wars was once a subject of controversy. For those who weren't drawn to it, it seemed to spoil the competition. Some even called it cheating. But there was never any way to prevent it, so it was tolerated, then accepted, and finally became the norm — but only in Trade Wars. Most modern games use closed-source clients, and place severe restrictions on enhancing or scripting them, if they allow it at all.
From the outset, I've designed my game with scripting in mind. I want to keep the game enjoyable to casual players by incorporating features like global cooldown timers to give human reflexes a chance against scripts. But rather than merely acknowledge the inevitability of scripting, I'm officially encouraging it and making it easy. I want to entice the authors of Trade Wars helpers and scripts to play my version. I want scripting my game, or even developing an entire custom client for it, to be an opportunity for inexperienced programmers to write something exciting. Above all, I want every player to enjoy the fruits of a competition for the best ways to collect, analyze, and present the game data.
I came up with several criteria for the format of the protocol's messages. First, I wanted them to be human-readable, for easy understanding, logging, and debugging. This ruled out binary. Second, I wanted to maximize content and minimize bandwith. Bandwidth shouldn't be an issue in this century, but I envision my game being played on smartphones, and the telcos are still outrageously stingy with their data plans. So this ruled out XML. Third, I wanted the messages to be extremely simple to generate and parse in any programming language.
I eventually settled on a properties list crammed into a string of comma-separated values. Every message is terminated by a newline. A message might look like this:
ts=1307312894,type=SERVER_HANDSHAKE,name=Official Test Server,version=1.0,protocol=1.0Simple, right?
I've been working on an XML document describing the various message types. It follows an XML schema, which I suppose makes the schema meta-meta-data. From this master XML document, I'll generate the Java library for reading and writing messages. Details next week!
Friday, May 27, 2011
Overview
As a programmer, I have a bad habit of reinventing the wheel. I've devoted vast energies over the years to algorithms and data structures that I could easily have sourced from elsewhere, had I not been so neurotic about "bloating" my projects with "unnecessary" libraries. My fascination with implementation details produced some pretty groovy stuff, like a Java thread pool years before Java's standard library offered thread pools. But it didn't produce very many complete apps. I rationalized that coding was just a hobby that I enjoyed for its own sake — that it wasn't a means to an end, but an end in itself.
Well, I'm over it.
I've been working on this project for a little over a month now. I was surprised how quickly it started coming together once I decided to use existing libraries whenever I could. Instead of spending months writing my own persistence API, I spent two weeks comparing the options and studying the one I settled on, JPA2. Then I spent day or two each on Apache Commons Configuration and Apache log4j. I even pulled in Apache Commons Codec for the sake of one little hash function. I'm not writing anything I don't have to!
That said, after experimenting with several alternatives, I decided to roll my own client-server protocol. That decision cost me two weeks, but I'm very happy with it. The details will be the subject of my next post.
One of my top-level design goals was to make everything modular and scalable — a modern MMO, writ small. For the sake of simplicity, I chose not to create separate services for authentication or inter-client messaging. Both of these will be part of the game server. But in the unlikely event that I ever need to run clusters of game servers to handle thousands of clients, they will be relatively easy to refactor.
There are five major components:

I'm calling the reference client a "telnet bridge" because it will function either as a stand-alone client, or as middleware to provide a text interface for traditionalists and casual players. I want people to be able to check out the game without installing anything.
I should probably count this blog as the sixth component, as much time as it takes to write. But I enjoy it; it helps me put things in perspective. Programming is a hobby I can easily get sucked into at the expense of all else good in my life. I'm pacing myself by aiming for one milestone worthy of writing about each week.
Well, I'm over it.
I've been working on this project for a little over a month now. I was surprised how quickly it started coming together once I decided to use existing libraries whenever I could. Instead of spending months writing my own persistence API, I spent two weeks comparing the options and studying the one I settled on, JPA2. Then I spent day or two each on Apache Commons Configuration and Apache log4j. I even pulled in Apache Commons Codec for the sake of one little hash function. I'm not writing anything I don't have to!
That said, after experimenting with several alternatives, I decided to roll my own client-server protocol. That decision cost me two weeks, but I'm very happy with it. The details will be the subject of my next post.
One of my top-level design goals was to make everything modular and scalable — a modern MMO, writ small. For the sake of simplicity, I chose not to create separate services for authentication or inter-client messaging. Both of these will be part of the game server. But in the unlikely event that I ever need to run clusters of game servers to handle thousands of clients, they will be relatively easy to refactor.
There are five major components:
- the game logic, contained in a Java application
- the game data, stored in a relational database
- a Web interface for account management and scoreboards
- a client-server protocol, implemented as a Java library
- a simple reference client, also written in Java

I'm calling the reference client a "telnet bridge" because it will function either as a stand-alone client, or as middleware to provide a text interface for traditionalists and casual players. I want people to be able to check out the game without installing anything.
I should probably count this blog as the sixth component, as much time as it takes to write. But I enjoy it; it helps me put things in perspective. Programming is a hobby I can easily get sucked into at the expense of all else good in my life. I'm pacing myself by aiming for one milestone worthy of writing about each week.
Tags:
client,
database,
game server,
protocol,
web interface
Subscribe to:
Posts (Atom)