By 2005 I had really started to get more and more interested in game design and development and was building up a bit of a library of books on the subject. I had even started making games, having gone through a few projects over the course of the year (that's not to say any of them were ever finished!). The first of which I had totally forgotten about until I found it again just now.
It was really a project to try and learn some Flash, but as a "Hello World" goes it was a bit over the top. It was a turn-based territorial game that connected to a MySQL database via PHP. The grid that represented the map was built using dynamic 3D elements, so that you could zoom in and out on it and also rotate it.
As for the rules:
- Each player starts off in one corner of a 31x31 grid, and you have to try and take over the centre square (fight against a neutral tower there with automatic dice rolls).
- In order to be able to have the chance to take over the centre square (at x=0, y=0), you need to control a certain area around it (11x11 grid).
- You can control squares by moving onto them, but this control decays after a certain number of turns.
In other words, if you move onto a blank square and move off it again that square will turn to your colour. You will remain fully in control of the square for ten turns, after which it will begin to decay, which will last for ten turns after which the square will go back to being controlled by no one. Unless, you revisit the square to fully regain control of it.
- You can't control squares already controlled by another player.
- To control squares without them decaying, you can place a tower which will control an area of squares around it. You will only lose control of those squares if another player destroys the tower.
- In order to build towers, you need to collect resources from the squares. These resources will be randomly distributed around the board.
- You can only extract resources from squares you are currently on and control. i.e. you can't extract from squares controlled by other players.
- If a square is controlled by another player but is decaying, you have a chance to extract the resources but it depends on how decayed the square is (better chance at 90% decayed than 10%).
- After a certain number of turns, the resources will be re-spawned and redistributed around the grid.
So as you moved about the map you left a Tron light-cycles style trail behind you that gave you temporary control of squares on the map. Collecting resources and then building towers would eventually allow you to get to the stage of winning the game.
As with most such projects that I embark upon under my own initiative, this was eventually abandoned (with only a handful of items on that list implemented) as other priorities got in the way of any game design aspirations. When I did start making things again my attention was all on 3D game engines thanks to the
book that finally allowed me to get a grasp on C++ and more importantly Object-Orientated Programming.
About the time I was connecting databases to the game engine that you get out of Vaughan Young's book, thinking I was going to put together a mini MMO, I got distracted... again!
On the game design forum of my gaming guilds site, one of the users, Golga Bolg, had suggested the design for a simple economic simulation. But lacking the programming experience needed to put it together himself he asked if there would be anyone else up to the challenge of coding it. Thinking it would be a short distraction I jumped on it.
It's rules were:
- Player gets 5 digs per hour.
- Player has maximum of 200 digs bankable.
- Dig has chance to unearth random number of nuggets. (Say Base: 1-100)
- Plans get auctioned regularly for Digging machines. (Generated by the game)
- Digging machines have varying qualities. Generally the machines get more powerful as the game goes on. Although weaker ones are also generally sold as well.
- If you win an auction for a digging machine plan, you can no longer dig, but must make nuggets by selling digging machines to other players.
- Digging Players may only utilize one digging machine. (Buy one from a manufacturer and you replace the one you have, if any)
- Digging machines have the following qualities:
X amount of nuggets as ingredients for the machine
Y minutes to produce a machine (Must be made serially)
Z% increase in digging production.
- Digging machines are sold in a Marketplace style. (ie. Public pricing, no private trades)
- Winner of the game is first to 1,000,000 nuggets.
This was built in about 900 lines of well-spaced procedural PHP (with MySQL db), with basically a link to 'dig' and a bunch of tables for data such as the 'market'. About two full games were played with a handful of players, only a couple of whom saw it through to the end. So the "complex economic dynamics" that were looked for never really emerged. There were a number of suggestions floating about on how the game could be improved, but I ended up going far beyond them as I effectively merged Golga's digging game with my earlier Flash game and made what would eventually be called Tile Tactics [link to old site removed].
Tile Tactics was built from scratch with PHP5 to take advantage of its better OOP features compared to the previous version of PHP (where is was more of an afterthought). In fact since I was going to be doing some 'real' OOP stuff with this project I did something that I tended not to do with any previous project; sit down a plan it out before doing any actual coding. Which was probably a good thing to do, as the code that formed the core of Tile Tactics is mainly the same code that runs this and a number of other sites.
Of course over the course of its development things changed, as SOAP web services made way for AJAX, and the games design fleshed out and expanded.
Starting with the first rendering of data to the screen in the browser at the end of 2005 the game began to
steadily improve in its display and features. Looking back at it now I am having some "
I did all this?!" moments as I look at how much I had actually gotten done; markets, guilds, territorial control, chat channels, resource distribution, etc. Granted it was not all complete and it slowly accumulated over the course of about two years, but I am actually proud of what I managed to get done there.
But ultimately it lies unfinished in a permanent Alpha state. My intention was to actually 'finish' it and release it to the public at some stage, and perhaps even eke out some sort of income from it, but I don't think it will be going anywhere now. Of course my main intention was simply to make a game because I was (and still am) interested in somehow getting into the games industry. The normal Customer Support entry route probably isn't the best for me, what with me being an unpersonable hermit and all. Maybe I would be suited to a start in QA... not saying that everyone in QA is an unpersonable hermit!, but I think I'm perhaps somewhat decent at tracking down bugs.
But following the advice of many a 'Breaking into the Industry' article I decided that perhaps the better option for me was to actually make finished games and perhaps get them noticed or to go on CVs.
But at the time I was struggling to maintain enthusiasm for a development process that I was taking my time with and seeing little feedback from, and it was when
Metaplace finally came along that Tile Tactics finally fell by the wayside.
I though that Metaplace would be a much better place to make games that would get some attention, but first I had to learn this new platform. So following the advice of many a 'how to be a writer' articles - to write what you know - I tried to
make what I knew and so the very first world I made was TileTacticsTest...
Due to the nature of how the web works, building a game with PHP/JavaScript, the original Tile Tactics was an asynchronous multiplayer game where you acquired action points over time that you could then use in one short session.
Metaplace on the other hand runs a server with open synchronous connections to all its connected clients, so it wasn't necessarily limited to the same style of gameplay.
So in Metaplace Tile Tactics started to become a Real-Time Strategy style of game. So rather than a single avatar that you controlled yourself, there were a number of non-player units that you could give orders to.
After my first week in the Metaplace alpha test I had my units being selectable and you could tell them to move to a location by double-clicking on the map
In Metaplace you can define different mouse inputs to perform different commands. So to define a double-click you can do something like this in a script...
Code:
Define Commands()
MakeInput('move to location', 'mouse-terrain', 'double-click', 'none', 'move')
MakeCommand('move','move to x,y', 'x:float','y:float')
end
But this double-click behaviour was only added to the server at the beginning of this year, and has only started working in the client recently. Before that if you wanted to do a double-click type of action you needed to do it yourself by scripting it. This would involve listening for a single click and delaying the execution of the single clicks default action by about a quarter of a second. If another single click was received within that quarter second then the entire chain would register as a double click. The single click action would be cancelled before it could run and then the double click action would be run right away in its place.
Since Flash, which Metaplace use for its main client, limits you to just the left mouse button, scripting in this type of behaviour became a necessity for those who wanted greater input control. And RTS games need a lot of input options.
In short order I had the units chopping down trees, and when they had their hands full dropping off what they were carrying at the nearest tower before going back for more.
I had also altered my double-click behaviour so that when you double-clicked on a unit you selected all the units of that type
Another useful selection method of RTS games is window selection. Again this was not something Metaplace could handle itself, so it was something I had to make myself.
If a user used a shift-click on the map then it started the window selection mode by placing an image for the top-left corner of the window in that position, while also changing the cursor to show the image for the bottom-right corner. When the user then clicked on the map again with a normal single click then a window would be drawn between those two points and any units within that area would be selected. This feature worked great at the time, although it relied on one big assumption, that the size of the client window was 640x480. This is because the selection window was drawn as User Interface, which is drawn to the client window and does not account for it position in relation to the world, so there is a conversion required between Worldspace co-ordinates (where you clicked on the map) and Screenspace co-ordinates (where the window will be displayed on the client screen). Again I'll leave the
technical details to Crwth, but this doesn't work if you do not know the size of the clients window. Since anyone can be viewing the world in full-screen mode, and since everyones full-screen sizes are different, this useful feature become completely broken.
The fix for this would be each client telling the server what its current screen size is, and we know the client is aware of its size as it sits in a browser window (because there are debug messages displayed each time the windows is resized), so we could use that information in the worldspace to screenspace calculations. But despite this being an apparently simple changes there is no sign of such a thing actually happening. I had been asking for this almost for as long as I've been testing in Metaplace, through a number of avenues, but we've never heard so much as a 'Yes', 'No' or 'Maybe' on this issue. So I won't be holding my breath.
In RTS games, since you have no avatar yourself but are controlling units that can be scattered across the map you tend to need to be able to move your view of the world about a lot, so good camera controls are needed.
In Metaplace when a user is in the world there is a 'player object' within the worldspace to represent them. This is typically used to make an avatar that the user controls, but in my world the user had no avatar so I decided to turn the player into the camera, which I did by making the player invisible (this can be done by either using a transparent image or setting the objects sprite to an invalid id. e.g. player.spriteId = '-1:-1'). With the view locked to the player object, as the object moves about the world it also moves the view. Now I already had some simple camera movement control in place, where if you double-clicked on the map with nothing selected then the camera moved to that location. But I decided to add some more precise control and allow for zoom controls too (as a part of the worldspace-screenspace calcs I had disabled the use of a mouse scroll-wheel to zoom the view).
The movement arrows were pretty straightforward; click on one of the eight directions and you moved a certain distance (dependant on zoom level) in that direction. But a limitation was that you had to do it one click at a time, you couldn't hold down the button and scroll across the world. This was because, again until recently, unlike keyboard input support for which you could define both up and down key states, mouse support was limited to just one state. This means you could not do something like 'do something while the mouse button is down, then stop when it is released'. But recently a UiEvent() function was added along with a whole list of mouse states that would make such a behaviour possible.
The other item of note on the camera position controls was the 'home' buttons. The small button outside the big circle allowed the player to set their current camera position are their 'home' position. Then if they had the camera positioned somewhere else on the map they could press the big circle button in the middle of the arrows and they would then be taken back to their home location without having to manually navigate their way there.
Now, the zoom controls might be what some could call a bit of a dirty hack, since it used a function call
OutputToUser. This allowed a script to send any bit of text to clients, including text formatted in the markup tag language that the client expects to receive from the server. This way you could fabricate what would otherwise be legitimate tags that would normally be sent to everyone (if you changed the Places zoom setting for example) but send it to only the user specified. I used this 'feature' to make a client think that the places zoom settings had changed (and so the client would alter the display accordingly) when its user clicked on the zoom buttons. Each player object had a new 'zoom' property attached via script and each managed their own settings independently of each other. But as Crwth noted in his post, the OutputTo*() set of functions are no more, so if you went into the TileTacticsTest world you could click on the zoom buttons all you want but they wouldn't do a damn thing!
Luckily there was a replacement for this particular use of OutputToUser (although that can't be said of other uses I put it to). In fact there was a whole set of new camera control functions added, which means I could remake my entire camera control widget to make use of them, and I may just do that someday unless someone beats me to it.
I made only a few more additions to this world, including making a bigger map and adding some terrain, and also transplanting some of my PHP scripts over to Lua to show a bit or territorial control.
The world was used for the regular Spotlight feature on the Metaplace site, but I didn't give the world too much attention after that. I had learnt enough about Lua and Metaplace that I felt I could try on some fresh projects.
And with that my work on Tile Tactics ended. I'm not sure if I'll ever get back to working on it, but I learnt a lot from it in its various incarnations. Maybe it will live on in spirit in whatever future game I make!