<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="http://blogs.nowhere-else.org//styles/rss.css" type="text/css"?>
<rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
  xmlns="http://my.netscape.com/rdf/simple/0.9/"
>

 <channel>
  <title>NEaB Today</title>
  <link>http://garg.blogs.nowhere-else.org</link>
  <description>&lt;p&gt;The official NEaB blog. Where you can read what&#039;s going on.&lt;/p&gt;
</description>
 </channel>
    <item>
   <title>Tales of a space merchant game</title>
   <description>Nebula Rider (official name of the game to come) is progressing slowly. It&#039;s certainly not yet features complete, nor in any shape ready to be beta-tested. However the code size increase and with it the number of features implemented.&lt;br /&gt;&lt;br /&gt;Just to give an idea, the real coding started 12th May, and 16 days later we do have 3800 lines of code which means a good average of 237 lines of code (counting weekends where I don&#039;t actually code).&lt;br /&gt;&lt;br /&gt;Currently the game offers a smooth (on windows at least) experience, with plasma shoot, worm holes, space stations, planets and suns gravity attraction, asteroid fields, sounds and music. The initial stock exchange code is there, and you can buy and sell stuff... however each space station offer the same goods at the same price... which means =&amp;gt; currently not much fun.&lt;br /&gt;&lt;br /&gt;The graphical user interface is also taking shape, and is more and more complete.&lt;br /&gt;&lt;br /&gt;ETA is still in about 2.5 months to really have a beta, so be patient, as much as us at least, and be assured we do our max to bring you a great new game.&lt;br /&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/25215</link>
      <pubDate>Fri, 28 May 2010 07:04:47 -0700</pubDate>   
  </item>
    <item>
   <title>IRC chat finally arrived</title>
   <description>Even if not all is clearly working, the IRC chat is there for all. Sure some stuff need to be improved, or even yet ported to the new IRC chat, however a lot of work has been invested to make it a safe, stable, and friendly chat. From this move we gained the advantage of having an IRC compatible chat, which means any IRC client will do the trick, as well as the possibility to host IRC bots.&lt;br /&gt;&lt;br /&gt;Also this move allows me to use the IRC client I&#039;m working on, and share the workload across multiple projects.&lt;br /&gt;&lt;br /&gt;New features from this move include:&lt;br /&gt;- Infinite number of channels&lt;br /&gt;- Better whisper / private messages handling&lt;br /&gt;- Self written scripts for the chat&lt;br /&gt;- Faster feedback&lt;br /&gt;- Lighter on the server (as well on the network)&lt;br /&gt;- Clan channels&lt;br /&gt;- Channel topics&lt;br /&gt;&lt;br /&gt;Things which are still missing:&lt;br /&gt;- A good player info page&lt;br /&gt;- Some handling for clan channels&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=692d2945-5fbc-8658-af56-195453e0764d&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/20750</link>
      <pubDate>Mon, 01 Mar 2010 22:16:54 -0800</pubDate>   
  </item>
    <item>
   <title>IRC Chat</title>
   <description>Finally after a HUGE amount of work we starts to test the firsts versions of the new IRC chat. Basically the chat is composed by 2 different softwares. A new fresh self written IRC server, which does have quiet different rules than a normal IRC server (that&#039;s the reason of a fresh self written code), and the usage of wsIrc (one of my pet projects) as web IRC client. Now thanks to wsIRC scripting capabilities, some stuff have been tweaked to reflect more how the old chat was working. Like avatars, titles, PH color and more.&lt;br /&gt;&lt;br /&gt;The work is not finished, but well, it&#039;s a good start already, and starts to be used as well. Now the good news is that it seems the new server doesn&#039;t use much server resources, and that could save us a bit more in case the game continues to grow.&lt;br /&gt;&lt;br /&gt;Things will now improve with old features like Glum, shortcuts, word filters etc...&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=0f4470c4-e8bd-83fb-9ce7-22f4df2d9016&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/20270</link>
      <pubDate>Wed, 24 Feb 2010 11:35:42 -0800</pubDate>   
  </item>
    <item>
   <title>PvP is there and some other goodies</title>
   <description>The first part of the PvP battles are in. And it seems to work so far. Yes it&#039;s odd but it works and I can assure you it wasn&#039;t a small thing to make. Now remains to code some scoring system and implement the clan PvP. Seems my todo will never decrease.&lt;br /&gt;&lt;br /&gt;On the &quot;other news&quot; side, some drop downs have been replaced with a good chunk of JavaScript. The goal is to remove those ugly and barely usable drop downs we had with something which allows you to search inside and maybe offers some grouping for example for the items you have with you. Maybe it can be further improved but so far I don&#039;t know how.&lt;br /&gt;&lt;br /&gt;On the map making side, I tried to make the smart draw automatically make the transitions between water and grass (without the need that you make the sand), but epically failed. Yes that happens.&lt;br /&gt;&lt;br /&gt;Finally (for today post), as Croesy had to step down for a while, I had to find some backup as I simply cannot handle all by myself, and found great help in the persons of Kerrik, Jones and Zonneschijn. Many thanks to them to accept this work, as it will certainly help me concentrate more on the development side, and remove a bit of the work load produced by all the admin work.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=bb92e572-f75e-80ae-a9e9-35fe47920383&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/19642</link>
      <pubDate>Mon, 15 Feb 2010 00:38:47 -0800</pubDate>   
  </item>
    <item>
   <title>Map actions are there</title>
   <description>Yes I did it, as promised: map actions are implemented. This opens the door to all kind of odd quests, where a map can change by simply walking somewhere. Or actually you don&#039;t need to even change the map, think about a quest where you need to explore some area, and you just need to go to the end of a tunnel, well with the new function you will be able to track if the player went there, without using a NPC dialog.&lt;br /&gt;&lt;br /&gt;Also, multi player quests are possible, as if you use global variables, map will change in real time for all the players on the map. So think about some quests where you need multiple players standing on different points to unlock a given door. Well all that is now possible.&lt;br /&gt;&lt;br /&gt;On the other side, I should present you another project of mine:&lt;br /&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.wsirc.com&quot;&gt;http://www.wsirc.com&lt;/a&gt; it&#039;s a full featured Web IRC client, which allows you to chat on IRC without the need to install anything. Some of you may know mibbit, well this is actually like mibbit but hopefully even better. Why did I started that? Well for a few reasons:&lt;br /&gt;&lt;br /&gt;1) It&#039;s a fun project.&lt;br /&gt;2) I learned some stuff.&lt;br /&gt;3) I hope it will help to drive money / advert to our beloved game.&lt;br /&gt;&lt;br /&gt;Indeed, even if doesn&#039;t have much to do with NEaB, it could allow us to just make NEaB more visible, as we could advertise it on a completely different service. And if this service does generate some money (not sure), well we could use this money for traditional advertisements. We shall see how it goes.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=efa2f8eb-ae03-81d6-b29d-a58dfdfca674&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/18483</link>
      <pubDate>Fri, 22 Jan 2010 22:47:06 -0800</pubDate>   
  </item>
    <item>
   <title>Improved security on NEaB</title>
   <description>As I described in my last article, there is ways to improve the login security, well guess what? I implemented it inside our game. However it&#039;s not just matter of changing the home page and all would work, sadly NEaB is a tiny bit more complex and I had to dig into a lot of files to replace the old login schema with a new improved function.&lt;br /&gt;&lt;br /&gt;Part of that work has been done last week, and then I waited the new week such that I would be able to debug things during the week. We do now have a more secure login / cookie as we NEVER transfer the password in plain text over the network. Also on the database side we don&#039;t store the password as plain text either, and therefore even if we get some hackers to read the table (which I hope is not possible) they would still not see our passwords. I don&#039;t know the passwords either as the encryption used is called &quot;one way encryption&quot; which means there is no real way to get the data back, beside from a brute force attack.&lt;br /&gt;&lt;br /&gt;As side work, I changed the password recovery tool and to help players to use it, we now allow all users to change their email directly from the option panel.&lt;br /&gt;&lt;br /&gt;On another subject, the battle rework seems to please a vast majority of the players, and even if there was some glitches, and 1 or 2 players unhappy with the move, I still believe it was a good feature change. Let&#039;s hope the next &quot;phases&quot; of this rework will be as good as the previous ones.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=58417459-63c4-850c-829b-14a8e8b49219&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/15838</link>
      <pubDate>Mon, 30 Nov 2009 07:21:52 -0800</pubDate>   
  </item>
    <item>
   <title>A more secure login</title>
   <description>&lt;link rel=&quot;File-List&quot; href=&quot;file:///C:%5CUsers%5CAlain%5CAppData%5CLocal%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt; &lt;w:WordDocument&gt;  &lt;w:View&gt;Normal&lt;/w:View&gt;  &lt;w:Zoom&gt;0&lt;/w:Zoom&gt;  &lt;w:HyphenationZone&gt;21&lt;/w:HyphenationZone&gt;  &lt;w:PunctuationKerning/&gt;  &lt;w:ValidateAgainstSchemas/&gt;  &lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;  &lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;  &lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;  &lt;w:Compatibility&gt;   &lt;w:BreakWrappedTables/&gt;   &lt;w:SnapToGridInCell/&gt;   &lt;w:WrapTextWithPunct/&gt;   &lt;w:UseAsianBreakRules/&gt;   &lt;w:DontGrowAutofit/&gt;  &lt;/w:Compatibility&gt;  &lt;w:BrowserLevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt; &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt; &lt;w:LatentStyles DefLockedState=&quot;false&quot; LatentStyleCount=&quot;156&quot;&gt; &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!-- /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:&quot;&quot;; 	margin:0cm; 	margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:&quot;Times New Roman&quot;;} @page Section1 	{size:595.3pt 841.9pt; 	margin:70.85pt 70.85pt 70.85pt 70.85pt; 	mso-header-margin:35.4pt; 	mso-footer-margin:35.4pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt; /* Style Definitions */ table.MsoNormalTable 	{mso-style-name:&quot;Table Normal&quot;; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:&quot;&quot;; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:&quot;Times New Roman&quot;; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;Once more I will pick a question from a chat discussion as starting point for a little article. The question was how to use SHA256 in JavaScript. Of course you may wonder what SHA256 is, well to make a long story short, it&#039;s a replacement (more secure) version of the well known MD5 &quot;digest&quot; function or hash function. Basically MD5 or SHA256 are functions which take some string and produce a binary short identifier for it. That means, you can in theory have more than one initial string which produce the same identifier, but it practice it&#039;s very unlikely and it is certainly extremely difficult without doing a brute force attack (more on this later) to find a possible string out of those identifiers. Those functions are also called one way cryptography, as it allows you to encrypt something but you cannot normally go back to the original message.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;You know now what those function are, but how useful is it? Well maybe you don&#039;t know it but all the communication between the browsers and the servers are PLAIN TEXT which means anybody between the browser and the server could see the data exchanged without any problem. This is valid for all the GET, POST parameters as well as for the cookies or anything else exchange. The only way to prevent this is to use the HTTPS (S for Secure) protocol instead of the normal HTTP one. However there is a few issue with the HTTPS, first of all it requires a server certificate, and if you don&#039;t purchase one you will force your users to go through some odd browser acknowledgment which basically says: &quot;Yes I agree and understand that this certificate is not valid or unknown&quot;. There is some cheap certificate (look for Go Daddy for example, but normally an SSL certificate is expensive and needs to be re-installed every year. Another problem with HTTPS is that it requires some more CPU on the server as well as on the browser side.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;So if you don&#039;t use HTTPS as most web sites out there, you are in the risk that somebody steal the passwords players or admins use to log in on your site. And here we can use those &quot;digest&quot; functions mentioned above.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;The idea is that you take the password given by your player, encrypt it on the browser side via JavaScript, and then send the encrypted string over the network. The advantage is that if somebody is sniffing your traffic he/she will not be able to read / know the password used. However this is only a first step, as this person could use the exact same encrypted string to be able to log in as well. So the solution is to concatenate the IP of the client as well as the password together and then make the MD5 out of it, on the server, as you cannot decrypt you do the same job take the user password out of the DB, glue it to the browser IP, feed it to the MD5 function and see if it matches with what you got from the player. By doing so, you ensure the same encrypted string cannot be shared along other PC if they use different IP. You could further improve it by using a cookie or some other kind of session identification so that only that browser will be accepted for that session and not all browsers / pc sharing the same IP.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;As this could be somewhat difficult to understand just like that, I prepared you a full script (PHP and JavaScript) to see how things works. The first (and biggest) part of the JavaScript as you will see is taken from internet, so if you use it, please leave the copyright. For the remaining parts you can use it as you want.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;The script:&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://base.nowhere-else.org/tutorials/check_pass.zip&quot;&gt;http://base.nowhere-else.org/tutorials/check_pass.zip&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;&quot; lang=&quot;EN-GB&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=2a184406-ecda-8ecc-809e-49ceee790f27&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/15619</link>
      <pubDate>Wed, 25 Nov 2009 12:12:33 -0800</pubDate>   
  </item>
    <item>
   <title>A little bit more SQL complexity</title>
   <description>While chatting with some of the well known moders in &lt;a target=&quot;_blank&quot; href=&quot;http://www.makewebgames.com/&quot;&gt;MakeWebGames &lt;/a&gt;forums and chat, I discovered that even if all have some knowledge of SQL (as it is required to be able to store and retrieve all the information in a standard web site setup), most fails when we go to something yet a bit more special, like, using sub-queries, join or grouping functions. This couple of articles will be toward this group of people which could gain something by doing yet more complex queries. I will explain the what and why of all those, and hopefully you will be all up and running to do yourself more complex queries and dig into the tables with some stronger tools.&lt;br /&gt;&lt;br /&gt;Before we start digging into complex queries we will have to setup a couple of tables where which will help us to build our examples. I will also store those in a SQL file so you can directly download them and run them inside your PHPMyAdmin.&lt;br /&gt;&lt;br /&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://engine.nowhere-else.org/article4_tables.txt&quot;&gt;http://engine.nowhere-else.org/article4_tables.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This should create a table PLAYER with about 60 entries inside.&lt;br /&gt;&lt;br /&gt;Now that we have the table and the data, we can start to check a few things. The simplest query that everyone should know is retrieve a row given an ID:&lt;br /&gt;&lt;br /&gt;SELECT * FROM PLAYER WHERE ID=1;&lt;br /&gt;&lt;br /&gt;If we read this query, we can decode it like that, &quot;take all the data from the table PLAYER where the column ID contains the value 1&quot;;&lt;br /&gt;&lt;br /&gt;Of course this was an easy one, now if we want instead to retrieve all the rows where the username starts with the letter B the query will use a keyword &quot;LIKE&quot; instead of the equal sign:&lt;br /&gt;&lt;br /&gt;SELECT * FROM PLAYER WHERE USERNAME LIKE &#039;b%&#039;;&lt;br /&gt;&lt;br /&gt;If you run this query you will see it returns more than one row, and that the uppercase or lowercase doesn&#039;t matter to the condition. Again this is not a very complex query, the only interesting thing here is the use of % which is a wild character when you use the &quot;LIKE&quot; keyword. The underscore &quot;_&quot; match any single character and the percent &quot;%&quot; match any number of any characters. You can also do a &quot;NOT LIKE&quot; operation to reverse your query. Keep in mind that &quot;LIKE&quot; is not a fast operation as MySQL needs to go inside the field an analyze it.&lt;br /&gt;&lt;br /&gt;Now what if we want to count how many players reached at least level 20?&lt;br /&gt;&lt;br /&gt;SELECT COUNT(*) FROM PLAYER WHERE LEVEL &amp;gt;= 20;&lt;br /&gt;&lt;br /&gt;And here you see your first &quot;GROUPING&quot; function, as instead of returning rows MySQL will start to do some work with the result as it needs to count the number of rows.&lt;br /&gt;&lt;br /&gt;We can work further in this direction and ask to count the number of players grouped by the first letter of their username:&lt;br /&gt;&lt;br /&gt;SELECT LEFT(USERNAME,1), COUNT(*) FROM PLAYER GROUP BY LEFT(USERNAME,1);&lt;br /&gt;&lt;br /&gt;As you see, we use a string function here, to read the first character out of the username (LEFT) then the now known COUNT(*) to count the number of rows and suddenly at the end we find a &quot;GROUP BY&quot; instruction. This is needed if you don&#039;t use ALL grouping functions in the SELECT statement. As LEFT is not a grouping function we need to give the instruction to MySQL to say how it must be grouped.&lt;br /&gt;&lt;br /&gt;When you run this last query you will see that the column name of the result are basically generated out of the functions we use, however it may become odd to use such names in sub queries (something we will present here after), we need therefore to introduce column aliases:&lt;br /&gt;&lt;br /&gt;SELECT LEFT(USERNAME,1) STARTWITH, COUNT(*) NB FROM PLAYER GROUP BY LEFT(USERNAME,1);&lt;br /&gt;&lt;br /&gt;The names &quot;STARTWITH&quot; and &quot;NB&quot; will be used as columns name for the result table. Now, MySQL is not really strict on the syntax here, with some other databases you may need to use the keyword AS or put the alias name in double quotes.&lt;br /&gt;&lt;br /&gt;Now what is a sub query? Well let&#039;s start with this example, we want to know all the username of the players which are in a group of those username where more than 4 players uses the same starting letter. Make sense? Well basically we want to retrieve all users width start the very common starting letter. How useful it is in real life I honestly don&#039;t know, but it gives you a first view of what a sub query can offer.&lt;br /&gt;&lt;br /&gt;SELECT * FROM PLAYER&lt;br /&gt;WHERE LEFT(USERNAME,1) IN&lt;br /&gt;(SELECT STARTWITH FROM (SELECT LEFT(USERNAME,1) STARTWITH, COUNT(*) NB FROM PLAYER &lt;br /&gt;GROUP BY LEFT(USERNAME,1)) SUMIT WHERE NB &amp;gt; 4);&lt;br /&gt;&lt;br /&gt;Now you see it starts to get a bit more complex. What happens here is that we first need to extract which letters are mostly used, then select it in another query which are used by more than 4 players and finally retrieve all those which use those starting letters.&lt;br /&gt;&lt;br /&gt;The syntax is the following: SELECT * FROM (SUBQUERY) LOGICALNAME&lt;br /&gt;Where SUBQUERY is any kind of query and LOGICALNAME is a name you give to your pseudo table.&lt;br /&gt;&lt;br /&gt;You see we used also the &quot;IN&quot; keyword, this tells to retrieve all rows where a column is within a given list. The list could be a coma separated list of values like (1,2,3,4) or defined by a sub query in which case the sub query MUST return only 1 column.&lt;br /&gt;&lt;br /&gt;There is still something I want to explain before finishing with a nice query, and this is the JOIN feature. Normally when you want to &quot;link&quot; two tables together you do something like&lt;br /&gt;&lt;br /&gt;SELECT A.*, B.* FROM A, B WHERE A.ID=B.A_ID;&lt;br /&gt;&lt;br /&gt;Where the A_ID is the link between the two tables. This will work but will retrieve only the rows where there is a match. What if you want to retrieve also the rows of A, even if there is nothing in B? Then you must start to use the LEFT or RIGHT joins:&lt;br /&gt;&lt;br /&gt;SELECT A.*, B.* FROM A LEFT JOIN B ON (A.ID=B.A_ID);&lt;br /&gt;&lt;br /&gt;Now MySQL will retrieve all rows of A, with the data of B in case there is some.&lt;br /&gt;&lt;br /&gt;With this knowledge we can now see the final mighty query of this tutorial:&lt;br /&gt;&lt;br /&gt;SELECT PLAYER.USERNAME,S.NB NBTOT,A.NB NB10,B.NB NB30 FROM PLAYER,&lt;br /&gt;(SELECT REFEREE REF, COUNT(*) NB FROM PLAYER WHERE REFEREE &amp;lt;&amp;gt; 0 GROUP BY REFEREE) AS S LEFT JOIN&lt;br /&gt;(SELECT REFEREE REF, COUNT(*) NB FROM PLAYER WHERE REFEREE &amp;lt;&amp;gt; 0 AND LEVEL &amp;gt;= 10 GROUP BY REFEREE) AS A ON S.REF=A.REF LEFT JOIN&lt;br /&gt;(SELECT REFEREE REF, COUNT(*) NB FROM PLAYER WHERE REFEREE &amp;lt;&amp;gt; 0 AND LEVEL &amp;gt;= 30 GROUP BY REFEREE) AS B ON A.REF = B.REF&lt;br /&gt;WHERE S.REF=PLAYER.ID ORDER BY S.NB DESC&lt;br /&gt;&lt;br /&gt;This query retrieve all players which have referred players, and count how many referred players they have, and the how many over level 10 and finally how many over level 30. This could be a nice report for you admin, and this is done with a single query.&lt;br /&gt;&lt;br /&gt;The reason to do such complex queries is to avoid having multiple queries running to retrieve the data. Most of the time a single query even if a bit more complex is faster over a loop in PHP doing queries one after the other.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=5e306c5a-eb2c-8794-a38f-4bfd565b995e&quot; /&gt;&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/14736</link>
      <pubDate>Thu, 05 Nov 2009 01:52:02 -0800</pubDate>   
  </item>
    <item>
   <title>&quot;Small&quot; things, huge impact</title>
   <description>This week I worked on something which may seem like a little thing at first: I replaced the left menu links (or at least all the player links) with some new buttons containing an image and some text:&lt;br /&gt;
&lt;img src=&quot;http://eu.nowhere-else.org/gui_icons/bug.gif&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
Now of course this took quite a while for me to find ideas about which image should represent what, find a simple yet appealing look to those buttons, and finally make them with my trusty Photoshop.&lt;br /&gt;
&lt;br /&gt;
Still, after this, I wasn&#039;t expecting such a huge &amp;quot;welcome&amp;quot; to the improvement. Initially I did it to improve (slowly) the look of the game, to have it look more like a game and less like a web page, and it seems the players really appreciated it.&lt;br /&gt;
&lt;br /&gt;
Overall, small things can have a huge impact.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;zemanta-pixie&quot;&gt;
&lt;img class=&quot;zemanta-pixie-img&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=9d4727b0-283b-843f-baa7-a992b89c5ebf&quot; /&gt;
&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/14703</link>
      <pubDate>Wed, 04 Nov 2009 07:39:14 -0800</pubDate>   
  </item>
    <item>
   <title>Players Corner is growing</title>
   <description>Slowly things are growing on &lt;a href=&quot;http://www.playerscorner.org&quot; target=&quot;_blank&quot;&gt;playerscorner.org&lt;/a&gt; side. First change is that now we use OpenID to authenticate users. So if you have a yahoo, AOL or google account, you don&#039;t need to create another account as you are already up and running. Second thing you will spot (if it&#039;s not already the first one) that I changed the look, many people said it wasn&#039;t really great, and I have to agree it wasn&#039;t really my best website. Now I don&#039;t say the new one is perfect, but it&#039;s better.&lt;br /&gt;
&lt;br /&gt;
On the back end, I changed what the pages are called, instead of having a single index.php?PAGE=xxx I decided to call the pages directly. This makes things a bit easier to debug, and certainly easier to handle the links.&lt;br /&gt;
&lt;br /&gt;
On the features, I started to implement the &amp;quot;activity points&amp;quot; as well as having a first initial review system up and running. More goodies will come over time, but hey that&#039;s the beginning.&lt;br /&gt;
&lt;br /&gt;
I still need to code the Q&amp;amp;A (Questions and Answers) which will be like yahoo answers but focused on  games. This will certainly require a lot more work on my side, and hopefully will have some good impact on the community.&lt;br /&gt;
&lt;br /&gt;
On the content side, I had an agreement with a guy writing games reviews, he shall provide us about a review a week, which means we will certainly have some content to show.&lt;br /&gt;
&lt;br /&gt;
As always all the existing tools are... like drafts and need to be improved over time. However having most features running before making advertisements is what we need. And the quicker the site is up and running the better it is.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;zemanta-pixie&quot;&gt;
&lt;img class=&quot;zemanta-pixie-img&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=0b7c98be-3d13-853f-bb22-40cd89b2456d&quot; /&gt;
&lt;/div&gt;</description>
   <link>http://garg.blogs.nowhere-else.org/post/1/14431</link>
      <pubDate>Wed, 28 Oct 2009 07:23:20 -0700</pubDate>   
  </item>
  </rdf:RDF>

