6

As a player, I found the following problems about creating and using "extensions" (aka mods) for games:

1) Whenever the game is updated, all the mods break.

2) Most mods don't work with each other, so the player "has to choose"

3) If you ever de-install a mod, your "saved games" almost always become unusable.

I want to design a game in Scala/Java that does NOT exhibit those issues. I need help with point 2. I want to write it such that it is maximally extensible. My problem is I cannot nail down properly how I should do this, and since the whole design reside on top of the component/service/plugin architecture, than I can't move forward until I solved this problem.

The design qualities I want to achieve are:

1) For any "service", there should be a single object (at any given time) that implements it. Since it is a cycle-based simulation, I can safely "swap implementation" between the cycles.

2) It should be possible for a "third party" to create a "bundle" which either modifies or more likely extends the functionality of a "service", and "bind" it into the existing application at runtime, without recompilation.

3) It should be possible to load and unload those bundles at runtime, because they will be used in a long-running server.

4) Developing extensions should be easily possible, even for a "junior" programmer, without requiring extensive knowledge of some complex framework.

5) It should be possible for several bundles to extend/modify the same service at the same time, as long as they follow a certain set of rules preventing most conflicts.

I was first planning to use OSGi, but I can't really see how to get this to work. OSGi solution is to let many bundles register the same service and use a "filter" to choose one in the client code. Making the code aware that at any given time, there can be several objects that implements different variations of the same service, and that those instances can come and go, would make everything much too complicated and brittle.

My plan was to register every service as a generic "handle", which the user of the service can use to get the real instance and cast to what they want. The handle content could change over time, but the handle object itself would be valid for the duration of the program, therefore bypassing the constant querying of the registry, with associated filtering.

I think OSGi can solve 2 to 5, but only by using multiple instances of the same service, which is in contradiction to 1. I think that 1 an be achieved either by using composition, or by fusing all the different implementation of a service into a single object through byte-code manipulation. A look at Javaassist showed me that "rebasing" a class does not seem too difficult, if they all extend the same base-class and take the same constructor parameters. Composition, on the other hand, seem to put much more work on the hands of the third-party extensions developers, which is in contradiction to 4, and generally is a clunky solution at best.

If I implement the byte-code manipulation strategy, than I have to basically do almost everything myself, and loose most of the benefits of OSGi. Also, I cannot really create the fused service until all bundles have been activated, so they cannot register a "real" service instance at activation time, which is what OSGi is about (?). Do I even know from OSGi when it's "done"?

Is the only way of achieving those designs goal to create my own component framework, or can I still do it using OSGi, or some other system? Reinventing the wheel at that level sound like a stupid (and time consuming) idea, but I can't see how to solve those problems with OSGi. Maybe another service/plugin framework can do it? Or by using a specific well-defined design strategy?

UPDATE: It will a be an Internet Client-Server (Cluster) model running on OpenGL. I am mostly "framework unencumbered", that is, I can choose whatever fits my needs, but I want to stick to the JVM. OSGi is an attempt at standardizing "components" (called bundles) for the JVM.

3
  • Its your app. going to be on a network, internet, stand alone desktop app. ?
    – umlcat
    Commented Sep 12, 2011 at 15:26
  • Internet Client-Server (Cluster) model. The "mods" have to be installed both on the client and the server to work, but server is partitioned to allow different mods in different regions. Commented Sep 12, 2011 at 15:31
  • This question: programmers.stackexchange.com/questions/92811/… is less specific, but provides a good explanation of plugin based design. Commented Sep 12, 2011 at 16:21

3 Answers 3

2

Java Swing handles this problem using action handlers. Each component registers itself using one or more action handlers. When a particular action happens, each component that registered gets an opportunity to perform some code in response to the action.

A similar idea is a messaging system. A component registers to receive messages. The component is responsible for responding to whichever messages that it chooses.

Both of these ideas rely on the component having access to the rest of the code base. I'm not sure how you best make public all of the fields and instances of your game. I suppose a well defined set of game programmers interfaces is the best way.

2

Conceptually speaking, you want to deal with Component Programming, in which a section of code, maybe replaced with another, or new similar section of code may be added, removed or updated at runtime.

http://en.wikipedia.org/wiki/Component-based_software_engineering

I have read about several ways to do that, depending which programming language and which programming framework you are using. I ignore how to do it with the "Java Framework" or "Scala Framework".

(I done something similar with C/C++ & Object Pascal (Delphi), and "Shared Libraries" on network Windowze)

Its your game or application going to be in a network, internet or stand alone desktop app. ?

It is intended to run on a web page (javascript), flash control, or desktop interface like Swing or SWT ?

The technology to implement a "component driven" application, its very different from one "platform" or enviroment, from another.

On the programming language side, most of this "bundles" or "components", are objects that share the same class or implement the same interface.

1
  • It will a be an Internet Client-Server (Cluster) model running on OpenGL. I am mostly "framework unencumbered", that is, I can choose whatever fits my needs, but I want to stick to the JVM. OSGi is an attempt at standardizing "components" (called bundles) for the JVM. Commented Sep 12, 2011 at 16:08
0

The old game Dark Forces 2: Jedi Knight did not have this issue. Essentially, all game assets were stored in a place. You could add additional assets and use them(as long as they weren't overriding assets...for example replacing skins) and all was honky-dory. You just had to reference custom stages/assets by unique name. It's just proper design and including the pack-name as part of the asset ID.

If I'm grossly mis-understanding your question let me know, but I think this is a valid approach to what you're facing.

1
  • 1
    Well, I think that this applies to many games. The problem is "as long as they weren't overriding assets". Very many mods do precisely that, and without this ability, modding isn't have as interesting. Without "overriding", plain OSGi would do everything i need. Commented Sep 12, 2011 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.