Jump to content

Photo

Event System


  • Please log in to reply
3 replies to this topic

#1 anikom15

anikom15

    Dictator

  • Banned
  • Real Name:Westley
  • Location:California, United States

Posted 04 January 2014 - 08:00 PM

This is a hypothetical discussion. I don't have any working ZScript code to show for this idea.

 

I use a game library called Pygame, and one of its important features is event handling. Basically an event is an object that is placed on a queue (FIFO) which must be processed by the program. The queue is not processed automatically. The programmer has to decide what to do with the events. She usually throws most of them out and uses only the ones she needs. (E.g. there is an event for all key presses. She only uses the ones for the keys she needs and 'flushes' the rest.) This is used for low-level things like input, but can also be used for abstract things by defining custom events. (For those familiar with object-oriented programming, an event is an object, and a programmer need only make a class that is like an Pygame event, for Python is duck-typed.)

 

These events can be used for game state in limitless ways. For example, when a player gets an item, the game sends a GetItemEvent object (that the programmer has defined for her needs) to the queue. The program would have logic for catching this event and taking care of it.

 

Now that the object I'm discussing has been defined, let's talk about how this might relate to ZC.

 

One way an event model could be implemented is with the editor itself. This would be very useful to non-programmers. However, it is entirely up to the whim of the developers (if there is even going to be a future version of ZQuest). You would place a thing called a 'switch' on the screens. A switch is just something that sends an event when it is triggered. It could be a combo flag, a combo type, a property of an FFC, or something like that. For example, let's say Link enters a dungeon, and steps on a particular combo. It triggers a switch which sends an event to ZC. These events could be defined in their own section (like the other various editors). There would also be some way to define how ZC handles the event. Anyway, the event is handled in however the designer wants. Perhaps an item appears, enemies drop from the ceiling, or an NPC appears in some other screen on some other map.

 

So then there is scripting. I am trying to think of how to implement this with ZScript, but I'm not quite familiar with what features it supports and lacks. So instead I'll discuss how it might work in C. Scripts are, of course, the only way an event system can be implemented in the current version.

 

An enum would be used to define all the event types. A linked-list would be used for a queue, and each node would be a struct with its head and tail, the event type, and a pointer to a struct with arbitrary data (e.g. a GET_ITEM_EVENT would have the item type, &c.). The programmer could then use a loop that processes each event in the queue. The trouble is, I don't think ZScript has any support for structs. Has anyone been able to make these kinds of data structures with ZScript?

 

This is a probably a lot to take in, so let me discuss what we could do with this sort of thing. There are already tricks to do switch/events in ZC. However, they are, indeed, tricks, and scripting a uniform event system could reduce the amount of crap that needs to be on a screen to make a complex event work. (Such as Link enters a room with a guy, string is displayed, item appears, Link grabs item, enemies appear, Link kills enemies, guy goes North, Link goes North, guy is now in the room to the north. Actually I don't even know if this is possible in ZC, but it's a nice example.) An event system framework made with ZScript could reduce events to only having to set up an FFC, place a scripted combo, &c.

 

So that's what I've been thinking about for the past few days. I haven't started on making any events for my quest (beyond trivial ones) yet, but I have been thinking about what kind of events I'll have and how I might implement them. So now I ask you all, what are your experiences with this sort of thing? Have you done or attempted to do any kind of events in ZC? and how interested would you be in an event system built with scripts? Do you think it's feasible?



#2 anikom15

anikom15

    Dictator

  • Banned
  • Real Name:Westley
  • Location:California, United States

Posted 09 January 2014 - 12:13 PM

svi7dAY.jpg



#3 Saffith

Saffith

    IPv7 user

  • Members

Posted 09 January 2014 - 05:54 PM

ZScript is pretty limited. Structs can be faked well enough for most purposes, but there's no way to set up a callback, no way to call another script's OnEvent function, or anything like that. You could make an event system somewhat similar to SDL/PyGame, but I'm not sure how useful it'd really be.

Globally:
float eventData[1024];
int eventDataPtr; // Used in storing event data
int currentEventPtr; // Used in processing events

const int EVT_END = 0; // Indicates there are no more events
const int EVT_GETITEM = 1;

const int ED_GETITEM_ITEMID = 2; // ED = event data
const int ED_SIZEOF_GETITEM = 3; // Total size of event ID and data, including the size itself

// Called by the global script just before Waitdraw()
int ClearEvents()
{
    eventData[0]=EVT_END;
    eventDataPtr=0;
}

void AddEventGetItem(int itemID)
{
    eventData[eventDataPtr]=EVT_GETITEM;
    eventData[eventDataPtr+1]=ED_SIZEOF_GETITEM; // Store the size just after the event ID
    eventData[eventDataPtr+ED_GETITEM_ITEMID]=itemID;
    eventData[eventDataPtr+ED_SIZEOF_GETITEM]=EVT_END;
    eventData+=ED_SIZEOF_GETITEM;
}

int GetCurrentEventType()
{
    return eventData[currentEventPtr];
}

float GetCurrentEventData(int what)
{
    return eventData[currentEventPtr+what];
}

void StartEventProcessing()
{
    currentEventPtr=-1;
}

bool PollEvent()
{
    if(currentEventPtr<0)
        currentEventPtr=0;
    else
        currentEventPtr+=eventData[currentEventPtr+1]; // Increment by event size
    
    return (eventData[currentEventPtr]!=EVT_END);
}
And in any script interested in handling events:
void ProcessEvents()
{
    StartEventProcessing();
    while(PollEvent())
    {
        if(GetCurrentEventType()==EVT_GETITEM)
            OnGetItem();
    }
}

void OnGetItem()
{
    DoWhatever(GetCurrentEventData(ED_GETITEM_ITEMID));
}
If you want events to persist until they're handled, that's uglier, but not much harder. You'd have to either shift everything in the array after one is removed or allow it to have some empty areas.

The hard part is knowing when to add an event. The only reliable way to know if Link has picked up an item is with a pickup script, and even then there are ways of getting items that won't trigger the script (like string control codes).

#4 anikom15

anikom15

    Dictator

  • Banned
  • Real Name:Westley
  • Location:California, United States

Posted 16 January 2014 - 12:53 AM

You know, that's a lot smaller than I expected it to be, and I'll probably end up using it to. Thanks.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users