Eklentilerde Optimizasyon
Gönderilme zamanı: Pzt Tem 23, 2018 11:10 pm
Hepinize merhaba arkadaşlar. Birçok yazar arkadaşımız eklentilerini kaba taslak yapıyor. Bunun içinde yazarlığa yeni başlamış arkadaşlar çoğunlukla bulunmakta. (Kimse üstüne alınmasın lütfen.) Daha doğrusu kimseden yardım istemediği veya araştırma yapmadığı için kendi bildiği gibi kodluyor. Burada birkaç optimize kodları hakkında anlatım yapacağım. Bu anlatım yabancı siteden alınmıştır.
Orjinalini okuyabilirsiniz; (Çeviri tıpa tıp aynısı değildir, bazıları doğru bazıları kendi eklediklerimdir)
https://wiki.alliedmods.net/Optimizing_ ... Scripting)
Giriş (Kısaltılmıştır) :
Çoğu kişi, yazılan eklenti için şunları varsaymaktadır:
* Önceden derlenmiş eklentileri daha optimize edemeyiz. Onlar zaten optimize edilmiş halde.
* Ayrıntılar, sadece "komut dosyası (sma)" olduğu için önemli değil
Öncelikle bunların hiçbiri doğru değil. Derleyici, aslında opitimize etme konusunda çok zayıftır ve eklentilerinizin hızını
ve verimliliğini birkaç kural göz önünde bulundurarak büyük ölçüde arttırabilirsiniz. Unutmayın ki;
Talimatları en aza indirmek, kod satırlarını en aza indirmekten daha iyidir.
( Yani kod satırı az olan eklentiler, çok olanlardan kesin daha hızlı çalışır diye bir şey yok.)
Derleyici Optimizasyonları :
Bu optimizasyonlar kodunuzun nasıl derleneceğini değiştirmekle ilgilidir. Sözdizimi aynı kalabilse bile,
sadece derleme süresini arttırmakla kalmaz, aynı zamanda eklentinin verimliliğini ve hızını da arttırırsınız.
* Her zaman sonuçları kayıt et :
Aşağıdaki örnek kodu inceleyiniz
Bu, "sonuçlarınızı önbelleğe al" ın hafif bir örneğidir. Derleyici bu şekilde çalışacaktır.
Sorunu fark ettiniz mi? Biz çağrıda get_user_team komutunu gereğinden fazla kez kullandık. Bunu böyle kayıt edebiliriz.
Şimdi derleyici bu şekilde çalışacaktır.
* If yerine switch kullan :
Eğer yapabiliyorsanız, if yerine switch komutunu kullanın. Bunun nedeni, derleyici aynı komutu defalarca kontrol ediyor.
Yukardaki örneği bu şekilde değiştirebiliriz.
Derleyici, case olarak adlandırlan yerleri kontrol edecektir. Derleyici bu şekilde çalışacaktır.
* Dizileri İndexlemeyin :
Eskiden yaygın bir hataydı. Artık o kadar kullanılmıyor fakat bunu da silmek istemedim. Sorun; dizileri yeniden diziye eklerek,
yer tasarrufu yapmaktır. Derleyicide yer tasarrufu yapıp bu şekilde eklentinizi kodlamayınız. Aşağıdaki koda bakalım;
Derleyici bu şekilde çalışacaktır.
Ne olduğunu gördünüz mü? Derleyici indexi (players) önbelleğe almaz. Biz players komutunu defalarca kullandık.
Bu yüzden tekrar tekrar oyuncuları kontrol etti. Bunun yerine bu şekilde kullanmak daha iyi olacaktır;
Derleyici bu şekilde çalışacaktır.
Büyük bir döngüde kodları bu şekilde büyük ölçüde azaltabilirsiniz.
* Küresel vs Yerel (Global vs Local) ve Döngülerdeki Değişkenler :
Bu konuyu kısa bir şekilde, anlayacağınız şekilde anlatacağım. Bazı şu anlık ilk başlayanlar için anlamsız yerleri sildim.
Döngüler içindeki dizileri bildirmekten kaçının. Aşağıdaki örneğe bir bakalım.
Eğer 32 oyuncu varsa, bu döngü aslında bir satırda 32 kez sıfırlanacaktır ve tekrardan yazılacaktır. İyi değil!
Bunu dizenin ilk karakterini sıfırlayarak optimize edebiliriz. Aşağıdaki koda bir bakalım.
Bu komutlar çok fazla çalışma süresi yükünü büyük ölçüde azaltır.
* Statik vs Küresel (Static vs Global) :
new yerine static anahtar kelimesiyle bildirilen bir değişken, bir global yapıda olduğu gibi çalışır.
Yani yalnızca bir kez oluşturulur. Ancak değişken işlevi yereldir; Bu kodun hızını önemli ölçüde geliştirirken okunması daha kolay
olduğu anlamına gelir; Örnek:
NOT: Bir değişken statik olduğunda, işleviniz yinelemeli olarak veya aynı yığın içerisinde birden fazla kez
çağrılıyorsa, statik değişken kullanmamalısınız demektir. Yani değişkeni sadece salisede bir kere çalışan yığınlarda
veya herhangi bir yığında değişmeyen komut olması şartıyla kullanabilirsiniz. Bir örnek vereyim, bu örnekteki gibi kullanmayınız.
Herkesin ismini teker teker algılayacağı için bu değişkende statik değişken kullanmamalıyız.
* Sabit Değişkenler :
Değişken adından önce "const" anahtar sözcüğünü ekleyerek sabit değişkenini bildirebilirsiniz.
Bu, değişkenin değişmesini engeller. Aslında, değişkeni bir değere kilitlediniz.
Ek olarak, sabit değişkenler genellikle daha hızlı ve daha küçük kodla sonuçlanacak şekilde optimize edilir.
* Döngü Karşılaştırmaları (for komutu) :
Yaygın bir hata bu şekilde kullanımdır.
Önceden benzer bir prensip yürütülür: önbellek sonuçları. Derleyici, döngü uzunluğunu, döngüdeki her yinelemede yeniden hesaplar.
Dize orta döngü değiştirilirse, bunun daha kötü etkileri olacaktır. Daha mantıklı bir yöntem.
* Arama Tabloları :
Örnek olarak silah endekslerinin isimlere eleştirildiğini varsayalım.
Amx Mod X içinde get_weapon_name komutu olduğu gerçeğini yok saymak verimsizdir.
Bu sonucu bir tabloda önceden yapabiliriz;
* Yerel Dizeler :
Bir sabit kodlu dizeyi eklentinizde çok kez kullanırsanız çok farklı kez görünecektir (kullanılacaktır).
Örnek;
Bu komut gerçekten zarar vermez iken, eklentinizin boyutunu arttırır.
Benzer olarak, bu aynı sorun var.
Bu karışıklıktan kurtulmanın tek yolu, global değişken kullanmaktır.
Yine, gerekli olmasa da, bu eklentinin boyutunu hafızada ve diskte azaltacaktır. Zaten tanımlar kullanıyorsanız,
bu anahtarı kolay şekilde yapabilirsiniz.
Bunun değişmesini önlemek için, onu sürekli olarak bildirmek isteyebilirsiniz. (const kullanabilirsiniz)
Şimdi mükemmel bir güvenli saklama yöntemi kullanılmış oldu.
Kullanabileceğiniz Daha Hızlı Komutlar :
* Cvar Pointers :
Cvar komutunu pointer ile kullanmak düzinelerce kat daha hızlı olan kritik bir optimizasyondur. Örneğin;
Tüm cvar komutları [set_cvar_string hariç] set_pcvar_* get_pcvar_* komutları ile eşleşir.
get_cvar_pointer veya register_cvar ile cvarları önbelleğe alabilirsiniz.
FormatEX :
format ile formatex komutu neredeyse aynı olarak çalışır. Fakat format komutu, geri kopyalama yeteneğine sahiptir.
Bir kaynak girdisi, çıktısı arabelleği ile aynı ise, formatex kullanılamaz. Örneğin; bunlar geçersiz;
Bu komutlarda format kullanılmalıydı. Geri dönüş olmadığı sürede formatex kullanabilirsiniz. Genellikle format komutundan
daha hızlı çalışır.
FM_Touch (fakemeta.inc) | Ham_Touch (hamsandwich.inc) | register_touch(engine.inc):
Dokunanı algılamak için kullanacağınız komut istisna durumları hariç register_touch olmalıdır.
Diğer komutlardan daha hızlı çalıştığı yabancı forum AMX Mod X Plugin Approver yani eklenti onaylayıcısı tarafından denenmiştir.
[Kaynak:https://forums.alliedmods.net/showthread.php?t=213075]
Örnek kullanım; (oyuncu oyuncuya değerse)
Stock | Bool | Tagsız Komutlar [Hangisini kullanmalıyız?]
Eklentilerde bazen bir komutu veya bir düşünceyi tekrar tekrar kullanabiliyoruz. Bunun için kısayol tarzı bir şey yaptığımız da oluyor.
Peki bunlarda stock mu bool mu yoksa hiçbir tag kullanmayacak mıyız?
Öncelikle hiçbir eklentinizde stock kullanmayın. stock komutu çoğunlukla include yani kütüphanelerde kullanılıyor.
Eklentide kullanılması önerilmiyor.
; [Kaynak : https://forums.alliedmods.net/showpost. ... stcount=13]
Oyuncular glow verme komutunu ele alabiliriz. 4 komutu kullanmak yerine bir komuta bağlayıp, o komutu kullanıyoruz.
Doğru veya yanlış şeklinde geri dönüş almamız gerekmediği için buna bir şey koymamıza gerek yoktur. Eklentide böyle kullanmanız
daha iyi olacaktır.
Burada oyuncunun gömülü olup olmadığını algıladığı için bize bir sonuç verecek ya doğru ya yanlış.
Bunu true false olarak sabitlemek için bool kullanmaniz daha iyi olacaktır. Gömülü ise true, değilse false.
Dosya yazılımı :
Hala yaygın olarak kullanılan bir hatadır. Amx Mod X ısrarla bu komutları kullanmayın demesine rağmen hala kullanılmakta.
read_file, write_file gibi komutlar yerine fopen, fgets, fputs, fclose gibi komutlar kullanılmalıdır.
+
Verdiğim siteden hangi komutun ne işe yaradığını ve nasıl çalıştığını öğrenebilirsiniz. Sorularınızı ve anlamadığınız yerleri sorabilirsiniz.
Umarım yardımcı olabilmişimdir. Sunucular için optimize edilmiş eklentiler yapmanız dileğiyle :)
Site: https://amxx-bg.info/api/
Get_players mi yoksa maxplayers mi? :
Oyuncu çekmek için en iyi yöntem get_players komutudur.
get_maxplayers ile yaptığınız kodlar sunucu 32 olmadığı zaman gereksiz komut kullanır. Bu yüzden tavsiye etmem.
Şu şekilde kullanabilirsiniz.
Orjinalini okuyabilirsiniz; (Çeviri tıpa tıp aynısı değildir, bazıları doğru bazıları kendi eklediklerimdir)
https://wiki.alliedmods.net/Optimizing_ ... Scripting)
Giriş (Kısaltılmıştır) :
Çoğu kişi, yazılan eklenti için şunları varsaymaktadır:
* Önceden derlenmiş eklentileri daha optimize edemeyiz. Onlar zaten optimize edilmiş halde.
* Ayrıntılar, sadece "komut dosyası (sma)" olduğu için önemli değil
Öncelikle bunların hiçbiri doğru değil. Derleyici, aslında opitimize etme konusunda çok zayıftır ve eklentilerinizin hızını
ve verimliliğini birkaç kural göz önünde bulundurarak büyük ölçüde arttırabilirsiniz. Unutmayın ki;
Talimatları en aza indirmek, kod satırlarını en aza indirmekten daha iyidir.
( Yani kod satırı az olan eklentiler, çok olanlardan kesin daha hızlı çalışır diye bir şey yok.)
Derleyici Optimizasyonları :
Bu optimizasyonlar kodunuzun nasıl derleneceğini değiştirmekle ilgilidir. Sözdizimi aynı kalabilse bile,
sadece derleme süresini arttırmakla kalmaz, aynı zamanda eklentinin verimliliğini ve hızını da arttırırsınız.
* Her zaman sonuçları kayıt et :
Aşağıdaki örnek kodu inceleyiniz
Kod: Tümünü seç
if (get_user_team(player) == TEAM_T)
{
//...code
} else if (get_user_team(player) == TEAM_CT) {
//...code
} else if (get_user_team(player) == TEAM_SPECTATOR) {
//...code
}
Kod: Tümünü seç
CALL get_user_team
COMPARE+BRANCH
CALL get_user_team
COMPARE+BRANCH
CALL get_user_team
COMPARE+BRANCH
Kod: Tümünü seç
new team = get_user_team ( player )
if ( team == TEAM_T )
{
//...code
} else ise ( team == TEAM_CT ) {
//...code
} else ise ( team == TEAM_SPECTATOR ) {
//. ..code
}
Kod: Tümünü seç
CALL get_user_team
COMPARE + BRANCH
COMPARE + BRANCH
COMPARE + BRANCH
* If yerine switch kullan :
Eğer yapabiliyorsanız, if yerine switch komutunu kullanın. Bunun nedeni, derleyici aynı komutu defalarca kontrol ediyor.
Yukardaki örneği bu şekilde değiştirebiliriz.
Kod: Tümünü seç
new team = get_user_team(player)
switch (team)
{
case TEAM_T:
//code...
case TEAM_CT:
//code...
case TEAM_SPECTATOR:
//code...
}
Kod: Tümünü seç
CALL get_user_team
COMPARE
COMPARE
COMPARE
* Dizileri İndexlemeyin :
Eskiden yaygın bir hataydı. Artık o kadar kullanılmıyor fakat bunu da silmek istemedim. Sorun; dizileri yeniden diziye eklerek,
yer tasarrufu yapmaktır. Derleyicide yer tasarrufu yapıp bu şekilde eklentinizi kodlamayınız. Aşağıdaki koda bakalım;
Kod: Tümünü seç
new players[32], num, team
get_players(players, num, "h")
for (new i=0; i<num; i++)
{
team = get_user_team(players[i])
set_user_frags(players[i], 0)
}
Kod: Tümünü seç
:LOOP_BEGIN
LOAD i
LOAD players
CALC
LOAD players[i]
CALL get_user_team
LOAD i
LOAD players
CALC
LOAD players[i]
CALL set_user_frags
Bu yüzden tekrar tekrar oyuncuları kontrol etti. Bunun yerine bu şekilde kullanmak daha iyi olacaktır;
Kod: Tümünü seç
new player
for (new i=0; i<num; i++)
{
player = players[i]
team = get_user_team(player)
set_user_frags(player, 0)
}
Kod: Tümünü seç
:LOOP_BEGIN
LOAD i
LOAD players
CALC
LOAD players[i]
STORE player
CALL get_user_team
LOAD player
CALL set_user_frags
* Küresel vs Yerel (Global vs Local) ve Döngülerdeki Değişkenler :
Bu konuyu kısa bir şekilde, anlayacağınız şekilde anlatacağım. Bazı şu anlık ilk başlayanlar için anlamsız yerleri sildim.
Döngüler içindeki dizileri bildirmekten kaçının. Aşağıdaki örneğe bir bakalım.
Kod: Tümünü seç
for (new i=0; i<num; i++)
{
new message[255], name[32], player
player = players[i]
get_user_name(player, name, 31)
format(message, 254, "Hello, %s", name)
}
Bunu dizenin ilk karakterini sıfırlayarak optimize edebiliriz. Aşağıdaki koda bir bakalım.
Kod: Tümünü seç
new message[255], name[32], player
for (new i=0; i<num; i++)
{
player = players[i]
name[0] = '^0'
message[0] = '^0'
get_user_name(player, name, 31)
format(message, 254, "Hello, %s", name)
}
* Statik vs Küresel (Static vs Global) :
new yerine static anahtar kelimesiyle bildirilen bir değişken, bir global yapıda olduğu gibi çalışır.
Yani yalnızca bir kez oluşturulur. Ancak değişken işlevi yereldir; Bu kodun hızını önemli ölçüde geliştirirken okunması daha kolay
olduğu anlamına gelir; Örnek:
Kod: Tümünü seç
stock SomeBigFunction()
{
static gaben[255];
format(gaben, "%L", LANG_SERVER, "STUFF");
}
NOT: Bir değişken statik olduğunda, işleviniz yinelemeli olarak veya aynı yığın içerisinde birden fazla kez
çağrılıyorsa, statik değişken kullanmamalısınız demektir. Yani değişkeni sadece salisede bir kere çalışan yığınlarda
veya herhangi bir yığında değişmeyen komut olması şartıyla kullanabilirsiniz. Bir örnek vereyim, bu örnekteki gibi kullanmayınız.
Kod: Tümünü seç
public PurposeLess_Ornek()
{
static name[32];
new players[32], inum;
static Uid;
get_players(players, inum);
for(new i=0; i<inum; i++)
{
Uid = players[i];
name[0] = '^0';
get_user_name(Uid, name, charsmax(name));
client_print_color(Uid, Uid, "Isminiz: %s", name);
}
}
* Sabit Değişkenler :
Değişken adından önce "const" anahtar sözcüğünü ekleyerek sabit değişkenini bildirebilirsiniz.
Kod: Tümünü seç
new const AMX_GABEN[] = "amx_gaben"
Ek olarak, sabit değişkenler genellikle daha hızlı ve daha küçük kodla sonuçlanacak şekilde optimize edilir.
* Döngü Karşılaştırmaları (for komutu) :
Yaygın bir hata bu şekilde kullanımdır.
Kod: Tümünü seç
new string[256] = "something long"
for (new i=0; i<strlen(string); i++)
//...code
Dize orta döngü değiştirilirse, bunun daha kötü etkileri olacaktır. Daha mantıklı bir yöntem.
Kod: Tümünü seç
new string[256] = "something long"
new len = strlen(string)
for (new i=0; i<len; i++)
//...code
* Arama Tabloları :
Örnek olarak silah endekslerinin isimlere eleştirildiğini varsayalım.
Kod: Tümünü seç
if (weapon == CSW_AK47)
copy(name, len, "weapon_ak47")
Bu sonucu bir tabloda önceden yapabiliriz;
Kod: Tümünü seç
new g_WeaponNamesTable[TOTAL_WEAPONS][] = {
//..0 to CSW_AK47-1
"weapon_ak47",
//..CSW_AK47+1 to TOTAL_WEAPONS-1
};
* Yerel Dizeler :
Bir sabit kodlu dizeyi eklentinizde çok kez kullanırsanız çok farklı kez görünecektir (kullanılacaktır).
Örnek;
Kod: Tümünü seç
set_cvar_num("amx_gaben", get_cvar_num("amx_gaben") + 1)
Benzer olarak, bu aynı sorun var.
Kod: Tümünü seç
#define AMX_GABEN "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
Kod: Tümünü seç
new AMX_GABEN[] = "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
bu anahtarı kolay şekilde yapabilirsiniz.
Bunun değişmesini önlemek için, onu sürekli olarak bildirmek isteyebilirsiniz. (const kullanabilirsiniz)
Kod: Tümünü seç
new const AMX_GABEN[] = "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
Kullanabileceğiniz Daha Hızlı Komutlar :
* Cvar Pointers :
Cvar komutunu pointer ile kullanmak düzinelerce kat daha hızlı olan kritik bir optimizasyondur. Örneğin;
Kod: Tümünü seç
new g_enabled = register_cvar("csdm_enabled", "1")
//OR
new g_enabled = get_cvar_pointer("csdm_enabled")
stock SetCSDM(num)
set_pcvar_num(g_enabled, num)
stock GetCSDM()
return get_pcvar_num(g_enabled)
get_cvar_pointer veya register_cvar ile cvarları önbelleğe alabilirsiniz.
FormatEX :
format ile formatex komutu neredeyse aynı olarak çalışır. Fakat format komutu, geri kopyalama yeteneğine sahiptir.
Bir kaynak girdisi, çıktısı arabelleği ile aynı ise, formatex kullanılamaz. Örneğin; bunlar geçersiz;
Kod: Tümünü seç
new buffer[255]
formatex(buffer, charsmax(buffer), "%s", buffer);
formatex(buffer, charsmax(buffer), buffer);
formatex(buffer, charsmax(buffer), "%d %s", buffer[2]);
daha hızlı çalışır.
FM_Touch (fakemeta.inc) | Ham_Touch (hamsandwich.inc) | register_touch(engine.inc):
Dokunanı algılamak için kullanacağınız komut istisna durumları hariç register_touch olmalıdır.
Diğer komutlardan daha hızlı çalıştığı yabancı forum AMX Mod X Plugin Approver yani eklenti onaylayıcısı tarafından denenmiştir.
[Kaynak:https://forums.alliedmods.net/showthread.php?t=213075]
Örnek kullanım; (oyuncu oyuncuya değerse)
Kod: Tümünü seç
register_touch("player", "player", "touch_player");
public touch_player(touched, toucher)
{
static name[32], name2[32];
get_user_name(touched, name, charsmax(name));
get_user_name(toucher, name2, charsmax(name2));
client_print_color(touched, touched, "%s adli kisi size dokundu", name2);
client_print_color(toucher, toucher, "%s adli kisiye dokundunuz", name);
}
Stock | Bool | Tagsız Komutlar [Hangisini kullanmalıyız?]
Eklentilerde bazen bir komutu veya bir düşünceyi tekrar tekrar kullanabiliyoruz. Bunun için kısayol tarzı bir şey yaptığımız da oluyor.
Peki bunlarda stock mu bool mu yoksa hiçbir tag kullanmayacak mıyız?
Öncelikle hiçbir eklentinizde stock kullanmayın. stock komutu çoğunlukla include yani kütüphanelerde kullanılıyor.
Eklentide kullanılması önerilmiyor.
; [Kaynak : https://forums.alliedmods.net/showpost. ... stcount=13]
Bool ve tagsız komutlar için örneklere bakalım.You shouldn't be using "stock" in the .sma files. This tag is used only if there is a possibility that the function will not be used at all. Since this is your code and you added the function,
you're probably going to use it as well, so remove the "stock" tag. Only use "stock" in include files where not all functions must be used in the code when included.
"bool" is pretty self-explainatory. If the variable is tagged with "bool", then the return value of the function should also be "bool". Bools can be only true or false.
Oyuncular glow verme komutunu ele alabiliriz. 4 komutu kullanmak yerine bir komuta bağlayıp, o komutu kullanıyoruz.
Kod: Tümünü seç
rg_set_user_rendering(index, fx = kRenderFxNone, {Float,_}:color[3] = {0.0,0.0,0.0}, render = kRenderNormal, Float:amount = 0.0)
{
set_entvar(index, var_renderfx, fx);
set_entvar(index, var_rendercolor, color);
set_entvar(index, var_rendermode, render);
set_entvar(index, var_renderamt, amount);
}
daha iyi olacaktır.
Kod: Tümünü seç
bool:is_user_stuck(index)
{
static Float:origin[3];
get_entvar(index, var_origin, origin);
engfunc(EngFunc_TraceHull, origin,origin, IGNORE_MONSTERS, get_entvar(index, var_flags) & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, 0, 0);
return (get_tr2(0, TR_StartSolid)) ? true:false;
}
Bunu true false olarak sabitlemek için bool kullanmaniz daha iyi olacaktır. Gömülü ise true, değilse false.
Dosya yazılımı :
Hala yaygın olarak kullanılan bir hatadır. Amx Mod X ısrarla bu komutları kullanmayın demesine rağmen hala kullanılmakta.
read_file, write_file gibi komutlar yerine fopen, fgets, fputs, fclose gibi komutlar kullanılmalıdır.
+
Verdiğim siteden hangi komutun ne işe yaradığını ve nasıl çalıştığını öğrenebilirsiniz. Sorularınızı ve anlamadığınız yerleri sorabilirsiniz.
Umarım yardımcı olabilmişimdir. Sunucular için optimize edilmiş eklentiler yapmanız dileğiyle :)
Site: https://amxx-bg.info/api/
Get_players mi yoksa maxplayers mi? :
Oyuncu çekmek için en iyi yöntem get_players komutudur.
get_maxplayers ile yaptığınız kodlar sunucu 32 olmadığı zaman gereksiz komut kullanır. Bu yüzden tavsiye etmem.
Şu şekilde kullanabilirsiniz.
Kod: Tümünü seç
new players[32], inum;
static Uid;
get_players(players, inum); // burayi yasayan olu vs gibi editlemeniz gerekebilir.
for(new i=0; i<inum; i++)
{
Uid = players[i];
// yapilacak islemler
}