Talek says, "All right. Synchronization in MUSH-coded games."

Talek says, "I had hoped to have a working MUSHcoded game as an example and prop for tonight's lecture, but events (and laziness) conspired against me, and I only got my game of hearts about half done, this morning. What I have of it is on object #2944, which you are free to examine. However, so I'll press on without them."

Talek says, "What I'm talking about tonight isn't really new or innovative; it's just a summary of the things I've seen done to implement games, and the methods I've used when implementing games of my own. I don't take particular credit for any of the ideas here... they're not mine, I probably stole them from someone else who implemented it before me."

Talek says, "There seem to be three basic models of player synchronization in games on MUSH: fixed-interval timeslicing, everyone together, and one-at-a-time. In fixed-interval timeslicing, a timer is started, players have a certain amount of time to decide on their moves, and when that timer expires, everybody actually makes their moves, and the timer is reset. Everyone together is a variation of this, where if everybody decides early, the move happens early. In one-at-a-time, each player is asked in turn for their decision, and that decision is implemented immediately, before moving on to the next player."

Talek says, "Fixed-interval timeslicing is the easiest of these. At the start of the game, all the players are given status attributes indicating a default choice of what to do, and a timer is started. The players can use commands to set their status attributes indicating their decision. If the players change their minds before the time limit, then they just use the commands again, to change their recorded decisions. When the timer expires, all the status attributes are checked, the decisions implemented, the attibutes get reset to default positions, and the timer starts over."

Talek says, "'Everyone together' is a close relative of fixed-interval timeslicing. The key differences are that there doesn't have to be a timer, and the decisions get executed as soon as every player has made a choice. Because everybody has to make a choice, the default action is replaced with 'hasn't chosen yet'. Implementation-wise, the timer action is replaced with a check at the end of any decision-making player command which checks to see if anyone is left, and if not, implements the decisions, et al."

Talek says, "'One-at-a-time' adds the complexity of cycling through the different players individually. When a player makes a decision, the check is not to see if everyone has made a decision, but instead if that player was the one under scrutiny right now. Instead of implementing all decisions, you just implement the one decision just made, reset that one player back to 'hasn't chosen', and advance to the next player in line. If you're implementing a system where the players can choose before it's their turn, it also needs to immediately check after implementing one players decision to see if the next player's decision can be implemented immediately, too."

Talek says, "Common to all these models are questions of good interface design. I like to leave the timers in for the everyone together and one-at-a-time models, even though they aren't strictly necessary... the timers keep players who leave in the middle of a game from holding up everyone else. I also like to give players the ability to make choices while waiting for other players, so that the gameplay goes faster. It's also good to have a way for the players to see who the game is waiting on, so that if a player gets distracted, he can figure out what's going on, and so the others can nag him into making a move. ;-)"

Talek says, "In terms of MUSH code, the timers are (as you probably expected) implented with @wait. In fixed-timeslice games, a standard timed @wait is sufficient, but in the others (where the time may be cut short by the players making choices), semaphores are required, so you can @drain stuff out of the queue. This means that for PennMUSH (which only has semaphores based on objects), you have to have a separate object for each concurrent game, which can get to be a bit of a bookkeeping hassle. TinyMUSH and TinyMUX allow semaphores based on attributes, which means you don't require a proliferation of objects."

Talek says, "The implementation of decision execution also has a few implications, too. In general, it's convenient to put it on a separate attribute from everything else, so that it can be called from many places, or looped easily. Calling from different places is common in everybody together and one-at-a-time (it gets called from each of the decision-making commands), and looping is common in fixed-interval (where you're just restarting the timer to call the attribute) and one-at-a-time (which needs to loop to check for players deciding in advance)."

Talek says, "The disadvantage to doing the decision implementation on a different attr is that it incurs a queue delay when you @tigger it, which may cause timing problems."

Talek says, "As I said at the beginning, I had hoped to use an implementation of hearts (a trick-based card game) as an example of these models. The two models in the game of hearts are everyone together (for the card passing, immediately after the deal), and the one-at-a-time (for laying down the cards in the tricks). Unfortunately, the code took too long to write, so you can't play the game here."

Talek says, "That's all I knew I wanted to say, so I guess I'll throw it open to Q/A now."

Talek says, "Fulcrum?"

Fulcrum says, "You mentioned interface design... how would you suggest implementation of a combat system that allows for RP to occur? Longer turns?"

Talek nods. "Definitely longer turns, or a system without a timer."

Fulcrum says, "Would you award points for RP?"

Talek says, "Timers are the bane of true roleplay, because you might want to focus in on some detail that the combat system doesn't know about."

Talek says, "Awarding points for RP is very tricky to do without a judge, so I wouldn't (since I don't want to wander around judging all the time)."

Kamui says, "How would one deal with such a problem as net lag and sudden disconnects? Timer system seems unfair in cases where lag is frequent, but everyone at once system poses problems for disconnects people don't recover from."

Talek says, "That's a really hard question. I try to set it up with fairly long timers, and also make it so the actions if you do get lagged out won't kill you."

Talek says, "Possibly implement a simple AI to take over for the player when they get lagged out."

Kamui nods..

Talek says, "Or, as several people mention, defensive stances in combat."

AdamDray mentions something at invitation by Talek, "I've planned a fourth synch method for my combat systems: Implement a virtual timer. It moves ahead 1 or more 'ticks' when you ask it to. A combat starts at tick 0. Since different players may react at different speeds, you just move ahead to the next tick where action occurs. It might be at ticks 5,6,8,12,20. The turns are not guaranteed to be one at a time, but could be if the players had equal reaction timing." He goes back to being quiet.

Talek thanks AdamDray. :-)

Raevnos says, "Are there any plans for PennMUSH to have the TinyMUSH style of semaphores that you mentioned?"

Talek says, "We've thought about implementing that style of semaphore, but there's a namespace problem."

Talek says, "In Penn, you can have attrs which begin with a digit, unlike Tiny... which means that we can't tell the difference between @wait <obj>/<time> and @wait <obj>/<all-numeric-attr>

Talek says, "Last question..."

Alierak says, "Aside from the lack of portability, do you think that the object stack in TinyMUX could be useful for synchronization, like a semaphore with limited trigger count but more stored information?"

Talek says, "To be perfectly honest, I have never looked at the object stack, so I don't know."

Talek says, "Okay, folks, thanks for coming!"

Talek says, "Many of the presenters will be available in the lobby for further question, and feel free to mill about."

Fulcrum claps.

Alierak claps

Malachi claps.

Kamui claps too.