by
Paul Mendoza
3/20/2013
If you've seen my "Writing Maintainable JavaScript" talk you may want all the example code that I used. Click the link below to get the JavaScript file. It is the raw examples that I used and I didn't really label anything. I give this talk fairly often. I'd suggest reading the book "JavaScript: The Good Parts" or "JavaScript Patterns" which are both great books and cover a lot more than I am able to cover in my talk.
JavaScript Talk Examples.js (9.22 kb)
Tags:
Categories:
by
Paul Mendoza
6/3/2012
This weekend I built a website for monitoring the downtime of Diablo III. It was more just a fun hobby project so I've made it open source on GitHub. I've been wanting to learn more about Git and do a project with it so I used the new Git For Windows client which is pretty slick.
Check out the Diablo 3 downtime monitor and let me know if you have any feedback.
Tags:
Categories:
by
Paul Mendoza
5/14/2012
I just published a website for a contest called GreenButtonAnalyzer.com that will allow you to analyze your Green Button data provided by your utility. Please vote for us in a few days at the Challenge.gov site in the link on the homepage.
Green Button Analyzer
Tags:
Categories:
by
Paul Mendoza
8/5/2011
SQL Server has a geography data type that can store geometry or latitude and longitude points. One of the major selling points of this data type is to allow an efficient indexing and lookup of points near a specific latitude and longitude.
Once a spatial index is created there are two different functions that make this possible and picking the right one is important.
Filter() and STInterects()
Here is an example of using both queries.
DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);
select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.Filter(@region) = 1
select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1
Notice that I have included a hint to use the spatial index that I’ve setup before this.
The only difference between these two queries is that one uses Filter() and the other uses STInterects().
For performance on a set of 5 million geocoded locations using a correctly configured spatial index, the first query returns results in less than a second using Filter() and the second query runs in 3 seconds. Why the difference you might ask?
Filter() is much faster because it can return false positives. As a result it doesn’t run as many checks to ensure that the point falls exactly within a region.
STInterects() does extra calculations to ensure that no false positives are returned. This results in much high CPU usages.
Here is how I’ve found use cases for each of these:
Filter - I’ve used this when building a map of points. On my map I want to show points around the center of where the map is currently looking. Because I don’t care if there are some extra points plotted outside of the visible map space, I use the Filter. Returning extra results doesn’t matter as much as speed matters.
STInterects - When I want to determine which points are in a geography object that is a polygon shape. For instance, I might have Lat and Long values for points but don’t know what the Zip code is that they are in. I might have in my database geography objects as polygons that represent the shape of individual zip codes. I could write a query that determines which zip code geography point this falls into. I don’t want any false positives here because then my query could end up coming back saying that my point is in two zip codes which it isnt.
by
Paul Mendoza
1/9/2011
The next thing you should setup if you're going to be doing coding for your UDK project is WOTGreal if you're using that for your IDE. I like WOTGreal a lot for UnrealScripting. If you put the WOTGreal directory into the root directory of your game project you can relative path the executable to the proper folders and classes. This way you don't have to change your WOTGreal settings every time you want to switch projects.
Here is my root UDK folder layout. Notice the WOTGreal folder.

In WOTGreal go to Options => Preferences and then Game Information.
Fill in the UCC.exe File, Game Root Dir, and Source Root Dir like so.

Once you fill this in, click Apply and leave the Preferences window. Then right click in the Packages section of WOTGreal and select the option "Refresh Class/Package Tree".

by
Paul Mendoza
1/8/2011
Recently I've been programming with UDK mobile and have come across a few limitations that I couldn't find a whole lot of documentation for.
One of the limitations is that terrain isn't supported as of yet in UDK Mobile. If you attempt to start UDK Mobile previewer using terrain it will crash the player.
Another limitation is that Dominant Directional Lights aren't supported either which is sort of a pain because this is a nice way of creating sunlight type effects. This can easily be worked around though using a directional light. You can use a skylight to brighten the level up a bit as well.
Tags:
Categories:
by
Paul Mendoza
1/6/2011
I've been working with UDK Mobile on a new game project. Upon downloading the UDK and getting it ready to check in to source control I found there were a whole bunch of files I didn't need since I'm creating a mobile only project. Here is how I've configured my project to minimize space and increase my productivity as a coder. What is nice about this configuration is that it allows you to have a whole bunch of UDK instances on your system at once without getting conflicts.

I've done the following.
- Removed the UDKGame folder. This folder is over half the size of the whole dev folder. This is an easy way to avoid having to check as much into source control if space matters.
- Added batch files for the most common operations which I've included the contents of below.
- Created a new folter under Development/Src/EPGame/Classes for the classes that will be a part of my new game.
- Created a test map for my game in the UDK editor.
- Deleted EpicCitadel.mobile map file because it is HUGE on the disk and I'm not going to ever use it. Don't delete the content for it because you can totally use that stuff in your game.
- Go to MobileGame/Config/DefaultGame.ini and under [Engine.GameInfo] set DefaultGame=EPGame.EPGameInfo where EPGame is the folder you make for your game in the Development/Src folder and EPGameInfo is your main GameInfo class. This will let your artists preview your game rules running inside of the UDK editor.
[Engine.GameInfo]
DefaultGame=EPGame.EPGame
DefaultServerGame=EPGame.EPGame
DefaultGameType="EPGame.EPGame"
Batch File Contents
BuildAndRun.bat - Builds and then just runs the mobile game with no logging.
Binaries\Win32\UDKMobile.com make
Binaries\Win32\UDKMobile
BuildMobile.bat - Builds and pauses so you can read any errors that may occur during the build.
Binaries\Win32\UDKMobile.com make
pause
MobileEditor.bat - Start UDK editor in mobile mode
Binaries\UDKMobileLift.exe editor
MobileGame.bat - Start mobile emulator with the log showing.
Binaries\Win32\UDKMobile.exe -simmobile -log
by
Paul Mendoza
4/16/2010
I just found this great concise writeup today on how to configure BIND DNS service on Windows easily. I have a Windows Web Server 2008 server setup but it doesn't have the standard DNS software that comes with the other versions of Windows Server. So I needed another solution and I found the BIND DNS software that is free and open source.
BIND DNS Setup on Windows Guide
by
Paul Mendoza
1/31/2010
Here are some general suggestions for working with .NET that will help when writing high performance .NET code where milliseconds matter.
1. ArrayList is slower than List<>
2. List<> and an array have the same performance if the list's initial capacity is set to an appropriate size when the list is created.
If the list doesn't have an initial capacity set then it will create an array of 1 size. Then when a second item is added to the list it'll allocate a new array of size 2 and move the points from array 1 to array 2. Then after 2 each time it runs out of space it'll create a new array and double the size of the new array.
List<int> x = new List<int>(); <--- Bad
List<int> y = new List<int>(1000); <-Good
3. Lamba and LINQ expressions tend to be slower than running a for loop with if statements. If you find your code having performance issues always look at any place where you use a lamda or linq to object expressions because they may be running 2X - 5X slower than a for loop would in most cases.
Bad:
var x = from p in people where p.Name == "John" select p;
Good
List<Person> foundPeople = new List<Person>(20);
for(int i = 0; i < people.Count(); i++)
{
if(person.Name == "John")
foundPeople.Add(person);
}
The reason for this performance concern is that for the LINQ statement it has to perform some extra steps for each comparison. From what I understand the cost in the LINQ statement above that is has to do some type reflection in order to determine how the comparisons should operate.
There are ways to get your LINQ to operate fast though and this page explains the ways to do it. Since you can never be totally sure what LINQ-To-Objects is doing I tend to go with what I know over what I hope LINQ-To-Objects is doing.
4. Use Dictionary.TryGetValue instead of checking for the key and then pulling the value out by index.
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "Paul");
dict.Add(445, "John");
Bad
string foundName;
if (dict.ContainsKey(445))
{
foundName = dict[445];
}
Good
string foundName;
if (!dict.TryGetValue(445, out foundName))
{
throw new Exception("Failed to find the index in the dictionary.");
}
5. RAM is the new hard drive so access it as little as possible. You can iterate over a list of objects and never actually access the data that composes the objects from RAM. A value doesn't generally get pulled from RAM unless it's needed.
List<Person> persons = (from f in Enumerable.Range(0, 10000)
select new Person()
{
Age = new Random().Next(12, 75),
Weight = new Random().Next(100, 250)
}).ToList();
// There is no slow memory access because it only loops over the pointers in the array.
for (int i = 0; i < persons.Count; i++)
{
Person person = persons[i];
}
// There is memory access here because the values that composed the object had to be retrieved from RAM.
for (int i = 0; i < persons.Count; i++)
{
Person person = persons[i];
int multiple = person.Weight * person.Age;
}
Also, there are multiple levels of being in RAM. L1 and L2 both sit on the CPU but there is very little of it. L1 takes 1 to 3 ticks to pull data from. L2 takes between 10 - 20 and L3 and standard RAM takes between 100 - 300.
Tags:
Categories: