Public Draft: Pawn Maintainability (‘static’ Keyword)
Posted by simon in Development on November 22, 2011
Introduction
One thing that is missing in the Pawn programming language is classes and encapsulation. If you want a variable’s value to persist (i.e. stay the same) throughout function calls there’s one immediately obvious way to do so. The most common and obvious way is to make the variable global which is fine for smaller scripts. However this method becomes problematic and difficult to maintain in larger scripts due to:
- Naming clashes if trying to use more simple variable names
- Overcomplicated variable names in attempts to prevent variable clashes
- Out of context variable declarations and unauthorized editing of variables
These problems stem from the number of variables increasing substantially and variables are declared out of visual range from where they are used. Frequent use of global variables can lead an individual and even a team being very quickly overwhelmed.
During this write up I will most likely brush over a few non-important definitions. It is expected that you can learn about these terms by searching the internet or prior knowledge. If however, you still cannot understand the definitions you’ve found then feel free to leave a comment saying so.
Static
An alternative way to make variable value persistent is to use the static keyword. Use of the static keyword puts your variable in the heap as opposed to the stack. The heap is a space of memory that used by the compiler to put your global variables.
During the compilation process static variable declarations are put on the heap. Any reference to that variable in the same scope is translated to a memory address. This can mean that memory usage can increase if you overuse it. Memory increases as you technically have more global variables instead of the compiler determining a stack based on the largest predicted stack frame and dynamically adding/removing data from that.
Making use of variable scope is a very important technique to prevent your script from being too overwhelming. Scope is simply whether or not you can view a variable from another place, or another context. It allows us to hide information that is unnecessary to another context in the script. For example, you might have a checkpoint system that doesn’t need to know if the player is on the pirate ship.
Rules of the Pawn language tell us that we cannot declare a variable with the same name more than once in the same scope. This is to prevent ambiguity about what the variable actually means and what data it refers to.
It is also worth noting that files are of a different scope when using the static keyword. This is useful if you split your game mode into several modules each contained in their own file.
Example
Now we will have a look into a piece of code that uses global variables. I have made the variable names simple to highlight the point. However, this exaggeration does not dismiss the point and shorter names allow for a shorter amount of keystrokes when referring to the variable:
// These values will only be set ONCE since they're global
new
// The last time an update occured in this
// scope
g_iLastUpdate = 0,
// The X, Y, Z positions of the
// camera and the initial values.
Float: fCameraX = 2010.0 ,
Float: fCameraY = 1500.0 ,
Float: fCameraZ = 50.0 ,
// The X, Y difference to add on between
// updates
Float: fDeltaY = 0.25 ,
Float: fDeltaX = 0.5 ;
/*
The several thousand lines in between until you actually reach this method within
your source code.
*/
public OnPlayerUpdate(iPlayerID) {
// If the player is not logged in or they haven't read the rules
// then we'll try update the camera.
if (!Player_IsLoggedIn(iPlayerID) || !Player_IsReadingRules(iPlayerID)) {
// This variable will be set EVERYTIME the
// script reaches this point.
new
iCurrentTickCount = GetTickCount();
// Check if the difference between the last update and the
// new update is 50 msec.
if ((iCurrentTickCount - g_iLastUpdate) > 50) {
// Some logic to take care of the differences in
// camera positions
if (fCameraX > 2150.0 || fCameraX < 1850.0) {
// fDeltaX is static, so it will keep it's value the next
// time this function is called.
fDeltaX = -fDeltaX;
}
// Some logic to take care of the differences in
// camera positions
if (fCameraY > 1600.0 || fCameraY < 1400.0) {
// fDeltaY is static, so it will keep it's value the next
// time this function is called.
fDeltaY = -fDeltaY;
}
// Update the X, Y co-ordinates of the camera
fCameraX += (fDeltaX * 1.1);
fCameraY += (fDeltaY * 1.1);
// Set the updating players information so that the camera
// updates.
SetPlayerPos(iPlayerID, 2109.0, 1456.75, 30.0);
SetPlayerCameraPos(iPlayerID, fCameraX, fCameraY, fCameraZ);
SetPlayerCameraLookAt(iPlayerID, 1980.0, 1535.0, 13.5);
// Set the last update to the current tick count
g_iLastUpdate = iCurrentTickCount;
}
}
return 1;
}
Now imagine there’s actually several thousand lines of code between those variable declarations and that callback. You have to admit that it would be very tough to ensure the integrity of those simple variables and also annoying to ensure they do not clash with other variable names. Instead of using this method we can use an alternative method which makes use of the static keyword:
public OnPlayerUpdate(iPlayerID) {
// If the player is not logged in or they haven't read the rules
// then we'll try update the camera.
if (!Player_IsLoggedIn(iPlayerID) || !Player_IsReadingRules(iPlayerID)) {
// This variable will be set EVERYTIME the
// script reaches this point.
new
iCurrentTickCount = GetTickCount();
// These values will only be set ONCE by
// the compiler and dumped somewhere in
// memory.
static
// The last time an update occured in this
// scope
s_iLastUpdate = 0,
// The X, Y, Z positions of the
// camera and the initial values.
Float: fCameraX = 2010.0 ,
Float: fCameraY = 1500.0 ,
Float: fCameraZ = 50.0 ,
// The X, Y difference to add on between
// updates
Float: fDeltaY = 0.25 ,
Float: fDeltaX = 0.5 ;
// Check if the difference between the last update and the
// new update is 50 msec.
if ((iCurrentTickCount - s_iLastUpdate) > 50) {
// Some logic to take care of the differences in
// camera positions
if (fCameraX > 2150.0 || fCameraX < 1850.0) {
// fDeltaX is static, so it will keep it's value the next
// time this function is called.
fDeltaX = -fDeltaX;
}
// Some logic to take care of the differences in
// camera positions
if (fCameraY > 1600.0 || fCameraY < 1400.0) {
// fDeltaY is static, so it will keep it's value the next
// time this function is called.
fDeltaY = -fDeltaY;
}
// Update the X, Y co-ordinates of the camera
fCameraX += (fDeltaX * 1.1);
fCameraY += (fDeltaY * 1.1);
// Set the updating players information so that the camera
// updates.
SetPlayerPos(iPlayerID, 2109.0, 1456.75, 30.0);
SetPlayerCameraPos(iPlayerID, fCameraX, fCameraY, fCameraZ);
SetPlayerCameraLookAt(iPlayerID, 1980.0, 1535.0, 13.5);
// Set the last update to the current tick count
s_iLastUpdate = iCurrentTickCount;
}
}
return 1;
}
If you read the comments you can see what is happening in this piece of code. This code is using the static keywords and due to their scope the variable names are not required to be extra specific. The meaning of the variables such as fCameraX, fCameraY and fCameraZ can be picked up quite easily as they’re only used within that short piece of code. If the variables had been declared at a higher level than shown then the meaning would become less obvious. The code would have had to have been investigated to make sure there were no side-effects from reading or writing to the variables.
Conclusion
Hopefully after reading this you can appreciate the static keyword and its uses. Here is a quick summary of the topic discussed in this write-up:
- You can use the static keyword to hide variable information from unrelated modules in your code
- Data will persist throughout function calls which means that global variables are not always necessary
- Keep your code simple a programmer can only remember so much at once. You should limit the amount of information so that carelessness will not cause script breaking bugs
- Hide the information from areas it is not necessary
I hope that I have opened your eyes up to a few ways to take advantage of the static keyword. Remember not to overuse it if it’s not necessary, you may increase memory usage or cause unintended side effects.
5 Years: What does it mean? Will it go on?
Posted by simon in Development, Gaming on May 9, 2011
Today marks five years since littlewhitey’s SA:MP server was created. It was founded by a young man who had the alias of “littlewhitey” as SA:MP’s first server.
The server at the time of creation ran on a script simply named LVDM. This was a gamemode created by jax (SA:MP developer) and simply allowed players to freeroam around Las Venturas. It was very enjoyable but it started to get old due to it being a standard SA:MP gamemode, which was beginning to be hosted on almost every server and being surpassed by more technical edits.
Soon after the server was created, there was an edit to LVDM that was released to the public named LVDM~MG+LG. This script was created by Sintax and added features such as properties, spawn weapons and temporary saving to the server. The script had had RPG elements added to it and they were very succesful for the server, the players would join, build up their banks and mindlessly kill.
Mike, who was also a SA:MP developer took development under his wing when the default SA:MP administration tools were not enough for administrating a server with a 100 player average player count. You almost always had to wait in line, the server was constantly at max capacity of 100 due to it being one of a few official servers.
Development mainly occured with minor gameplay tweaks and behind the scenes administration tools; motivation for development was dying slowly. This was the time that I stepped up and offered to develop for the server, being a good e-friend of littlewhitey he had no problem with this. I wasn’t a confident developer, I started small and made edits to the existing script (nothing that interesting that I can recall).
After editing the script for what seems like a million times, I started to get fed up with it. It was becoming very difficult to update a script designed for 0.1 for the now released 0.2. The script seemed to be held together by sticky tape, one simple edit had a high probability of leading to catastrophic failure. I had an epiphany: I could rewrite this script from the ground up, code it more efficiently, add features while I was at it and learn a great deal from the process– it’d be a “gift” to littlewhitey for the fun service he’d provided for me and likely tens of thousands (possible exagerration?) of other individuals.
I scripted, and scripted, and scripted, and scripted. I experienced several nights turning into days, I’d become so attached to developing the script that it became a part of me. The script became something more concrete and was nearing completion. The feature list had expanded from something great to something even greater, the number of properties were increased, users could register, the gamemode employed stat-saving, spawn-weapons saved, gang territories were introduced, the gang system was expanded, the pirate ship changed from a simple money generator to a challenging mini-game of “Capture the Briefcase” and many other minor changes.
As the script neared completion I employed the help of Brandon to help get it done. He coined the name LW_LVDM for the script and helped tie up lose ends within the script to speed up development until finally LW_LVDM v2 was released on the 14th of July 2007.
The release of LW_LVDM v2 was a big milestone for me. It was my first major coding project ever completed. I’d created simple SA:MP scripts and dabbled with the generic hello worlds but never put in the time to make a full, working system. It helped me figure out what direction I want to take my life in, I found that it was a very influential project.
Now you know what it means to me.
In between now and then, the script has employed the skills of many scripters. They’ve all left a mark in the history of the server, so I’m sure it means at least a little something to them. What does your time on littlewhitey’s mean to you?
The question “will it go on” or a variation of it has probably lingered in your mind. Well I have an answer for you, and that is: yes. The next version of LW_LVDM will infact be v3.0, I have been working on it in my spare time (with Sneaky) and a lot in my recent university break. A release date has been set internally so we have a goal to reach.
The script will not be a rewrite in the sense that it’s started from <BLANK>. It is a highly re-organized version of v2.0 where changed core systems have been re-organized in order to refresh them and to address problems within them. However, 3.0 is not simply a re-organized script new features have been added to the script and are continuing to be added.
Stay tuned.
(Images thanks to Darius of SA:MP)
Perfect Dark 64
You know those Microsoft Points (MSP) that are given away during promotions; those points that usually won’t buy you anything? Well today those random MSP have finally added up to something worthwhile– Perfect Dark 64.
I’ve always been meaning to purchase Perfect Dark 64 for my Xbox 360, however, I never got around to doing so. I didn’t have the time nor did I want to hassle around with purchasing MSP. The excess MSP usually accrued through a MSP card purchase means that I would’ve essentially been mini-banking with Microsoft; the kicker being that my money is not “universal” once deposited.
As soon as the game had installed I didn’t hesitate to start playing it. Once the game had finished loaded up I knew a mistake had not been made, the joys of gaming in my “tween” years were revived. The tunes were in-tact, the resolution was better than ever, the controller scheme had been updated and everything else was just as I remembered it (perfect?)
I started with the tutorial part of the game to refresh my memory; the Carrington Institute was a nice hit of nostalgia. Grinning from ear to ear at what seemed like a “steal”, I then decided to play the solo missions on the toughest difficulty. The game was a lot more difficult than I remembered here. I believe the difficulty was just a controller change and the fact that I’m not very accustomed to controller FPS.
Playing around on solo for a bit when I decided I needed to share my new found joy. I introduced my younger sisters to the game via multi-player. Local multi-player is what I’ve truly missed from the current generation of consoles, it’s something that needs to return.
I do not have a single Xbox 360 game that provides multi-player magic like Perfect Dark 64. The only game with FPS multi-player that I own on Xbox 360 is Borderlands. The multi-player in Borderlands is clearly just tacked in there; it depends on where players are in the story which usually means that both players do not get the same enjoyability.
After playing the game with my sisters for approximately 3 hours I had proven the awesomeness. My little brother who used to play the game religiously with a friend and I is about to relearn what it’s like to have fun local multi-player gaming.
At a special price of 400 MSP, I highly recommend you purchase the game. You can get to the Marketplace page by clicking this link.
Enabling WebGL in Firefox 4
If you go to Google Body in Firefox 4, do you get an error stating that WebGL is not initializing properly? If so then keep on reading and I’ll explain a very quick switch that you can toggle in order to access the Body Browser and other WebGL applications:
- Fire up Firefox 4 and type “about:config” into your address bar then press Enter on your keyboard.
- You may get a warning about dragons. Tell Firefox you are aware of them and that you’ll be careful by clicking the “I’ll be careful, I promise!” button.
- Type into the “Filter: box” below the address bar the word “webgl”. You should now see most (if not all) of the WebGL options in Firefox 4.
- Scan the list for “webgl.force-enabled” under “Preference Name” (or type it in the filter, whichever is fastest for you), if the “Value” is set to false then right-click it and select “Toggle”; it should change to true.
- Re-open the Google Body page and it should be working
Now you can browse the anatomy of a human female or maybe you can view some other WebGL content. If you have problems with Firefox 4 after enabling this then you should disable it; one would assume it’s in beta (since not enabled by default) or you may have actually awoken a dragon.
End of Holidays
Posted by simon in Development, Jibber Jabber on February 3, 2011
I know I’m more than a month late, but I hope everyone had a very merry Christmas and a happy new year. I hope the rest of the year is filled with opportunities and good times for everyone.
My summer holidays are coming to an end. I’ve enjoyed the break from university but the lack of a routine is getting to me, even more so that my family and girlfriend have gotten back into their daily routines.
In light of this, I’ve thought to myself about what I can do for the next month of my holiday. I can’t go on doing things without a cause, that seems to me like a waste of time. I could be more productive, I could be building things and learning in anticipation of going back to university.
I thought that I’d create some sort of agenda for me to follow: something that will remind me to get things done. As of right now, I seem to just be doing a lot of non-important things such as browsing the internet or screwing around with my XPERIA X10 Android phone.
It would be nice to work on some sort of project to be able to stick on my resumé for when I finish university, a project that would also further my learning in C#, .NET and give me more programming experience in general. That project is a Pawn IDE, simply named “PawnEditor”.
I’ve also started adding some improvements to LVA (a branch of LW_LVDM), I’m adding the ideas to LVA because LW_LVDM seems to be evolving into something different to what I envisioned. The first update to LVA will be a more friendly UI, those who have stumbled onto my Twitter page will have seen developments of that a couple of months ago.
Another thing I’d like to do is read in hopes of improving English literacy skills as I believe mine are starting to slip. Although I have quite a bit of spare time due to holidays, it still feels difficult to whip out an “old-fashioned” book and start comfortably reading. I am currently attempting to read a novel named Atlas Shrugged by Ayn Rand, which I hope can be finished in good time.
Finally, it think it would be a good idea to post some Pawn tutorials. I believe that the best way of learning is to teach, therefore if I post up some Pawn tutorials it will also help me clarify and remember programming and Pawn concepts.
Control Your Music While You Play (i.e. iTunes “Web” Interface)
Posted by simon in Development on October 10, 2010
One thing that gets kind of irritating while playing a full screen game is that it’s often difficult to change songs while playing.
If you’re like me and don’t have a super gamer keyboard then it becomes a tedious task having to ALT+TAB frequently. Not only does ALT+TAB’ing become a tedious task but games often crash randomly or jump into infinite non-responsive loops when you jump back into them.
I have an idea that may help gamers control their music in-game. The idea won’t require any memory hacking and the likes overcomplicated coding voodoo, it’s to simply create a web interface for controlling iTunes. This interface can then be opened in the Steam browser which I believe is compatible with all games you add to Steam.
I was playing around with the idea by creating a basic ASP.NET page and it was all functioning fine. However, in order to run ASP.NET scripts you’ll need to install the ASP.NET server — not ideal.
The other option is for me to look at a JavaScript implementation. The only problem with that would be that the Steam Web browser may disable vital JavaScript controls (or all of them!) for security measures.
It’ll be an interesting project to work on. I do not actually know the in’s and out’s of JavaScript and ASP.NET (enough to get the basics working) so this project will be a very motivational learning project.
Almost One Year of Study Down
Posted by simon in Jibber Jabber on October 9, 2010
The most important recurring schedule at this stage in my life is coming to it’s yearly break. That is my tertiary study. I was thinking about what I’ve learned about tertiary study and the “journey” it took me to get there.
I’ve always wanted to go to university for something, as a child it just looked like such an achievement to be able to do so. I stuck through till the end of my secondary education even if admittedly it was a very lazy last year. I done this so even if I didn’t feel like studying, I’d still have the option to someday when I decided to grow up.
Well, my secondary education had come to an end and I hadn’t signed up to go to any university. The application process seemed daunting — there were loans, commitments, more study and general confusion about university applications to top it off. I couldn’t motivate myself to do all this while struggling to study for my end of year exams. I wasn’t ready.
I decided I’d continue working at my current job (a Domino’s Pizza store). I asked my boss if I could become a full time worker and work 40 hours per week, however he stated that he would only be able to give me 30 to 35 hours per week. This seemed reasonable as there were limited hours to be shared at the time. In light of this information I accepted the offer and hoped that if someone were to leave then my hours would be bumped up, it seemed like the logical thing any loyal employer would do.
Over the next year there were several people who left the job or transferred to another store meaning that more hours had become available. As a worker being loyal to his employer I was hoping that I’d get loyalty in return, however that wasn’t the case. I didn’t get the extra hours I had hoped for, I had actually started to lose hours so the replacements could get more hours.
There wasn’t much I could do once I realised I wasn’t being valued as a worker, a human-being and was being disrespected. It seemed I was rather thought of as a tool to make money and not a person. The worst part of the recession was upon me — I couldn’t find a new job which meant I was stuck working there.
My income was not steady enough to move out from home and push my life ahead. I then made myself a basic plan to push my life ahead:
- Hold Onto the Job:
It’s crap but it’s money in the hand. I can keep looking for another job while working but don’t simply drop it without another job to go to. - Go to University:
The chances of being employed and the amount of doors open to me will increase if I’m qualified. There will also be better doors available to me, doors that I’m interested in and doors that will make me happy.
I decided I’d study Software Engineering at the University of Waikato. This subject choice was a relatively simple choice to make, during my gap year I had enjoyed my time scripting for a San Andreas Multiplayer server named littlewhitey’s SA:MP Server and learning about programming in a language named Pawn.
The 8 papers that I chose for my first year of study were the following:
- ENEL111-10A: Introduction to Electronics
- COMP103-10A: Introduction to Computer Science 1
- STAT121-10A: Introduction to Statistical Methods
- ENGG180-10A: Fundamentals of Engineering
- ENMP102-10B: Materials and Process Engineering
- MATH101-10B: Introduction to Calculus
- MATH102-10B: Introduction to Algebra
- COMP104-10B: Introduction to Computer Science 2
After taking action I had to wait until 2010. The year I started my tertiary study and put my life on a better path. I haven’t regretted my decision to take this action, it has presented some difficult hurdles but not anything that cannot be overcome.
In the next week I will complete my last week of my first year of this exciting journey. The last week of teaching will then be followed by a 3 week exam period which will require me to knuckle down (damn calculus) so I get a 100% pass rate.
The time I’ve had at university has allowed me to undertake my interesting perspectives of things. I hope to continue developing that perspective and be able to put it to a good use.
I’ll also have you know that I recently quit the job at Domino’s Pizza. It was becoming too difficult to study and work at a disrespectful place. The kicker to this is that I got a call 3 days later to allow me to work at a new store opening in my home town. I’m looking forward to working at my new place of work: time will tell me how it works out.
Last.FM 2 iTunes Playcount Populator
Posted by simon in Development on July 27, 2010
This console program imports your last.fm playcounts into your iTunes library. It has slowed down on purpose to wait 3 seconds between each ‘page’ load due to last.fm API restrictions. It still chewed through my library (6700 songs) at a reasonable speed — just leave it running in the background.
This program is quite handy if you’re a frequent user of last.fm and iTunes/iPod. You may need it in the case of having to delete your library (or accidentally deleted playcounts) and would like your playcounts back from “the cloud.”
The program is written in C#. It makes use of the .NET framework and lastfm-sharp. You may need .NET framework v3.5 to run the program (as that’s what it’s compiled for)
Last.FM 2 iTunes Playcount Populator [Download Compressed Folder]
I personally use the playcounts to create dynamic playlists. This is done since there’s no way I’m going to rate all the songs in my iTunes library.
Update @ 28/09/2010:
It has been brought to my attention that the program crashed upon opening this. I apologize for this, the problem was that I didn’t include the DLL files required, this has been rectified and the program can be downloaded using the link in the post.
Google Images Update
Google has updated their Google Images search engine. I quite like the change as it gets rid of pages and presents the image results like its one page. This means no more clicking back and forward, easily comparing images in the search with another image in the search.
I have read some posts on a forum about the update and people seem to be complaining about the cluttered look. I quite like the look as it allows more images to be placed into one frame rather than having a tabulated, space consuming look.





