Archive for category programming
Build 20100609
Posted by visual77 in gaming, programming, sc2build on June 15th, 2010
The newest iteration in my StarCraft II Build Order Calculator is a minimalistic approach, in comparison to the previous builds. Unlike the last few ambitious builds that attempted time and resource calculation, this is an attempt at the absolute basics. It is also my first build calculator that is somewhat usable right at the moment, as opposed to merely offering a glimpse at where I want to go with this system.
This calculator contains all units for all 3 races and allows for race changing and resetting the build. It also begins to toy with styles and the UI, although I didn’t spend much time other than getting elements in the rough position that I would like them to be.
I dropped back to a more minimal approach because I felt like the more advanced approaches I was working on were going in the wrong direction. I’d ultimately like a more advanced system, but I want to rewind a bit and go back to basics and consider alternative approaches to the other systems, that relied heavily on large data structures to store data, at times storing it repeatedly for different purposes.
Build 20100524
Posted by visual77 in gaming, programming, sc2build on May 30th, 2010
I completed the third JavaScript iteration of the StarCraft II Build Order Calculator this morning and put it online. It took a few days longer than I expected, but I also drastically changed how the data is being stored for the build order. In my previous builds, I stored the data with the time as the lowest level element, whereas this build stores the unit as the lowest level element. This makes it easier to see what the unit is doing (and thus, what it is allowed to do), but makes it harder to display the timeline.
I also stored unit actions (such as build Probe, warp in Pylon, etc.) as functions within each unit. As I wrote the functions, it quickly became apparent that a huge number of functions are identical and should only be written in one place.
This build shows me the viability of storing unit actions within the function and keeping track of unit timelines within the unit, but also shows the weaknesses of displaying the timeline when I have to scan every unit for every second to see what has been done. It still does not take into account that you need a Gateway before you can make a Zealot, but I chose to not pursue that in this build when all of the flaws of this build became apparent. It does, however, take into account queuing and will not let you build more than 1 Probe from a Nexus at any one time.
I will begin my next iteration very soon and hope to have that online within the next few days. Each iteration definitely teaches me a lot about what will and will not work. I am still very far from a final build, but I still think it is possible to get the final build online before the game launches on Jul 27, 2010.
The next iteration of the S2BOC is online
Posted by visual77 in programming, sc2build on May 24th, 2010
In my last update on the StarCraft II Build Order Calculator, I said that I was going to have this next version work on building queues, but I decided to work on the URL sharing instead. The newest version of the S2BOC still doesn’t account for queues, but you can now send someone the URL to share build orders.
This URL sharing is one of the most critical requirements of this system. This calculator is designed to aid strategy discussions and a key part of that is showing a friend your strategy. As you update your build order, the URL will be modified, so you can send the build order at any time and anyone going to that URL will see what you see.
This calculator also allows you to switch between Terran, Protoss and Zerg, albeit in a clunky way that will be addressed before the final build. In order to change race, change the URL to start the build order string (from # to the end of the URL) with T, P or Z. In both FireFox and Chrome, I had to refresh the page after changing the URL before the new race properly appeared.
StarCraft II Build Order Calculator
Sample Build (9 Pylon / 12 Gateway Protoss build)
Iterative Development for Economy Calculator
Posted by visual77 in gaming, programming, sc2build on May 19th, 2010
This iterative build was to test the economy calculator at different time intervals. I created an array to store information on 5 basic protoss units – Nexus, Pylon, Gateway, Probe and Zealot. I then wrote some quick calculators to accept a time, in seconds, and return the amount of minerals available at that time. The display is fairly minimal, just showing economy, but various units and builds were constructed at certain times.
The calculation is based on finding out how many probes exist at this time, how long they have existed, and multiplying that by 5/6. 5/6 is the number of minerals gathered per second per harvester (before saturation, at least). Once I have found the total minerals gathered, I get a list of all units that have begun construction at that time and subtract it from the total and return it.
The formula for calculating wealth seems okay, but the initial array contained far more data than I ended up using and the formulas were a bit too hard coded. Things like MULE and Chrono Boost are not being accounted for, and supply count is ignored as well.
I like the idea of a function being passed a time value and returning a snapshot of the build status at that time, and the array storing the build information also containing when each item was started. This system would fairly easily allow new commands to be inserted mid way through the build.
I definitely need to make the calclations more dynamic, though. I’m also still unsure of how to handle the starting Nexus and 5 Probes. This system puts the build time at -100 and -17, respectively, and always adds 700 minerals to the mineral count.
All in all, this iteration did show some interesting ideas, particularly with where to store data on all of the units. I ended up sliding it in as an array inside the build class, but that seems impractical. I should probably set a race as a class, units as a class, buildings as a class and special abilities as a class. My next experimentation will involve testing those methods for viability.
StarCraft II Build Order Calculator
Posted by visual77 in gaming, programming, sc2build on May 18th, 2010
I’ve recently begun work on a new project that should see the light of day in time for StarCraft II to launch on July 27. The project, being hosted over at http://sc2build.com, is the StarCraft II Build Order Calculator. The project aims to take the ease of use and share-friendly nature of World of Warcraft talent calculators and apply it to StarCraft II build orders.
The project is just beginning the iterative development phase, with some small scale tests of single aspects of the system. I began writing my notes on the site in plain text, but it quickly became apparent that I will have enough notes to require a full fledged blog.
Expect to see a flood of posts in the coming days as I think aloud on how to build this system and test various methods of implementation. I will be building it through iterative development, and as such there will be many micro tests in the coming weeks of single aspects of the system.
The first test that has already been pondered upon and attempted once is how to store the build order data in a URI without that URI becoming ungainly in length. You can see my notes on that test and see a sample of this one attempt in the iterative development section of that site.
Setting up dynamic themes on Kohana
Posted by visual77 in programming on April 14th, 2010
It’s been a little over six months since I first began to use Kohana framework for all PHP development, and I thoroughly love the system. The only issue I’ve had with Kohana is the lack of built in, intuitive support for dynamic themes. I was unable to find an easy method to set up a theme that automatically wraps itself around all pages, while remaining dynamic enough to change certain elements on a page to page basis.
Over the past few days, I have been exploring methods to do this, with the following requirements:
- Keep all theme files separate from the application
- Require no changes to existing controllers and views to implement or change a theme
- Allow multiple applications on the same Kohana build to use the same theme
- Provide support for cascading themes
After a few failed attempts, I have found a solution that covers all four requirements and is pretty easy to implement. Of course, it is easier to implement this from the start, but if you have an existing Kohana site, it shouldn’t be too difficult to integrate this theming setup into the site. The concept of the theme is simple: create a theme as a module and then use hooks to implement the theme elements as appropriate.
How to flatten an array in PHP
Posted by visual77 in programming on March 23rd, 2010
In a recent Kohana project, I came across a somewhat odd PHP scenario – I had a multidimensional array that I needed to compress to a single dimensional array, but retaining all of the non array values. Basically, I need to make this change:
Array
(
to => Array
(
0 => stevep
1 => bobw
)
bcc => Array
(
0 => paulj
)
)
Array
(
0 => stevep
1 => bobw
2 => paulj
)
I looked around a bit for an existing PHP snippet to do just this, but they were all overly complex and used recursive callback functions. I had a feeling I could pull this off in a much more clean fashion. I toyed around a bit with the array functions and the ArrayObject library, and this is what I settled with:
$new_array = new ArrayObject(); array_walk_recursive($old_array, array($new_array, 'offsetSet')); $flattened_array = array_keys($new_array->getArrayCopy());
The big drawback is the way ArrayObect::offsetSet() accepts its parameters, compared to how array_walk_recursive() sends the callback parameters; they are reversed. This causes the values to become keys, which has the effect of canceling out duplicate values. If your script needs duplicate values to remain intact, then this solution won’t work for you. Otherwise, it should work out just fine.
Dealing with PHP and character encoding
Posted by visual77 in programming on February 16th, 2010
How many times have you been presented with a character encoding glitch on a PHP site that you thought was working properly? You finished the site months ago with no issues, but now you are being told some weird character is showing up on that page? Chances are, that character is either Ã, Â or Ä, possibly followed by some other random character. If I’m right, keep reading. If not, I offer my deepest condolences, for you are knee deep in a character encoding issue that I cannot help you with.
So what is it that causes that à to show up? In short – you have UTF-8 encoded data set to display as ISO-8859-1. But the more important question is how to prevent this from happening in the future. The easy answer to that – store all data in the same format as the final display. Convert the encoding as soon as you receive the data, either through an input field, reading a file or any other method. Don’t put anything in your database unless you are sure it is in the right format.
First, an introduction to the three important character encodings that you are likely to deal with – ASCII, UTF-8 and ISO-8859-1. Character encoding is, in a nutshell, the exact method that characters are stored and displayed by a computer. Since computers only deal in binary, there must be some way to convert from binary into a character. Character encodings come in two flavors (at least, two flavors I’ll be discussing) – single byte and multi byte encodings. Single byte encodings, such as ASCII and ISO-8859-1, use a single byte to represent a character. For instance, the letter “M” in ASCII is represented as 0×4D, whereas the number 4 is 0×34.
A single byte is limited to only 256 possible values, which rapidly becomes a limitation when you want to use characters not typically seen in English, such as “ç” or “ß”, and when you begin thinking about Asian languages, you can quickly see there simply isn’t room for all characters. Multi byte encodings use one or more bytes to represent a character. Each byte still only has 256 possibilities, but 2 bytes have 65,536 possibilities. But, what if there is confusion as to whether or not you are using single or multi byte encoding? Is that short string “0×3C 0xA5″ supposed to be the UTF-8 character å or the ISO-8859-1 string ÃÑ? And there we are – a sudden bug has shown up.
ASCII is the oldest of the three and the most basic. The ASCII character set started out as just 128 characters, and very English-centric. You can see that the basic ASCII table is very restricted to the English speaking world. The extended ASCII table goes off into some weird directions and is rarely used. The full ASCII table is only 256 characters, and thus fits neatly into a single byte, and so it is a single byte encoding.
ISO-8859-1 is also a single byte encoding, but you can see that it is a bit better in the extended range to support many Latin based languages. Unlike ASCII, ISO-8859-1 can handle the majority of Latin based languages without too much issue. It fails when you go outside of the Latin based languages, however.
The third character encoding is UTF-8, which is designed to support over 1.1 million characters, more than enough for all existing languages (and a few dead ones). Unlike ASCII and ISO-8859-1, UTF-8 is not limited to a single byte, but can vary between 1 and 4 bytes, depending on the character being used.
One thing to take note of is that the first 128 characters of all three encodings are identical. This is why a character encoding issue on an English website can take so long to spot. You can go months not knowing that you have a character encoding issue because the only characters you used were the same in all 3 encodings – 0×4D is an M in ASCII, UTF-8 and ISO-8859-1.
On to the meat of this article – dealing with character encodings in PHP. Namely, how to detect and convert encodings.
The magic bullet of dealing with character encodings in PHP can be summed up in three functions – mb_detect_encoding(), mb_detect_order() and iconv(). The mb libraries are designed for working with multibyte languages and iconv is a function to convert from one encoding type to another. One nonobvious restriction to the multibyte languages is the lack of native support for ISO-8859-1, since that is a single byte language. mb_detect_order() can be used to specify the order of encodings to scan when attempting to detect an encoding on a string.
The basics of dealing with character encoding conversion in PHP is a simple three step process:
- Set the encoding types to scan (ASCII, UTF-8, ISO-8859-1). Luckily, this only has to be done once.
- Identify the encoding of the string to convert.
- Convert to the desired encoding type (I prefer UTF-8).
But, let’s cut to the crap. Sample code!
// tell the multibyte library which encodings to use
mb_detect_order('ASCII, UTF-8, ISO-8859-1');
// tell the browser that we are using UTF-8
header('content-type: text/plain; charset=UTF-8');
$string = "Fün wîth èñcøding!";
// UTF string displays properly
echo $string . "\r\n";
// convert to ISO-8859-1, which will confuse the browser
$string = iconv(
mb_detect_encoding($string),
'ISO-8859-1',
$string
);
echo $string . "\r\n";
// convert back to UTF-8, which the browser understands
$string = iconv(
mb_detect_encoding($string),
'UTF-8',
$string
);
echo $string . "\r\n";
How to unchunk data received through PHP sockets
Posted by visual77 in programming on February 12th, 2010
When using the PHP socket functions to pull data from another website, you’ll often find yourself dealing with chunked data. Chunked data often looks like this:
1e this line is 30 characters lon 2c g, while this line is 44 characters long. an 21 d this line is 33 characters long
As you can see, each chunk is preceded by a hex string. This hex string corresponds to the string length of the following chunk. Line breaks are included in the chunk, as you can see in the second chunk. So to unchunk the string, you have to find every hex string that is preceded by, and followed by, a line break (or start of end of string), and if the following block of code is equal in length to the hex value, strip out the hex value.
I accomplished this with a regular expression and preg_replace_callback. In essence, it finds each block of code that follows this pattern:
- start of string / hex string on it’s own line
- anything
- hex string on it’s own line / end of string
Once it has found all of those patterns, it replaces only the ones where the hex value of #1 is equal to the string length of #2.
My unchunk function:
function unchunk($result) {
return preg_replace_callback(
'/(?:(?:\r\n|\n)|^)([0-9A-F]+)(?:\r\n|\n){1,2}(.*?)'
.'((?:\r\n|\n)(?:[0-9A-F]+(?:\r\n|\n))|$)/si',
create_function(
'$matches',
'return hexdec($matches[1]) == strlen($matches[2]) ?
$matches[2] :
$matches[0];'
),
$result
);
}
Greased PMA – Stripping the suck out of phpmyadmin’s SQL query window
Posted by visual77 in programming on February 10th, 2010
Anyone who has used phpmyadmin’s query window knows how frustratingly small the textarea is, and how difficult editing SQL query blocks can be. I wrote a Greasemonkey script to de-suck this query window. As of now, Greased PMA is version 0.1 and has the following features:
- Automatic resizing of the textarea to make best use of the window size
- Ctrl+Enter submits the query
- Tab inserts 4 spaces into the query
Click here to download Greased PMA version 0.1.
Update: While messing around at home on Vista / Chrome, I noticed that Greased PMA partially works on Chrome. I wasn’t expecting this to work outside of Firefox / Greasemonkey, but Chrome has a similar extension feature, it seems. The textarea resizing works, but the Ctrl+Enter submitting query and tab modification do not work. Perhaps this weekend I will debug those two functions on Chrome.