Untitled

Published February 20, 2006
Advertisement
I ate so much this weekend I think I might actually die. I don't want to eat at all today, it still hurts :(

I reviewed the original MetaClass system code I had working. To mkae it work with the query system I think it'll be better to strip it down and start from scratch. It's possible to start implementing this new stuff now, but I would rather have it built up with this in mind. I can say that the original MetaClass system is useful, but has some annoying issues that I would want to work out.

For example, it's impossible to add per-object attributes at runtime; something that is fine for C++ but for this system it's undesirable. It's also too C++ like in its nature; I have the concept of 'classes' as an integral part of the system, methods are also separate from the normal attributes of the object. For the system to function as desired I'll need to remove this and implement a more flexibile system. The current attribute setup is interesting, I have an 'Attribute' class and an AttributeValue class being derived from it. This idea was to separate the data from the actual attribute - which is fine - but it's a little too restrictive in nature. Instead of inheritance, I'll use composition and store the AttributeValue as a member of the Attribute class. This will allow easy swapping of the values for attributes, even to the point of dropping in an entirely new typed value.

Seeing phantom talk about the concept of a Lua functor reminds me of the original idea behind my metaclass system. The first concept was to provide a 'class' system in C++ that was scripting system agnostic. You would specify your metaclass types, complete with attributes and methods and then operate on them using the API I provided. Admittedly, it didn't provide much of a bonus in 'pure' C++ environments as the extra level of indirection reduced the speed of the system and didn't offer anything else unless you needed 'pure data' classes that could be specified at runtime. However when you couple this idea with the notion of scripted methods it adds a lot more power by opening up the possibility to call scripted methods specified in any bound language. You could even call C++ specified methods or methods via a form of RPC as the marshalling process is somewhat the same - convert native metaclass properties / objects to a form understood by the other system.

So what happened to the prototype system? Quite simply, I started getting bogged down in my own VM implementation as I wanted a custom script system to power it - something that effectively stalled the project. By loosening the original design to incorporate the query interface I've effectively nullified the design of proposed scripting language for the system and been forced to revaluate how it'll be used. This is actually a blessing in disguise as I am now free to work on developing a useful system that reiterates my original goal of it being language agnostic.

So the system in a nutshell:

  • Runtime specification of object prototypes
  • Create object instances based on prototypes of other objects
  • Runtime modification of objects, allowing on the fly addition/removal of attributes
  • System is dynamically typed
  • Language agnostic declaration and calling of object methods
  • Objects can be tagged with name and data labels
  • System-wide database of objects allowing set-based querying and updating of objects via query interface
  • Object serialisation via special interface, allowing objects to be saved as binary, XML to a database or other
  • Caching system to swap seldom used objects in/out of memory (possible via serialiser interface)

    The 'metaclass' system name will be dropped; instead I will be referring to it as the Entity Object system (at least for now). The overall goal is to allow for complete data-driven game architectures to be formed around it.

    This system is all well and good, but now I want some feedback from you guys. Specifically, how would you use this system? What would you use it for? Can you provide examples, if possible?

    Usage examples will help when I'm rebuilding the prototype as it'll allow me to begin catering the system to some real-world scenarios instead of building it in isolation.
  • Previous Entry Untitled
    Next Entry Thanks!
    0 likes 3 comments

    Comments

    ApochPiQ
    I'm not really clear on the purpose of this system, to be honest. Are you trying to build a method of dynamically handling data, a method of dynamically acting on data, or both? This stuff seems like a really interesting way to handle data. It's sort of blurring the data-metadata lines a bit, and encouraging some forms of self-description that are really interesting - like XML, except not as dull. But I'm not really seeing how you intend to act on this data. Are we talking of an OOP-style system where data acts upon itself? Or is this simply a data-warehousing system, like an RDBMS, and there is an implicit logic layer that is built per-application on top of this?


    I could see this system being tremendously useful just as a data warehouse: vector graphics, game data (both runtime and prepackaged), documents, enterprise databases... all kinds of applications could be designed to do interesting things here. But do we really need another storage solution? Do we really need another Relational Database Theory, another XML, another incarnation of S-expressions without all the goofy parentheses?


    IMHO, this only becomes really interesting when the system itself provides ways for data to act on itself. RDBMS theory bores me. XML bores me. I've got to have one tool to blob all my data together, and one tool to do interesting things with the data. Lisp is cool because, with code as first-class data, I only need one tool to do both. (Lisp, and first-class-data coding in general, is a land of toys that I've not yet had the chance to explore as deeply as I'd like.)

    This may be utterly contrary to your intentions for the system, but if it were mine to mold, I'd have it set up thusly:

    - An object, by itself, is a formless void
    - The nature, or type, of an object, is determined by how it is "data-tagged"
    - Each "data tag" is permitted to record data (including nested objects/tags) as it sees fit
    - The behavior of an object is determined by how it is "logic-tagged"
    - Each "logic tag" acts as the fundamental aspects of logic that act on data, essentially the functions-half of a typical OOP class hierarchy

    A typical thing we might have is a GUI Widget. In OOP GUIs, it is not uncommon to see things like "a PushButton is a subclass of RectangularWidget and ClickableWidget, both of which inherit from Widget." (At least, in C++, where we get multiple inheritance. Translate to the OOP sub-paradigm of your choice.) In this system, a Widget has an abstract Render function; RectangularWidget specifies this by adding Rectangle data and making Render draw the rectangle. ClickableWidgets do analogous things with user input.

    In this other system, I'd see it playing out as such: "this particular Object is data-tagged as a Rectangle. The Rectangle tag carries an implicit association of being a type of Shape tag. The Object is also logic-tagged as being Clickable, which carries appropriate semantics for handling user input. Finally, the Object is logic-tagged to handle rendering, and data-tagged to handle specifics such as text label, icon, pushed-state, etc."

    So really instead of having a rigid hierarchy of types, we have a pool of data attributes and logical behaviors. There's a method by which we can associate or link things; some Data tags are always implicitly tagged with metadata (all Rectangle tags are metadata-tagged as being Shapes). Some tags always implicitly link to certain behaviors. Logical tags can delegate behaviors to other associated tags if they like.


    I don't really have a clear idea of how that would work in a system, how to express it syntactically, or how to derive benefits from this over a strongly-classed paradigm; but it seems like an interesting and promising half-idea [grin]
    February 20, 2006 05:28 AM
    pan narrans
    You fat £*#&e<
    February 20, 2006 03:01 PM
    jollyjeffers
    Right, I'll finally get around to leaving a comment [grin]

    I think I'm keeping up with what the general idea is, but like ApochPiQ a little clarification (or refinement?) on how the data can be acted upon in a way that is abstracted/"unknown" to the application.

    Quote:Specifically, how would you use this system?
    Here's something I was thinking of when I first read about your plans last week, and then again whilst reading this entry..

    Real Time Strategy - classic C&C/TA style. Where you can have a large number of units that could derive from a number of basic technologies (e.g. "Advanced Rocket Tank" comes from a "Tank" and a "Rocket Launcher"). Being able to store all combatants in the playing field in your system you could run queries ("Find all player units in this region", "Retrieve list of all damaged/injured units", "Find all units attacking location P"..) and you have potential groupings/relations (a shared/common attribute) - "Find all units in this range, assign attribute X" and "Find all units with attribute X". Being able to manipulate these as well "Damage all units near explosion Z", "All units with attribute X attack building Y"...

    The ability to have some form of scripting would be quite powerful - you could use the scripting to generate the graphics (e.g. create a wake/splash for only units in/over water) as well as the basic gameplay - scripting the weapons effects/characteristics and so on.

    Being able to store all the units in the DB and then use scripts assigned to unit classes would allow the application side of things to have very little knowledge of what was actually happening. It'd get pretty close to a mostly/totally data-driven architecture [smile]

    Hopefully I'm not misinterpretting things here!
    February 20, 2006 04:31 PM
    You must log in to join the conversation.
    Don't have a GameDev.net account? Sign up!
    Advertisement