Data for Dummies

edited 2006 Jan 23 in Developers
<i>This post was originally made by <b>skyjake</b> on the dengDevs blog. It was posted under the categories: Engine, Games.</i>

Since map data now exists in the engine, games cannot create dummy lines on their own because they don't know the data structure of a line. This means the engine has to provide the dummy. In addition to this, the game may have some extra data (the "xline") that contains additional properties for a line. In the case of the dummy, only the game knows what extra data is needed, so the creation of a dummy involves both the engine and the game.

<blockquote><b>skyjake:</b> True, but what I was suggesting is basically just a helper mechanism for allocating a block of extra memory for each dummy so that the game wouldn't have to do it manually. (The game isn't obligated to use the engine's dummy memory helper since it can allocate the extra memory itself and not call P_XDummy.)</blockquote>

<blockquote><b>danij:</b> If we go with the idea of Doomsday allocating the space for the xdummy then I think we should suggest that the games shouldn't mix and match between local and game side management. What happens in the case of game-side objects such as things (the engine has no local objects of this type)?
Ultimately I would like to see Doomsday handling all custom map data object properties and objects themselves. I worry that applying different logic to different types of data object will lead to confusion.</blockquote>

Currently, in the case of mobjs, the games have all the necessary information to create a dummy mobj. (Mobjs still work on the old principle that the engine has defined the beginning of <tt>mobj_s</tt> and the game can extend it by adding members to the end.)

I agree that it can quickly get complicated if we start bringing in the engine in the allocations. However, it is beneficial if the engine knows the address of a dummy's extra data. That way, the extra data can be accessed via a reference to the dummy pointer itself without having to look through any lists. Let's say that the dummy is represented by <tt>dummyline_s</tt> engine-side.

<pre>
typedef struct dummyline_t {
line_t line; // Dummy line itself.
void* extraData; // Pointer to extra data.
struct dummyline_s *next; // Linked list of dummies.
} dummyline_s;
</pre>

The extraData pointer would be set when the game allocates the extra data for the dummy.

Now, P_AllocDummy() would return a void* to dummyline_t. We can have a P_DummyData(void* dummy) that now does this:
<pre>
// Determine that this is a line dummy.
return ((dummyline_t*)dummy)->extraData;
</pre>

This allows the game to implement P_XLine() in such a way that after determining if the line is a dummy, a call to P_DummyData() will return the xline. P_XLine() remains an O(1) operation.

P_DummySetData(void* dummy, void* extraData) would set the extraData pointer.

Comments

  • That data structure/architecture sounds good and it does have the advantage that no additional game-side book keeping is required.

    It should also deter 3rd party developers from doing anything funky with xdummy objects.

    Lets go with that.

    I'd like to provide a common interface for manipulation of object properties independant of whether a particular property is from the dummy or xdummy.

    The DMU API could be wrapped using (mostly common) game-side routines for:
    <pre>P_Set/Get/Copy/SwapXYZ()etc.</pre>
    That determine whether the property is of a "real" object or dummy one transparently to the caller.
  • Perhaps I confused the issue by mentioning things but it raises a good question. Should use of mobj_t be changed so that it works the same as the map data structures?

    It could very well be a complicated task to seperate common and game-specfic properties from a mobj_t...
  • <blockquote>The DMU API could be wrapped using (mostly common) game-side routines</blockquote>

    It could, although it may not be worth the effort. The DMU API contains quite a large number of functions.

    Just to clarify: dummies are handled in exactly the same fashion as normal objects, both in DMU and as (say) xline_t's. The only difference is that dummies exist outside the normal map data.

    When it comes to extended properties (i.e., the ones implemented by the game), they should not be accessed via DMU. After all, the game can do whatever it wishes with the extra data, even complex tree hierarchies or something stranger still.

    The mobjs are a good topic for another post.
  • <blockquote>When it comes to extended properties (i.e., the ones implemented by the game), they should not be accessed via DMU. After all, the game can do whatever it wishes with the extra data, even complex tree hierarchies or something stranger still.</blockquote>
    Of course. I was merely thinking that it would be nice to provide one syntaxically common interface to object properties, no matter if the extended properties or the internal properties are referenced.

    So:
    <pre>xline_t* P_XLine(line_t* line)
    {
    // Is it a dummy?
    if(P_IsDummy(line))
    return P_DummyData(line);
    else
    return &xlines[P_ToIndex(DMU_LINE, line)];
    }</pre>
  • That's exactly what I was thinking for P_XLine(), yes.
  • <blockquote>[from email] I think the local xdummy objects should be managed automatically? (ie whenever an engine-side dummy is alloc'd/free'd an xdummy is too)</blockquote>

    The allocation and freeing of a dummy needs to be handled by a game-side routine in Src/Common. They will handle the calls to P_AllocDummy/P_FreeDummy, and allocate/free any necessary extra data.
  • Yes thats what I meant :)

    I'll grant you I asked the question in a roundabout way though.
  • In XG when a dummy line is created in order to do Chain sequences, the current code explicitly sets the following:

    dummyline.frontsector = sec;
    dummyline.sidenum[0] = -1;
    dummyline.sidenum[1] = -1;

    These properties arn't writable via DMU currently, so how should we handle this?
    Perhaps we could allow writing to ANY property when the object is a dummy?

    Additionally <tt>sector->reverb</tt> cannot be changed via DMU currently.
  • They need to be made writable. We should allow doing this:
    <pre>
    P_SetPtrp(dummyline, DMU_SIDE0, NULL);
    P_SetPtrp(dummyline, DMU_SIDE1, NULL);
    </pre>
    These would set the index numbers to -1. We should avoid using the index -1 directly, though.

    The reverb property needs to be added.
Sign In or Register to comment.