Archive for May, 2007

Client-Server Stability

Potential RPG No Comments »

Yes, you may read that subject as a question.

Actually, I found a major one-line logic bug deep in the heart of the network code, where ByteBuffer mistakes deal swift justice to the unwary, and the ebb and flow of bytes must be respected and feared, like the sea… sorry.

From a technical perspective, I’m using the non-blocking java.nio system to handle network I/O. Sometimes, only some available bytes can be written to the network, and the non-blocking API allows the world to keep on spinning. Unfortunately, when some bytes were left behind, I forgot to re-queue the connection for output.

This would cause the network pipeline to stall intermittently (per client). I rarely ever saw this myself, because I connect with one client on a LAN (so all the pending output bytes tend to get sent at once). For you brave Alphanauts, somewhere across the aether, this may be the primary cause of several crash problems that I just couldn’t reproduce.

UPDATE (for Alpha playtesters): Nope, that didn’t fix all the problems. I’ve made some concessions and released a new client. I am bound and determined to solve all stability issues before moving on. Thank you for your patience.

UPDATE UPDATE: MMORPG appears to be stable again (after some quick testing — thanks Fox). I’m sure there are plenty of bugs to be found, but the game should be playable once again.

ACSPLAN (and the Puppet-Master)

Developer's Cave, Potential RPG No Comments »

ACSPLAN (autonomous client-side progressive latency-avoidance navigation) - \ACKS-plan\ - n - A temporal skew optimization for distributed simulation environments (and online games) providing client-perceived performance improvement in the face of network latency and server processing delay (lag).

MMORPG had a puppet-master model of character navigation. The client would directly manipulate and display the state of a puppet character. In the background, the puppet’s movements were requested of the server. The server maintains and updates the master, which is observed by the client. Thus, in the face of lag, the client has some slack to autonomously move the puppet without direct approval of the server.

In the common case, since both systems use the same character logic, the master would eventually be updated to the state of the puppet. However, circumstances exist (especially during pathfinding) in which the puppet would become out-of-sync with the master copy. Then, it is up to the client to reconcile the difference.

MMORPG’s initial reconciliation logic was very poor, causing wild navigational problems. So, as Knight to Taylor’s sport jacket, I threw it out. In fact, the whole puppet-master model caused several discrepancies. Now, how to get everyone to play on a gigabit switched LAN…

Java 6 Imminent

Potential RPG No Comments »

Up until now, all development has been on Java 5. I am now testing Java 6 (per issue#24). Backward compatibility has been a strong feature of Java updates, so I am not anticipating much hassle. There are even some new Java features that will be useful, such as splash screen support (plus new concurrency enhancements — yeah, I get more excited about the core features).

I’m hoping they’ve really polished Java Web Start. Java has always been developed by developers for developers. Sun also does a decent job promoting Java for corporate environments (maybe because they’re more used to selling hardware). Case in point, the JavaOne conference showcases a strange hybrid culture of corporate salespeople and geeks (I’m on the long-haired end of that stick).

Unfortunately, the Java marketing war hammer, for all its force, is still a blunt instrument that tends to miss the agile end-user target. Sun has begun to improve: java.com appears to be designed by publishers/artists rather than programmers. (In contrast, java.sun.com remains one of the most hideously difficult sites to navigate.) Hopefully, Sun will continue to improve the end-user’s desktop Java experience. Only then will Java finally be fully empowered to break the prevalent platform-dependent user application affliction.

Whole New World

Potential RPG No Comments »

There’s a whole new landscape to explore. Two reasons: (1) you deserve something new(*), and (2) I updated some base content types and didn’t want to bother converting the old world data.

(* …and the primary content I can provide right now is terrain.)

If you have trouble walking around, that’s because I turned off the ACSPLAN (autonomous client-side progressive latency-avoidance navigation) optimization. That’s a common feature, but there wasn’t a single name for it, until now. With this turned off, every step of your character has to be processed and reported by the server. If there is any lag (network or server processing), it’ll show up as delayed/rapid-fire character movement.

This fixes the client-server path-processing freakout bug (#74), but might make the game unplayable. This will be fixed by a better ACSPLAN implementation.

Until there is more gameplay, enjoy the new scenery.

ProxyIcon

Developer's Cave, Potential RPG No Comments »

For those who enjoy design patterns, I’ve written a ProxyIcon for the MMORPG client. The reason is to decrease memory allocation in the client, which is due in large part to graphic images, under the theory that most are not needed most of the time. This article describes the ProxyIcon (implementation details are left as an exercise for the reader). First, there is already a central factory of Icons. So, integrating a new proxy pattern only involved changing the factory. ProxyIcon implements the javax.swing.Icon interface, so users are none the wiser.

ProxyIcon knows the source of the image to load. When any Icon methods are accessed, it makes sure the internal image is loaded. If not accessed for some timeout, the internal icon can be unloaded. The simplest implementation would have set the internal Icon reference to null, allowing the garbage collector to clean it up. Why the present perfect tense? Because there’s an even better approach:

ProxyIcon holds two references to the internal Icon: A hard reference and a soft reference. After the timeout, the hard reference is set null, but the soft reference is retained. Since the embedded icon is only referenced (never exposed) from the ProxyIcon object, this leaves only the soft reference. Java cleans up soft references (only) when memory is needed. If, however, the ProxyIcon is accessed before being cleaned up, the hard reference is reinstated. This provides the best of both worlds: Application logic can set policy on when to release resources but is backed up by the Java Virtual Machine’s garbage collection logic to avoid unhelpful cleanup.

The primary benefit, of course, is that unused icon resources can be deallocated. The software design benefit is that image users do not need to concern themselves with whether the icon is currently loaded or not. Notice that all ProxyIcon references stay in memory forever (in the factory). They could also be deallocated by using soft or weak references in the factory, but the objects themselves are (theoretically) miniscule compared to image memory consumption.

Another minor benefit is lazy image loading. Instead of loading upon construction, the internal icon is loaded lazily upon first access. There are a number of icons that are requested in the code, but not always used. This feature has the benefit that the code can greedily ask for icons from the factory (e.g., as static variables) without impacting memory if not needed.

One major gotcha is that Java itself may be holding cached references to the image data, which prevents garbage collection. I have not investigated this fully, but do not use Toolkit.getImage(), as it’s API warns of just this problem. Also read the code for javax.swing.ImageIcon, which makes (undocumented) use of Toolkit.getImage(). Instead, use Toolkit.createImage() or ImageIO.read() with ImageIO.setUseCache(false). Further investigation is needed to determine exactly who has access to underlying image data depending on how it is loaded.

For Alpha testers, look at $HOME/.potentialrpg/stat/IconFactory.stat, which shows:

timestamp, total, loaded, hard_referenced, average_ms_timeout, ms_stat_time

Graphic Processing Updates

Potential RPG No Comments »

Graphic processing in general has been radically improved. In addition, client memory footprint was
reduced by about 50% (then I enlarged the rendering area, bringing memory use back up). Here’s a lesson for Java image manipulation: use BufferedImage.TYPE_INT_RGB rather than BufferedImage.TYPE_INT_ARGB_PRE when possible (one variable increased world rendering performance by roughly 90%).

The client deadlock bug has been mitigated (read: not fixed yet, but less likely). The cause, for those who enjoy fables of thread contention, is the AWT thread holding the Content lock and awaiting the Render lock, whilst the rendering Engine held the Render lock and awaited the Content lock. The render process still needs the content lock on occasion. The real fix will involve changing the content update process to not hold its lock on event notification… but I digress.

For the player, you’ll notice a major improvement during the world shift (when you get near the edge of the minimap). This used to freeze the client for a few seconds (usually while you’re being pummeled by Ogres). There’s still a delay, but it’s more like 300ms. Also, there shouldn’t be any edge garbage on the minimap during the shift — you should immediately see new terrain to explore (as the edge terrain is now pre-rendered and ready for the shift).

New Alpha Features (Plus new bugs!)

Potential RPG No Comments »

It has been about 2 weeks since the last release. My focus tended toward system-level improvements, but there are also some significant gameplay improvements. The best way to keep track of what’s going on is to follow the bug tracker. You can also get the RSS feed.

New features: Drop/take items from the world surface. Characters can also find items if walking around in the right area. There’s not much content for this yet, but check out the new Smelter in Second Town.

Experimental feature: World zoom. Roll the mouse wheel on the minimap to zoom the main surface view. All the world features (seem to) function, but it’s not entirely playable.

Known Issues: GUI freezeup. This may be related to the new scaling (zoom) control, but the cause has not been isolated.