Guildsystem: Difference between revisions
Line 94: | Line 94: | ||
== 6 the persistence == | == 6 the persistence == | ||
To avoid that guilds data, such as their names stored in '''guildnames''', vanish when the game or is restarted we must save on disk these information. | |||
To do this, in the procedure which actually represents the guilds application: '''doGuildOperation()''' - you will find it inside '''underworld.dxw'''- we use the following: | |||
saveSetting "ctx_guildnames",guildnames | |||
This saveSetting saves the whole set guildnames in a setting related to the game's context, which we will load back once the game is restarted. Please not that in the local '''onStart''' event we have got: | |||
Call LoadContext() ' Reads game saved status from disk | |||
Which is a call to a single function which is designed to load, at the game start, these context values with a number of '''getSetting'''. These will reconstruct the exact guilds situation as it was before game restart. | |||
It is interesting to notice that '''saveSetting''' with the guilds data is performed only when necessary, that is when a guild operation is performed. The saveSetting is not performed a regular intervals in time. This is because '''saveSetting''' is a slow operation and causes performance degradation in the game, which is what we want to avoid. | |||
== 7 the guilds application == | == 7 the guilds application == |
Revision as of 03:59, 10 February 2006
How the guild system works - game: Underworld
The guilds system is a small application within the Underworld game, built thanks to two features of DimensioneX: the support for SET objects and the SaveSetting/LoadSetting instructions.
This article refers to version 6.9.5 of [Underworld], and to DimensioneX version 6.1.0.
If you have other versions of the software you could meet some inaccuracies. Being this article hosted on a WIKI site, you can correct errors by using the EDIT tab or eave comments by using the DISCUSSION tab.
Good reading.
This article has been translated from Italian by using Google and it is now being corrected by hand. The translation is still in progress so if you find some errors in sections below please come back tomorrow
1 the guilds room
Everything starts from a room ( guildroom ), that is where the application runs mostly.
I have created this special room (tower the south-west) and a specific character ( Lord Guilford ) who has the purpose to dispatch to the user a message in case he/she does something wrong.
ROOM guildroom NAME Southwest room DESCRIPTION This the room of the guards' captain. He knows about all existing Guilds. IMAGE S armoroom2.jpg PANEL pguilds
In this room we will manage the guilds, that's why in the definition of the room I have specified that it uses a special panel "pguilds" about which we will speak now
2 the panel
To make it possible to manage guilds, I have created an appropriate set of commands.
I defined a new panel of commands, pguilds , that is defined as follows:
PANEL pguilds VERSION OF default CR CR BUTTON guildcmd, "Do this: ", "Guild action", doGuildOperation DROPDOWN guildop, guildOps, join LABEL "" DROPDOWN guildsel, guildnames, 0
As it stands, it is derived from the default panel. We added two drop-down lists ( DROPDOWN control ). This is a new control that has been introduced in version 6.0.2 of DimensioneX, and it works like this (we see the guildop list first):
3 the drop-down list
The first ID, guildop is the dropdwn itself.
We don't have to worry about this ID until we have to read the player's input.
Second, we find a name of a SET, guildOps. This is fundamental because it should contain all the available choices, that is, all the commands that I am setting up for the users.
4 il set comandi
The guildOps command set could have been defined in the SETS section, but I found it more convenient to create it inside the onStart event, which is called automatically at the game's start. If you go and check it out, you will find out that this event's code is in the file named underworld.dxw:
guildOps = NewSet("0new=Start new guild, 1edt_logo=Change logo, 2edt_web=Change website, 3del=Delete my guild, 4ban=Ban a member, 5-=------(all users)------, join=Join this guild:, leave=Leave this guild:")
A SET is an associative array, and the NewSet function allows me to define it via a simple syntax: Elements are separated by commas and are key=value pairs.
The key is a unique identifier inside the set, I have made some of them starting with a number so to have a well defined ordering. The value is a string which is what the user will actually see in the drop-down list. The key is what I will have to check to discover what the user has chosen.
now, thanks to the DROPDOWN control this SET is automatically turned into a dropdown list.
5 the guilds set
Coming back to the pguilds panel, you see that there is a second drop-down control there. This is because for example, if the user wants to join a guild, he has to choose which one.
So I put a second drop-down, with the guilds' names. Here you see the used SET is called guildnames.
guildnames is a set that contains the guild names. I decided to use as keys the names of the guild founders, since each person can start no more than one guild a time. In this way it gets easy to see, for any given person, if he/she owns a guild.
guildnames is created this way:
guildnames = NewSet()
which is called by the onStart event.
For the sharpest programmers: This instruction can be found in the commons.dxl file in the common_onStart Sub.
This contains all the initialisation code which is common to the several areas of Underworld. The guilds are valid for all areas in fact, while the operations on the guilds are allowed only in the castle area, that is why the initialisations of these sets are done in different places in the code. This however is not of much importance.
The above mentioned instruction creates and empty set.
The guilds application, which we will examine straight away (but we can already say that code lays is in the doGuildOperation() event), simply adds new guild names to the set when the user requests so.
6 the persistence
To avoid that guilds data, such as their names stored in guildnames, vanish when the game or is restarted we must save on disk these information.
To do this, in the procedure which actually represents the guilds application: doGuildOperation() - you will find it inside underworld.dxw- we use the following:
saveSetting "ctx_guildnames",guildnames
This saveSetting saves the whole set guildnames in a setting related to the game's context, which we will load back once the game is restarted. Please not that in the local onStart event we have got:
Call LoadContext() ' Reads game saved status from disk
Which is a call to a single function which is designed to load, at the game start, these context values with a number of getSetting. These will reconstruct the exact guilds situation as it was before game restart.
It is interesting to notice that saveSetting with the guilds data is performed only when necessary, that is when a guild operation is performed. The saveSetting is not performed a regular intervals in time. This is because saveSetting is a slow operation and causes performance degradation in the game, which is what we want to avoid.
7 the guilds application
As I said, the application of the management gilde is in an only procedure that is subdivided for the possible operations. This procedure is the event doGuildOperation() that we find in it_underworld.dxw.
This event comes recalled (to see the panel pguilds ) from the push-button guildcmd . This why - at least in the version of used DimensioneX - enough not to select a commando from the list to curtain why they give to you they come sendes you to the serveur. This can be made single through a push-button, here why I have had it to insert.
Finally we see the code:
EVENT doGuildOperation ' Speak guildOps(input("guildOp")) If input("guildOp") = "0new" If input("txtBox") < > "" If guildnames($AGENT.name) < > null Speak guilford,$AGENT," you have already founded one gilda, to messere." Return End_If If $$AGENT.Esperienza < 14 Speak guilford,$AGENT, "To found a gilda demands greater Experience, getlteman. Returned later." Return End_If Dim s = guildSubscribed($AGENT) If s < > null Speak guilford,$AGENT, "You must leave" + guildnames(s) + ", before." Return End_If SetAdd guildnames, $AGENT.name, input("txtBox") saveSetting "ctx_guildnames", guildnames Else Speak guilford,$AGENT," As it will be called? Scrivetelo, to messere." Return End_If End_If If input("guildOp") = "3del" '... End_If If input("guildOp") = "4 -" Return End_If Call guildroom.onReceive saveSetting "ctx_guildnames", guildnames saveSetting" ctx_guildlogos", guildlogos saveSetting "ctx_guildsubscribers", guildsubscribers saveSetting" ctx_guildwebs", guildwebs saveSetting "ctx_guildkills", guildkills END_EVENT Here we notice as the control to curtain works: the control that calls guildOp me arrives in with from the predefined name that it is called input, that contains all gives sendes to you from the panel commandos to you. The keys of the entirety are the ID of the controls specify to you, and the values are the values immessi - in the case of the curtain, the chosen value.
Always speaking about the curtain, the value that returns to me behind is not the description that the customer has seen, but the code that I have used like key. We go see again section "4" here over for a reference.
8 the management of the set
To this point the management of the gilde is enough simple. To every commando it corresponds an arm of if and a sequence of operations to execute, than they are not granché complex.
Attention but: all they give you relati you to the gilde are in of the SET whose keys are the names of the owners of the gilde.
In this version of DimensioneX (6,0,2) it is not possible to in this way insert a new element in a set:
mioset("nuovachiave") = "new value"
but the SetAdd instruction must be used like is looked at in the source. It can give that to this thing changes in the next versions, but if modified the code you must be remembered some why using the sintassi here over you do not obtain errors but not even no result, and will pass hours to ask to you because it does not work.
After all, the used set from the system gilde is these (found all to them in LoadContext() defined in the rows it_commons.dxl)
guildnames names of the gilde guildlogos loghi of gilde (the URL) guildsubscribers list separated from ";" of the names of the enrolled one for every gilda guildwebs situated web of gilde (the URL) guildkills conteggio of the killings for every gilda This last one, guildkills , comes dawned to every killing and comes saved through saveSetting every 4 minuteren taking advantage of the onTick.
To notice that this modernization makes confidence on the property guild that the customer has to the income, previo control (it is not said that from the last time that you have played the gilda it still exists!) - to see event onNew()
9 Show guilds data
They give you of the gilde are shown through the funzioncina getGuildBox() , defined in it_commons.dxl . To this function enough to say who he is the wished owner of the gilda and if she wants or not to see also the list of the enrolled one with they give you of the killings.
Function getGuildBox(owner, withmembers) Dim txt = "" Dim tmp Dim link1 =" "Dim link0 =" "If guildwebs(owner) < > null link1 =" < To HREF=javascript:top.popupWin(' "+ guildwebs(owner) +" ', -1, -1); > " link0 = "</To >" End_If If guildlogos(owner) < > "" tmp = link1 +" < IMG SRC = "+ guildlogos(owner) +" WIDTH=32 HEIGHT=32 ALIGN=MIDDLE BORDER=0 > "+ link0 End_If txt = txt + tmp +" "+ link1 + guildnames(owner) + link0 founded + " from "+ owner +" "If withmembers txt = txt +"Members: "+ guildsubscribers(owner) txt = txt +"Combatt. won: "+ guildkills(owner) End_If Return txt End_Function Questa funzioncina viene richiamata opportunamente con un bel ciclo ogni volta che si entra nella stanza delle gilde:
EVENT guildroom.onReceive Dim txt="Questa è la stanza del capitano delle guardie. Lui conosce tutte le Gilde." txt = txt + " " Dim i Dim owner For i = 1 To SetLen(guildnames) owner = SetKey(guildnames,i) txt = txt + " " + getGuildBox(owner,true) Next txt = txt + " " guildroom.description = txt END_EVENT cosicché quando entro ho sempre la situazione aggiornata.
Inoltre la funzione è chiamata anche dal comando Info che restituisce informazioni sul giocatore stesso (definita in it_battlesystem.dxl).
Sub doCheckup() Dim item Dim name Dim s,guild s = guildSubscribed($AGENT) If s=null guild = "Gilda: Nessuna." Else guild = getGuildBox(s,false) End_If Print guild
...
Questa prima di tutto tramite la funzione guildSubscribed() va a vedere a quale gilda sei iscritto poi chiama la getGuildBox per stamparne i dati.
La stessa getGuildBox viene usata nell'evento onLook per fornire questa informazione su di te quando uno ti guarda.
10 Conclusions
Il sistema delle gilde è una mini-applicazione costruita dentro Underworld che dimostra efficacemente come usare le seguenti caratteristiche di DimensioneX:
tendine drop-down SET saveSetting/loadSetting in più la cosa è perfettamente compatibile con la struttura multi-area del gioco, quindi può essere applicabile in tutti i contesti. E' fattibile a questo punto aggiungere altri elementi per rendere la gestione più interessante.
In caso di commentie domande, consiglio di postare sul nostro Forum.