New object
$g.group - Parent object of all groups, new groups are children
of this group.
The group object number is sent to graphical clients in the case
that people can be in multiple groups at one time.
Verbs:
(*) Do we want these to return ints to allow for error messages?
Or do the verbs themselves emit errors? (May want to do both)
void
send_goal_orderings(OBJ explorer)
Call: |
$g.group:send_goal_orderings(OBJ
explorer) (I) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
explorer - display the goals this player can have |
Function: |
Sends the potential modules that a group can do. Function is
called by the graphical client to get modules for addition into
a list. Now calls $g.group_modules which performs all group goal tasks. |
Client Message: |
Determined by objects in $g.group_modules |
History Entry: |
None |
Notes: |
|
OBJ create(OBJ
leader) (I)
Call: |
$g.group:create(OBJ leader) |
Called By: |
$g.game_player:group,
$g.computer_selected_group_im_goal:start_goal (#1742 on Oit) |
Return Value: |
Object number of the group that was created |
Args: |
OBJ leader - player that will become the leader |
Function: |
Makes child of $g.group with leader as the only
member. Sets leader as the new leader. Move the new group object to
$g.group_room. |
Client Message: |
Sends this:status(explorer) message |
History Entry: |
{timestamp, "created
group", leader, {}, group_name} |
Notes: |
(*) Makes them a leader? (**) Yes
(*) How would a professor create a group? (**) Create group with player
set different from current player to create group like that. (**) Don't
know if this is necessary. If the professor wants to create a group,
ask the students to do so. Or create one themselves and add people
(*) How does it set a group goal? (**) Players select the first
goal they wish (**) Teachers should be able to set initial player goals if
they want (They can, using assign_goal)
|
OBJ
create_group_object(OBJ leader)
Call: |
$g.group:create_group_object(OBJ
leader) |
Called By: |
this.group:create |
Return Value: |
Object number of the created group object |
Args: |
OBJ leader - player that created the group, used so that
group objects can be organized into classes |
Function: |
Internal function that actually creates a new group
object, and, if necessary, its parent. (Groups are sorted by class) |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void invite(OBJ
explorer)
Call: |
$g.group:invite(OBJ explorer) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
OBJ explorer - player to invite |
Function: |
Send an invitation message to explorer if they haven't
recently declined |
Client Message: |
#GROUP|group_obj_num|declining
join|explorer.name|seconds left before can invite again =>
leader if invited to recently
#GROUP|group_obj_num|request
join|leader.name|group.name =>
explorer otherwise
|
History Entry: |
None |
Notes: |
|
int
are_declining_for(OBJ explorer)
Call: |
$g.group:are_declining_for(OBJ explorer) |
Called By: |
this.group:invite |
Return Value: |
Number of seconds before this person can be
invited to a group again (because they have declined before) (Ex: You can
only invite a person once every 30 seconds (change duration in
$g.group:decline_join)) |
Args: |
OBJ explorer - player to check |
Function: |
Internal function that returns how long before someone can
ask explorer to join this group. |
Client Message: |
None (performed in this.group:invite) |
History Entry: |
None |
Notes: |
|
int
decline_join(OBJ explorer)
Call: |
$g.group:decline_join(OBJ explorer) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
OBJ explorer - player that is declining |
Function: |
Sends a message to the leader, saying explorer has
declined to join and add them to a list so they aren't bothered for a
bit |
Client Message: |
#GROUP|group_obj_num|declining join|explorer.name|30 => leader
|
History Entry: |
None |
Notes: |
|
void
invoke_follow(OBJ mover, OBJ invoked_exit)
Call: |
$g.group:invoke_follow(OBJ mover, OBJ
invoked_exit) |
Called By: |
$g.game_exit:invoke |
Return Value: |
None |
Args: |
OBJ mover - The player who's moving
OBJ invoked_exit - The exit their moving through |
Function: |
Function that is called when someone goes through
an exit. It moves people who should be following them through the
exit as well. |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void
is_following()
Call: |
$g.group:is_following() |
Called By: |
$g.group:invoke_follow |
Return Value: |
list of people who are following the leader
in this group |
Args: |
None |
Function: |
Returns whoever is following, so they can be moved
as well |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void
change_permissions(OBJ explorer, list permissions)
Call: |
$g.group:change_permissions(OBJ
explorer, list permissions) |
Called By: |
this.group:set_leader |
Return Value: |
None |
Args: |
OBJ explorer - who's permissions to change
list permissions - what to change their permissions
to |
Function: |
Internal function that changes the permissions of a
group member (usually used to transfer leadership permissions) |
Client Message: |
None (performed in this.group:set_leader) |
History Entry: |
None |
Notes: |
|
STR
member_permissions(OBJ explorer)
Call: |
$g.group:member_permissions(OBJ
explorer) |
Called By: |
this.group:status |
Return Value: |
Comma delimited string of explorer's
permissions in this group |
Args: |
OBJ explorer - whose permissions to retrieve |
Function: |
Converts the permission list from member_info into
a string |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void
choose_module(STR goal_name)
Call: |
$g.group:choose_module(STR goal_name) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
STR goal_name - Name of the goal the user has selected
in the client |
Function: |
Changes the STR goal_name sent by the client into an OBJ
module, then calls assign_goal to set the group goal |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void assign_goal(OBJ
module)
Call: |
$g.group:assign_goal(OBJ module) |
Called By: |
group_goal:complete_goal, group:choose_module |
Return Value: |
None |
Args: |
OBJ module - module the group is working on, assigns
the group the next goal in the module they can do |
Function: |
Sets the group goal to the next available goal in
module |
Client Message: |
If group finished module ==
#GROUP|group_obj_num|finished
goal Calls group_goal:send_goal_directive to send the goal
information to everyone in the group |
History Entry: |
{timestamp, "set goal", leader,
{group_members}, new_goal, activity}
|
Notes: |
|
void confunc(OBJ
explorer)
Call: |
$g.group:confunc(OBJ explorer) |
Called By: |
$g.game_player:confunc |
Return Value: |
None |
Args: |
OBJ explorer - player that is connecting |
Function: |
Performs initialization of the client for connecting
group members. Send initial status message, group goal connection
information, a message to group members that explorer has connected, a
message if they have unread bulletin board messages and send group
options |
Client Message: |
#GROUP|group_obj_num|say|explorer.name has
connected. => group:members()
#GROUP|group_obj_num|say|unread notes
message => explorer that has unread notes
#OPTION|can create groups => explorer that
can create groups |
History Entry: |
None |
Notes: |
|
void disfunc(OBJ
explorer)
Call: |
$g.group:disfunc(OBJ explorer) |
Called By: |
$g.game_player:disfunc |
Return Value: |
None |
Args: |
OBJ explorer - player that is leaving |
Function: |
Send a message to the group that a player is leaving,
and perform any goal functions that should be done on disconnection |
Client Message: |
#GROUP|group obj
num|say|explorer.name has left => all other group members |
History Entry: |
None |
Notes: |
|
void add_member(OBJ
explorer) (I)
Call: |
$g.group:add_member(OBJ explorer) |
Called By: |
$g.game_player:group |
Return Value: |
0 if add was successful
-1 if explorer is not a player |
Args: |
OBJ explorer - player that will be added |
Function: |
Adds a person to the members list. |
Client Message: |
#GROUP|group obj num|add|member
name|role|following|can_remove|can_set_leader =>
$g.group:members() Note: can_remove and can_set_leader is
either 1 or 0 indicating whether the person reciving the directive
can remove the player or set him/her as the leader |
History Entry: |
{timestamp, "added member", leader,
{list of members *before* adding the new member}, member_to_add} |
Notes: |
|
void remove_member(OBJ
explorer)
Call: |
group:remove_member(OBJ explorer) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
OBJ explorer - player that will be removed |
Function: |
Remove a person from the members list. Calls disband if
this is the last person in the group |
Client Message: |
#GROUP|group obj num|remove|member
name => All group members |
History Entry: |
{timestamp,
"removed member",
leader, {list of members *before* removing the member}, member_to_remove} |
Notes: |
|
int follow(OBJ explorer)
(I)
Call: |
group:follow(OBJ explorer) |
Called By: |
$g.game_player:group |
Return Value: |
0 if successful
-1 if explorer is not a player
-2 if explorer is not in the group |
Args: |
OBJ explorer - player that is changing their follow
status |
Function: |
Changes explorer's follow status |
Client Message: |
#GROUP|group obj
num|toggle follow|name => All group members |
History Entry: |
{timestamp, "started
following", explorer, group:members(), explorer} if player
starts following
{timestamp, "stopped
following", explorer, group:members(), explorer} if player
stops following
|
Notes: |
|
void set_name(STR name)
(I)
Call: |
group:set_name(STR name) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
STR name - name to change the group name to |
Function: |
Set a group's name to name |
Client Message: |
#GROUP|group obj num|set name|name
=> All group members |
History Entry: |
{timestamp, "set name
to", leader,
{members in group}, "name"} |
Notes: |
|
void say(OBJ explorer, STR
group_msg)
(I)
Call: |
group:say(OBJ explorer, STR group_msg) |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
OBJ explorer - player that is actually saying
group_msg
STR group_msg - message that will be sent to all players
in group that are online |
Function: |
Sends group_msg to all group members that are online |
Client Message: |
#GROUP|group_obj_num|say|explorer.name
: group_msg => All group members but explorer - If someone is
online to
hear explorer
#GROUP|group_obj_num|say|No one is connected
message => explorer - If explorer is only group member that is
online |
History Entry: |
{timestamp, "said",
explorer, {members in group (and online to receive the message)
at the time}, "group_msg"} |
Notes: |
|
void status(OBJ
explorer)
Call: |
group:status(OBJ explorer) |
Called By: |
$g.group:confunc, $g.group:add_member, $g.group:create
|
Return Value: |
None |
Args: |
OBJ explorer - player to send the status message to |
Function: |
Returns group status |
Client Message: |
#GROUP|group obj num|status|
group.name|current goal name|current goal description|current goal
activity|current group bulletin board|group permissions for
explorer|number of players in the group|player 1 name|player 1 role|player
1 score|if player 1 is following|player 2 name|player 2
role|player 2 score|if player 2 is following => explorer |
History Entry: |
None |
Notes: |
|
void disband()
Call: |
group:disband() |
Called By: |
$g.game_player:group, group:remove_member |
Return Value: |
None |
Args: |
None |
Function: |
Takes everyone out of the group. |
Client Message: |
#GROUP|group obj num|remove|member name
=> all group members about each member removed
(Number of messages == members * members) |
History Entry: |
{timestamp,
"disbanded group", leader, {members in group at time}, ""} |
Notes: |
|
void get_activity()
Call: |
group:get_activity() |
Called By: |
Various - check $g:verb_grep |
Return Value: |
None |
Args: |
None |
Function: |
Accessor function to retrieve the current group
activity |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
list members() (I)
Call: |
this:members() |
Called By: |
All group functions |
Return Value: |
List of object numbers of all players in the group |
Args: |
None |
Function: |
Returns a list of what members are in the group from the super-list member_info |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
list search(OBJ
explorer, int online, int in_class, int in_room, int same_goal, int
not_in_group ) (I)
Call: |
group:search(OBJ explorer, int online,
int in_class, int in_room, int same_goal, int not_in_group) |
Called By: |
$g.game_player:group |
Return Value: |
List of player names that match the given search
criteria |
Args: |
explorer = player that is doing the searching
Note: For all int arguments, -1 means that particular search term doesn't
matter
int online = 1 - search for players that are online, 0 - search for
players that are offline
int in_class = 1 - search for players in explorer's class, 0 - search for
players that are not in explorer's class
int in_room = 1 - search for players in explorer's room, 0 - search for
players not in explorer's room
int same_goal = 1 - search for players with the same goal as explorer, 0
- search for players without the same goal as explrer
int not_in_group = 1 - search for players not in a group, 0 - search for
players in a group |
Function: |
Search through game players to determine if they match a
certain set of option criteria specified by the explorer, return a
list of player names that match those criteria |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
list search_by_name(STR
player_to_search_for) (I)
Call: |
group:search_by_name(STR
player_to_search_for) |
Called By: |
$g.game_player:group |
Return Value: |
List of player names that match player_to_search_by |
Args: |
player_to_search_by - String to search for |
Function: |
Searches for a player by name |
Client Message: |
None |
History Entry: |
None |
Notes: |
|
void
send_directive_to_group(STR directive, list players_to_ignore) (I)
Call: |
group:send_directive_to_group(STR directive,
list players_to_ignore) |
Called By: |
Various |
Return Value: |
None |
Args: |
directive - directive to send
players_to_ignore - player to not send the directive
to |
Function: |
Sends a directive to group members |
Client Message: |
directive =>
group:members() - players_to_ignore |
History Entry: |
None |
Notes: |
|
void set_leader(OBJ
leader) (I)
Call: |
group:set_leader(OBJ leader) |
Called By: |
this:remove_member and $g.game_player:group |
Return Value: |
0 - successful
-1 - leader is not a player
-2 - leader is not in the group |
Args: |
leader = player that will become the new leader |
Function: |
Sets the leader of the group |
Client Message: |
None (Calls this:status to display new leader) |
History Entry: |
{timestamp, "set leader
to", old leader obj num, {members in group}, leader obj num} |
Notes: |
(*) This may be a security hazard.
A simple say in a text window will allow a player to set him
or herself as the leader of the group. (say #GROUP|group obj
number|new leader|my name) or does the # need to be the first
letter? notify() is a programmer only verb, if that is that case,
and not a security hazard. |
void read_note(OBJ note_reader, int note_number)
Call: |
player.group_member.group[n]:read_note() |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
note_reader - player reading the note
note_number - index number of the note to read |
Function: |
Given a note index number, give the text of the note to note_reader |
Client Message: |
#GROUP|group obj num|read note|(int note number)|(string note text)
|
History Entry: |
None (*) |
Notes: |
|
void write_note(OBJ note_writer, STR
note_subject, STR note_text)
Call: |
player.group_member.group[n]:write_note() |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
note_writer = person that wrote the note
note_subject = subject of the note to add
note_text = text of the note to add
|
Function: |
Add note to list notes, send directive to all connected players that notes have been updated |
Client Message: |
#GROUP|group obj num|new note|(int note number)|(string player string)|(string note text)
|
History Entry: |
Into list notes - {timestamp,
note_writer, note_subject, note_text} |
Notes: |
|
void display_note_headers(OBJ explorer)
Call: |
player.group_member.group[n]:display_note_headers() |
Called By: |
$g.game_player:group |
Return Value: |
None |
Args: |
explorer - player to send the note headers to |
Function: |
Output all note headers (Ex: For text players, do this when asked, for graphical, do this on connect |
Client Message: |
#GROUP|group obj num|new note|(int
note number)|(string time_string)|(string player string)|(string
note subject) => explorer |
History Entry: |
None (*) |
Notes: |
|
Properties:
list history (I) - List
of tuples
{ timestamp, action, group member performing
action, {members in group}, result of action }
str name (I) - String
containing the group's name
list
module_search_order (I) - Ordering of group goals -- Not presently used
OBJ goal (I) -
current goal of the group
OBJ leader (I) -
current leader of the group
list member_info
(I) - current members information of the group Presently a
list of 3-tuples defined as {member_object_number,
member_is_following, member_permissions}
(*) This list could contain a variety of information about
individuals in a group, including role, score, and permissions
int search_limit -
Maximum number of results to return from the search() function shown above
OBJ bulletin_board - bulletin
board associated with this group (used to store offline messages)
list declined_join - List of
2-tuples of players who have declined to join. Form: {player_obj_num,
time_they_declined}
int uses_bulletin_boards -
indicates whether this class actually uses bulletin boards or not (may be useful
in future experiments)
OBJ activity - Activity that
the group is presently doing. Right now it is used to store the server-side
information about a map the group is drawing on
New Verb
Both client and text players can
call these verbs to activate their functionality
(*) Must be able to pick which group you wish to change
$g.game_player:group any none none rxd
create - Call $g.group:create_group()
add
(OBJ player) - Call player.group_member.group:add_member(player)
remove (OBJ player) - Call player.group_member.group:remove_member(player)
name (STR name) - Call player.group_member.group:set_name(name)
follow - Call player.group_member:toggle_follow()
say (STR group_msg) - Call player.group_member.group:group_say(group_msg)
status - Call player.group_member.group:group_status()
disband - Call player.group_member.group:disband()
leader (OBJ new_leader) - Call
player.group_member.group:set_leader(new_leader)
note read (int note_number) -
Call player.group_member:group:read_note(note_number)
note write(STR note_subject, STR note_text)
- Call player.group_member:group:write_note(note_subject, note_text)
note show()
- Call player.group_member:group:display_note_headers()
|
More Notes
(*) Still needs some work on the group creation process. How is a
group assigned a goal?
(*) Group goals must have minimum number of group members, maximum
number of group members, number and role of each group member, name
of
goal, ordering of goals into modules... (Other?) (**) Added information
for number of group members needed to group_status and set_goal (*)
Rather than having it in group_status, could poll the goal for this
information?
(*) Is group information stored over logins?
(**) Yes. If you want to leave a group, you must manual leave
it, or have the group disbanded.
(*) Can you be in more than one group? (group_member.group needs to
be a list, rather than a single object number, also need to be able
to select what group you are talking about in $g.group verbs)
(*) Do we need a group module object to remain separate from individual
player goals? Are these necessarily mutually exclusive? (Ex: Can
an individual goal be a group goal?) (**) I think yes, if you want
an
individual
goal to be
a member of a particular group using a particular
goal/role
combination, just make is_completed
check a person's group_member role history
(*) Can advertise that a player is looking for a group. Tutor can
joing players who are physically distant.
(*) Needs to be exportable to other MOOs (**) See hooks above for
what needs to be modified in MOOs this gets ported to
(*) How are team and individual goals different?
(*) Are goals chosen by player, assigned by program, or selected by
professor?
(*) Do we want leader paradigm? A potential option is for any number
or none to be leader (if professor is leader)
(*)
Professor can create mandatory groups?
(either manual selection or random selection)
(*) Split points evenly? Set by leader? Set by programmer? Professor?
Embedded in goal?
(*) What goals can we even have?
(*) Should we separate the note interface from the group interface?
|
Role Notes
I think roles should be objects. Each role would
have a list of actions that that particular role would gain points
for,
if
the person
does something
in
that list of actions, they get a certain
number of
points for being in the group.
One could make roles be children of goals. (Goals
that are part of
the module are enumerated in module_search_order.
A new property called roles would
need to be added to group modules)
We will also eventually need a tool that will allow a person to set up how they
want groups and goals to be set up and created for
a particular class.
|
|