PDA

View Full Version : Lua question



Bidmaron
April 24th, 2009, 02:59
Does FG2 lua support coroutines?

Goblin-King
April 27th, 2009, 08:31
No. This was looked at and the conclusion was that we'd need a lower level synchronization/event layer for it to be really useful. Also, I couldn't come up with a specific case that could not be implemented without them. Do you have any convincing examples to illustrate their usefulness in the current implementation?

Bidmaron
April 27th, 2009, 13:13
Well, yes, actually. What I am trying to do is to add sound capability to FG2. The best I have been able to come up with involves adding what I call a Monitor module and an event application. The application looks in the campaign folder for the local copy of the module data and detects any changes to that module. There is also an extension that lets the user organize his sound files (like mood, etc). The clients will have to install the sound files on their own computer as well and also have the event application on there computer. Here is how it works:
1) The GM wants to play a sound (either he goes to the sound extension and plays one or he clicks on a hotspot in an adventure entry).
2) The event code for the hotspot modifies a signal field in the Monitor module and then closes the module to update the field. The module file is immediately reopened.
3) The event code sends a message to all clients that will cause their own FG2 programs to execute step #2 locally on their computer.
4) The event application picks up on the module change, reads the signal field to determine which sound to play, and gets ready to play the sound. This happens on all the computers.
5) Each computer event application installs a signal file into the campaign's images directory.
6) The onChildAdded event handler for the image database node (installed at initialization of the Sound extension) detects the addition of the image, and causes all clients to send a ready to play message to the host. (note that the syncrhronization feature will probably be optional at the time the sound is played).
7) Once the host has all clients reporting in, the host uses the Monitor module to send a signal to the event application.
8) The host event application will determine the time delta between the initial signal received and the current signal. This represents the current signal delay on the network to execute a notification cycle to all the clients.
9)The host event application sends a signal graphic file into the campaign images directory, where the filename has the cycle delay time added to the current universal time (this is negotiated at initialization time and is passed to each client when they log on)
10) [this is the part I haven't quite figured out how to do because I don't know how to get the image filename into my code yet so I can parse it] The host FG2 parses the filename to get the start time for the sound. It then puts this in a message and sends it to all clients.
11) Each client and host takes the message time and puts it as a signal into the Monitors module, closes the module (to fire the event application), and reopens the module.
12) Each client and host event application reads the time to start the sound and plays the sound at that time.
13) If the sound is not set to loop, when each client and host event application completes playing the sound, it puts a signal file into the images directory.
14) Each client and host has the onChildAdded event of the image node fired, and this event causes a message to be sent to the host computer.
15) When the host receives the messages from all clients, it notifies the GM that the sound is done. This serves as a backstop so that if some particular user experienced a delay beyond the computed network lag that we used to syncronize the sound above, at least the GM would know that all his users heard the sound, even if it wasn't quite synchronized.

Quite convoluted, and I don't have this all working yet. I have tested individual pieces (I can successfully detect signal files added to the images directory, e.g.).

So, how would coroutines be helpful? Well, part of the ugliness of the above process is because there is no way in FG2 to tell the real-world time that I can figure out. Some kind of mechanism (an onTime event?) would help this kind of thing, but it wouldn't have to be a coroutine.

This would also be easier if there was a way to send a file using FG2. That way, the clients wouldn't have to possess all the sound files to be used. I know Smiteworks would be nervous about the potential to send harmful files over the network, but I would think the mechanism could guard against sending executable files.

Of course, the biggest thing that could be added is a more graceful way to handle interapplication communication....
--Bidmaron--

Foen
April 27th, 2009, 20:08
You can build host/client comms using message passing (The Box and the Notes built in to Labyrinth Lord both do this). BTW, the idea sounds neat, even if you are having to do a ton of legwork to implement it without having the ability to invoke code directly from FG.

Moon Wizard
April 27th, 2009, 21:17
Seems like a pretty complicated workaround. I'm thinking that it might be fragile, without some explicit support from FantasyGrounds itself.

I looked into adding the ability to import characters into a campaign from an XML file previously. The SmiteWorks team stated that they had explicitly disabled local file access for security purposes. Your project seems like it is primarily focused on circumventing that limitation to get access to any given file.

I think the image file approach is very interesting. However, there are several questions I have related to similar ideas I have:
* How are you getting time deltas? (all os functions including time are not available, tried this previously for better debugging)
* What functions are you using to load and play the sound file?
* All of the action in the ruleset seems to be event driven. How are you synchronizing host and client to play at the same time?
* How are you adding signal files to the image directory for the triggers? And how do you clean up?

Thanks,
JPG

Bidmaron
April 27th, 2009, 21:56
Most of my idea revolves around using a background application to detect changes to a shell module to get commands and info from FG2 to the background application. Going the other way, I can already detect the addition of a file to the image directory using built-in onChildAdded event on the image node.
In the extension initialization, I will use this handshaking mechanism to get the system time. I can then inform (through chat special messages) the clients what this official system time is. Synchronization will then rely upon the assumption that, over the course of a game until I choose to renegotiate system time, the drift of any client can only be on the order of microseconds - good enough for what we're doing. So when I go to play a sound (assuming synchronization is important to the sound - it won't always be), the system will measure the time it takes to notify the clients that a sound will be played and get a report-back from all stations. This will be the current system lag. (obtained by handshaking to the background task to get the time before messaging and the time after all clients message that they are ready). While the clients are waiting on the command to play the sound, thebackground task on the client will load the sound file buffer (I hope - I haven't researched open-source or .net sound libraries yet). Knowing this lag, and adding an additional (user-defined in a preference maybe ) fudge factor, the host will command the clients through chat messaging when to start playing the sound. The individual clients then pass this on to their own background applications (who were all notified before what the official time is and stored their own individual time error) as to when to start the sound. This systemshould very closely be able to synchronize the sounds within the amount of variance that it takes each computer's background task to actually initiate playing the sound.

Am I circumventing the system? You bet I am. But I think it's worth it. The down side is that the sound files will have to exist everywhere they might be played, and the background task will have to be running on each computer. But this is what makes it safe in my opinion. The user has to install and start the background task.

Bidmaron
April 27th, 2009, 22:09
How do I clean up? Well, you hit on another weakness of the system. There will always be one signal file in the user's images directory while the system is in use (although I could send a command to the background task to delete the file fairly quickly I guess). If the user had the images window open, he'd see the file appear and dissapear. Since the message will be in the filename and not it's contents, I intend to make the file a text graphic something like 'Sound manager signal file - delete if desired).

The other thing that will be there is the messaging module, and this would have a warning saying that the module must not be opened, closed, or monkeyed with in any way by the user or the sound system would no longer work.
The system would, of course have many other potential uses. (using the FG2 program as a small private forum hosting mechanism just for the players and GM comes to mind, for example).

Moon Wizard
April 29th, 2009, 21:49
So, essentially, it's not passing any information into FG other than what can be passed in the filename? And you are using this mechanism to get the time of the local machine, as well as notify your module of which file to play and when?

Did I understand that right?

Just want to understand how it might apply to the import features I was looking at before.

Cheers,
JPG

Bidmaron
April 30th, 2009, 00:01
Moon_wizard, the filename route isn't working, as I have had no success in getting FG2 to be able to return (with getValue) formattedtext or image nodes. What I am doing instead is returning the information in the module itself. This is no fun because you have to unpack and pack the module folder to get at it. I am using the image file trick however as an event I can trap in FG2 so that I can then go reopen the module and get the information I have placed there. The other flaw I discovered with my plan is that the client version of FG2 cannot edit a module, so the only way to get information to the outside world is to modify a database node, and that is not very timely -- it only saves the file every 15 minutes on the autosave. The other alternative is to pass a message to the host, who can then alter the module and have the host's background task take care of the processing.

The bottom line is that to get the system working, I will have to rely more on the background task. I'll keep you posted as I progress on this.

I have begged the developers to at least fix the bug/feature that won't process image tags, as that is keeping me from getting the pictures on item records from working fully.