home home

downloads files

forum forum

docs docs

wiki wiki

faq faq

Cube & Cube 2 FORUM


Plugin-based development of Sauerbraten or sauerbraten mods?

by IllvilJa on 04/29/2008 01:49, 37 messages, last message: 07/05/2008 05:23, 12414 views, last view: 05/05/2024 08:12

(This has been brewing in my mind and gnarling my skull for over a week or so, being impossible to get out of my mind... so I had to get this off my chest...)

When visiting the home page for the excellent editor jEdit (http://www.jedit.org), the very first sentence on that page is as follows:

"jEdit is a mature programmer's text editor with hundreds (counting the time developing plugins) of person-years of development behind it."

Now that at least SOUNDS impressive, marketing is a great thing! But now consider this rewrite of the sentence above:

"Sauerbraten is a mature FPS with hundreds (counting the time developming plugins) of person-years of development behind it's game engine."

That sentence depicts a hypothetical scenario, where we have some sort of architecture in the game engine allowing authors to create plugins that alters and extends the game in various aspects, potentially even inventing new aspects of the game. Note that I'm not talking about maps, textures, sounds, cubescripts or models here (even if they today provide some features of modular development which is good) but pieces of binary code which provides customized functions like custom lighters, custom 3d sound, custom modeling of shockwaves from explosions, custom particle systems, custom material cube shapers or why not custom cubescript commands. This without the requirement to recompile Sauerbraten but instead, just install the plugins at a place where Sauerbraten can reach them and load them whenever a map/mod/etc requires them. Of course, the plugins are opensource, so reviewers can read the source to verify that the plugins are not malicious.

Each sort of customizable plugin handles one well defined aspect of the game engine, preferably in some new special way, be it that it adds some sophisticated features for the game itself, or it is simply good at doing the normal job for such a plugin but only using 1/10th of the Memory and CPU usage normally used, or that it is intentionally simplified to bring down resource usages at the expense of ingame functionality and sophistication. The nice thing is that the plugin author do NOT have to grok the source of the entire game engine, it's just enough to understand the task of the specific kind of plugin being written. He/she writes the plugin, tests it and then uploads it to Quadropolis when ready, so others can use it.

Many good frameworks are built using this kind of approach. Many small modules and plugins, each of them doing just one or perhaps a handful of tasks but not more, but they do their job very, very well. Maybe Sauerbraten would benefit as well? Developers of the plugins and the maintainers of Sauerbraten can work independently of each other, which gives the plugin devs more freedom (at the end of the day, it is the acceptance of the end users that determines if the plugin is useful or not) and also, it frees up the Sauerbraten maintainers from having to manage the devs contributing with plugins and the developed plugin software. Then finally, the plugins can be distributed precompiled so the end users don't have to compile them or recompile Sauerbraten to use the plugins. Useful for modders too, as those now can create mods by creating some plugins as well as reusing already existing plugins that are useful. The Sauerbraten devs can also pick plugins they find really useful for the "vanilla" Sauerbraten and include them in the official Sauerbraten release.

jEdit is not an FPS. Sauerbraten is not a text editor. Both are however relatively complex pieces of software, both carrying out tasks which can be analyzed in such ways that separate functions inside can be analyzed. I think this kind of plugin architecture and associated development model can benefit Sauerbraten as well as the game's mods.

Curious about your thoughts on this. These plugins can be implemented one kind of plugin at a time. The plugin architecture can even be implemented in a mod of Sauerbraten (some more generic mod or a mod created ONLY for implementing this plugin concept) and then, if working well, it can be incorporated into the official Sauerbraten. Software development should be a little like Lego, after all ;-).

(and yes, I know that developing this kind of architecture requires both development effort as well as some (reasonable) amount of thought. I'm not naively assuming this is trivial.)

(BTW. I think the above statement from the jEdit homepage regrading jEdit actually IS accurate. The editor IS mature and very useful (I use it for software development) and there ARE a large number of plugins available, so I suspect even the "hundreds of person years of development" is accurate too)

Go to first 20 messagesGo to previous 20 messages    Board Index   

#18: Re: ..

by 2345234523452345 on 05/01/2008 23:19, refers to #17

this seems not well thought out...

all you'd really want to do with a plug-in thing is add new COMMANDs, VARs and game mods.

basically you'd have the lib supply one function along the lines of:

struct plugdefs *__init_my_plug(void)

where struct plugdefs just contains a dictionary of the various COMMANDs, VARs and mods that the plug-in supplies. then the lib loader registers those things, and yer done.

reply to this message

#19: Re: ..

by MovingTarget on 05/01/2008 23:29, refers to #18

That's not so bad of an idea! However, how would Sauerbraten know to load your library instead of its own (say engine.dll)? Would there be a txt file containing the lib to load? Would Sauer index all directories containing a lib of the preset name, and give you an option to load that mod (like with id games)? Would you simply replace the default one (not a good idea)? Would Sauer index all non-necessary libraries and load the one that is first in alphabetical order?

reply to this message

#20: Re: ..

by Quin on 05/02/2008 00:45, refers to #17

No, that is absolutely correct, and part of why I never bothered. In Linux, shared objects do exactly that, share. You can have them reference code from each other or the loading executable, in Windows.. this is another story. Sucky huh?

You'll need to come up with a good method of interprocess communication (IPC).

reply to this message

#21: Re: ..

by MovingTarget on 05/02/2008 02:56, refers to #20

Please elaborate on what you mean by IPC. This is a learning experience for me (and is starting to become "why I should switch to Linux").

reply to this message

#22: Re: ..

by Quin on 05/02/2008 06:26, refers to #21

Well, often programs that don't share memory communicate with each other by some other method, either via a socket, or as they sometimes do in Linux, via a named pipe.

reply to this message

#23: Re: ..

by MovingTarget on 05/02/2008 14:01, refers to #22

OK, but how would that help me eliminate the need for so many interdependencies?

reply to this message

#24: Re: ..

by 2345234523452345 on 05/02/2008 15:02, refers to #19

What is your goal with this?

Trying to make modules where you swap out entire sections of the engine is a waste of time. You may as well just distribute your own engine at that point.

But if you want something that will add complementary features, like in-game weather updates or in-game torrent downloads, then that could be worthwhile and significantly easier.

There are many ways to make a lib path:
- command line option
- COMMAND(loadlib)
- init.cfg
- special mod dir

There's no reason to have the libs all the same name.

reply to this message

#25: Re: ..

by a~baby~rabbit on 05/02/2008 15:48, refers to #23

You can eliminate interdependencies if you picture the engine as a switchboard - plugins don't 'talk' directly to one another instead they go via this switchboard...

I would follow 2345234523452345's advice.

reply to this message

#26: Re: ..

by MovingTarget on 05/02/2008 16:49, refers to #24

OK, so lets say I make a module that provides advanced bot functions. I put it in a special directory where the engine knows to look for mod libraries. The engine calls a special function required to be in each mod that returns the functions included. How the heck does the engine know when/where to call them? Does it look at the names of the functions and determine if they are the same as an engine function, and call the included func instead of the engine one?

I really like the idea, I just need to figure out a few things.

reply to this message

#27: Re: ..

by 2345234523452345 on 05/02/2008 19:07, refers to #26

that's a separate issue. essentially you're creating a cubescript interface to native libs.

It's up to the engine or mod guys to provide cubescript hooks that allow more control over the type of situations in your example.

reply to this message

#28: ..

by IllvilJa on 05/03/2008 00:04

The switchboard analogy is a good one.

What should consist of a module in the engine is a tricky question. Some stuff probably need to be refactored prior to be broken out into a module.

My thought is that a function in the game should preferably be broken out into a module if one can envision (or already has) an idea of another such module one can replace the "standard" version of the module.

The main thing that made my brain go "hey, this can be one of a bunch of alternate" is the shapes that every leaf node (cube) in the octree can have, a plugin we can call "cubeshaper" plugin (just to give it a name). One can imagine a cubeshaper plugin which provides shapes like the ones we have in Sauerbraten today. However, a map can be made more simplistic and instead of using the vanilla cubeshaper, it uses an alternate cubeshaper (which is specified in the .ogz or .cfg file, I have not really figured out which one should be the best... thing it is the .ogz) which is a "voxel" cubeshaper. The voxel cubeshaper only provides cubes that are either full solid plain cubes or that are totally empty. Simplistic but among other things, it takes just 1 bit to store shape information. Other cubeshapers are possible to envision, like cubeshapers that provide (approximate) bezier or spline surfaces, or which provide some sort of CSG (constructive solid geometry) functionality where a number of fractions of cubes (each fraction is a cube cut by one singe plane) are combined together using union and intersection operations.

The thing with the cubeshaper is that it virtually never directly call other plugins, but instead provides services to the engine. The engine can ask via a function available in all cubeshapers if a certain ray of light intersects with the shape stored in the cube. The cubeshapers must as well implement other functions that are necessary for the engine to carry out remipping, light calculations, physics calculation, but the key thing here is that it is the engine that directly calls functions in the cubeshaper, never the other way around. At least I assume (and hope from a code design perspective!) that the engine can use that calling convention.

Did that make sense? One single quite small functionality in the engine broke out into a swappable piece of logic.

I have a bunch of other plugins I would like to implement as well... I'll just give you some exotic names (I'll describe them in future posts when I have time):

cubecomposer (takes multiple cubeshapers, one per material, and let them all fit into one single cube. Permits shapes of water, solid ground and air for instance to exist in a cube containing a shoreline).

spacedivider. Today we have the octree, but one might imagine alternate ways to divide the space. For instance, we can have an octree with sections where the "grid" is rotated some angle around some axis, which would allow to create cities where one part of the city have blocks aligned in north/south and west east while another part of the city have blocks aligned in a grid which is ca 30 degrees clockwise to the normal north/west/south/east etc.

Surfdivider. Today textures are just one solid texture, but one can imagine an alternative scheme where a cube contains a "composed texture" containing a quadtree of squares containing different square textures as it's leaves.

etc etc

reply to this message

#29: ..

by IllvilJa on 05/03/2008 00:07

Hm. Pity we don't have any edit function.

"This could be a bunch of alternate"

in the post above should be

"This could be a bunch of alternate modules instead of just one fixed implementation"

reply to this message

#30: Re: ..

by a~baby~rabbit on 05/03/2008 03:00, refers to #28

"cubeshaper... one single quite small functionality" - umm, this is nontrivial... Can I suggest you begin with something just a tiny bit more simpler and tractable, i.e. making the menu subsystem a plugin, or weapon definitions, etc

reply to this message

#31: load

by Gilt on 05/04/2008 18:56

this might be too obvious, but usually when working on custom mods or commands that aren't right for the main distro I add the following file to sauerbraten, and then work on those mods in a completely separate location. keeps things clean and honest, and I don't worry about accidentally committing stuff to trunk.

// engine/load.cpp
#include "pch.h"
#include "engine.h"
#include <dlfcn.h>
ICOMMAND(load, "s", (char *s), if (!dlopen(s, RTLD_NOW)) conoutf("%s not found", s));


note that full game mods need to be loaded from init.cfg.

reply to this message

#32: Re: load

by MovingTarget on 05/04/2008 21:30, refers to #31

Yeah, I'm doing something like that, except I'm going to have the engine index a directory where people are supposed to place their mods, and load all of the libraries from there. Unfortunately, I'm on Windows, and the load code is a bit messier...

reply to this message

#33: ..

by MovingTarget on 05/08/2008 15:28

Just want to let y'all know that this is going to take a bit longer than expected. Real life is a terrible thing... :)

reply to this message

#34: ..

by IllvilJa on 05/08/2008 19:10

I know what you mean.

Real life is actually a very nice thing, IMHO, but it's demand for attention is quite astonishing.

Good luck! I'll try for myself to scramble some time for my experiments/research/misdevelopments.

reply to this message

#35: ..

by MovingTarget on 07/02/2008 18:09

Now that I have time to work on this some more, I had a question: What is the best way to expose the engine's functions (like conoutf) to an external project?

reply to this message

#36: mods

by fhkdajfconorfhdksj on 07/04/2008 11:35

I like how in Doom 3 (and a lot of ID Tech engine games) there is a menu item for mods. Maybe when a mod is made, it should be \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"zipped\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" into a sbm (sauerbraten mod) file that is places in sauerbrate/mods.

the command would be \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"loadmod modname\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"

the sbm file would contain dlls or shared libraries for each. Like if I made a physics mod called conormod:

sauerbraten/mods/conormod.sbm

loadmos conormod.sbm

inside my conormod.sbm would be physics.dll and physics.so

This would raise a problem, such as the fact that linux doesn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'t use dlls, and windows doesn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'t use shared libraries. Mac OS X uses shared libraries, but Mac OS X has two platforms: PPC and Intel. This is where Mac OS Universal binaries kick in, but then linux couldn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'t read the MACH-O Binary format.

Basically what i\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'m saying, is that the game mod would have to be compiled once natively, then cross compiled two times.


If only we could create a universal Linux/MacOSXintel/MacOSXPPC binary...


wow. 1.3498756 / 0.

ok for real. I think I found a bug in the forum software with the math problems.

ok refreshed. yeesh


and another genius move by me, I though I had been getting the math prob wrong, but i forgot a username

reply to this message

#37: Re: mods

by Quin on 07/05/2008 05:23, refers to #36

The answer is NaN .. or a segfault :P

reply to this message

Go to first 20 messagesGo to previous 20 messages    Board Index   


Unvalidated accounts can only reply to the 'Permanent Threads' section!


content by Aardappel & eihrul © 2001-2024
website by SleepwalkR © 2001-2024
53870949 visitors requested 71646151 pages
page created in 0.010 seconds using 10 queries
hosted by Boost Digital