Thursday 28 February 2013

DuskZ GMUD, & Source

I just got confirmation of the original source license so I decided to get it all out of the way tonight. I kept thinking it was Friday today, but since that's tomorrow I wanted to clean up then then try harder not to get sucked into hacking on it for the rest of my long-weekend.

I've kept most of the code GPL 2 or later but decided to exercise the 'or later' on the client side and used GPLv3 for the new files and for the whole package.

The source has been checked in to the DuskZ project. Well the DuskZ keeps with my naming convention theme, and it will soon diverge enough to need another name.

As I started without a version control system there is no detailed changelogs, but lets just say the changes have been 'considerable'.

Test Run

The code is pre-alpha but it should run the current test game from Zabin (with some bugs), although only the initially imported version will work. I already have pending changes to break it.

First check out all 3 modules from the DuskZ googlecode and build it. I use NetBeans 7.3 beta but presumably ant will work.

Then checkout the old test game from DuskRPG github. The compatible game files are in "DuskFiles/Dusk2.7.3"

Start the server:

$ cd {path-to-DuskRPG}/DuskFiles/Dusk7.7.3
$ java -jar {path-to-DuskServer}/dist/DuskServer.jar

Start the client:

$ cd {path-toDuskRPG}/DuskFiles/Dusk7.7.3/www
$ java -jar {path-to-DuskZ}dist/DuskZ.jar

A recent Oracle version of java is currently required as the JavaFX stuff hasn't been fully freed yet for the openjdk. Fingers crossed it will be a matter of months.

Connect to localhost, port 7474 and enter a username/password to create a new account. If all's well you'll get dumped into the game, or not - no promises at this point.

Update: I forgot to add www to the client starting directory.

Java Scripting?

Well to "relax" I did some reading up on JavaScript from Java ... and to be honest it's "bloody awesome". I've done plugin languages and extensions before in C and Java so i'm no stranger to the binding issue, but this makes it almost "zero work" if you already have well defined objects - which should be a goal anyway.

Anyway, it's tidy and 'included', which is nice - no wonder Oracle is trying to modularise Java, it's getting big.

As one might know from reading this blog i'm not a huge fan of writing applications in JavaScript ... but it does have it's uses and this one seems like a perfect fit.

One of the last major components of the original Dusk I haven't already gutted is the scripting language - but it's now on the chopping block too. One reason is the code is pretty opaque and difficult to maintain, another is that the 'scripts' are the whole game, the finally it is a reasonable enough implementation (compact pre-compiled code) and still works. But the thought of extending it to support planned new features is a bit unpleasant.

I think breaking the whole existing part-game is worth it in the long run. And efficiency isn't much worth if it isn't usable - and computers are somewhat faster than they were 15 years ago.

It's also what I would call a "marketing" or "management" feature: JavaScript has a huge following and a ton of resources, whereas trying to learn the arcane and obtuse syntax of Dusk's script engine is not going to be high on anyone's list of things to do before they die.

I played with it a bit more and realised you can basically do everything you could do in Java from any JavaScript script, including file and network i/o ... so it looks like i'll have to delve into SecurityManager. I've always avoided it as the documentation is obtuse and bereft of any useful examples - and we all know how complexity is such a winner when security is at issue. I'll also have to work out using it in a multi-threaded context, if that's possible.

Well I suppose life wasn't meant to be easy.

Time passes.

Ahh on threading it looks like everything has to be from the same doPrivileged() call. I chose to create a threadpool and submit jobs to that, and use Future to get the results if required. Seems to be a reasonable compromise. I've implemented a watchdog timer too, but because the ScriptEngine has no way of interrupting or stopping execution (should be something on the Context?) I'm forced to use the dangerous "Thread.stop()". Well what can you do eh? I guess it's more than a "few lines of code", but on the other hand I have a nice easy to use - and probably safe - script mechanism.

This deserves more of a write-up but I was supposed to have an early minute today so it will have to wait.

Update: I had more of a look at scripting including the SecurityManager aspects and documenting the current script system and how it's used.

Unfortunately the sandboxing turns out to be much more involved than I wanted. I can fairly easily do a basic sandboxing such as preventing disk and network i/o outside of prescribed locations (no thanks to the documentation; it's unreadable shit), but beyond that things get quite tricky. One reason is the rhino engine itself needs to do things like reflection in order to execute any script.

I experimented with some nasty stuff like scanning the stack-trace for 'legal' accesses, but I dunno, it seems complex enough that I wouldn't trust it. So for the moment my initial solution will stick with the simple high-level solution of restricting file and network access and put some trust that the players that reach a high enough level to create scrips that will behave themselves - as one did in the past.

I've still yet to come up with the solution i want for how the scripts should be structured. I've thought about everything from a simple global-context scripts to having the entire mob persistent state exist within local variables on objects within the JavaScript engine and all scripts merged into a single pre-compiled programme. Something in-between will probably be the result - as usual - but I need to implement at least a couple of ideas and see how they work in practice. One desires as much flexibility and simplicity as possible, but you can't maximise both at the same time. I initially thought of simply having global-state inline code, but that doesn't allow the use of 'return'. So now i'm thinking more of defining a function within the code that matches the filename. This also allows pre-compilation. And certain objects such as things or items require a number of related scripts, so it probably makes sense to wrap them in an object and just call methods on that.

The existing script language is pretty weird. Prefix notation for operators and effectively everything is just a function (which parses itself - the syntax is not parse-able without semantic information). Might take a while to grok and convert the scripts - a compiler which converts the scripts probably isn't worth the effort. One detail I hadn't previously been aware of is the number of general player commands that are implemented as scripts - and the complexity thereof. Most of the other scripts are fairly simple or at least straightforward. It's not an absolute necessity to convert all of them or even any of them - but having an existing game working is a good test-bed.

There are also some scripts which don't really do much and simply define global "game-theme" behaviour - yet need to run very often. I will look into whether these can be instead be implemented by Java code and supplied at run-time via a plugin/extension mechanism. This still allows for customised behaviour without recompiling the whole application, together with better space and time performance.

Tall tiles

Had a little hacking session this morning and implemented "tall tiles" into the client. The server doesn't need to know about them although I had to write a converter for Tiled format for the test map I generated.

Tall tiles allow for a great deal more flexibility in design for oblique or isometric projected maps without complicating any of the game logic. Well, ... it seems a pretty obvious feature for anything but a top-down game.

If one looks closely one can see the partially obscured player sprite. Even things like the tree in-front of the path/building/or other trees is completely impossible with the original Dusk engine - without creating separate tiles for every possible background.

As I need to store multiple images and so on I decided to store them in a jar file, with a manifest describing some meta-data about the files therein. In tiled I create a separate set of tiles for each tile size, and the converter creates one packed image for each tile set and stores it in the jar. I intend to use the same mechanism (and jar) for player and mob sprites too, allowing a lot more flexibility there as well, and possible even use tiled to manage those too (allowing for example symbolic names for sprites rather than using numbers which are hard to keep synchronised).

Rendering is straight forward from top to bottom and I render the map then the player. I put all the player labels and highlights above everything else because well it just seemed like the right thing to do.

Server

I decided to change the way tile actions are defined. Rather than have a separate script for each tile by number, I instead have a property file (why write my own parser, again) which defines which script is executed for each tile that needs one. By default tiles cannot be walked or seen through so values only need to be set for open tiles. This makes it a lot easier to manage, and I will probably hard-code some constants like "true" as well. I'm using Tiled to set the properties on the tiles which define which scripts are run, and the converter dumps these to a file the server understands.

Actually last night I also started working on a binary protocol for the server. I did the map update and a couple of others. But then I kind of got hung up on trying to encode some of the more detailed messages and just wasn't feeling the love. Probably a more re-usable approach using simpler "property lists" might be more loveable.

Source?

Some licensing queries I have should be sorted soon, and then i'll put the code somewhere once I've fixed up the files.

Anyway i'm pretty pleased with my progress this week (considering i've never worked on any game code ever before), and this little 'win' is probably a good opportunity to take a break, before I get overly keen and try to tackle multiple maps or layers and sink my last weekend of leave down the toilet!

Wednesday 27 February 2013

Tooling and stuff

Did a bit more refactoring and bug fixing this morning in the server. Removed a bunch of Vector types, and improved the code a bit. Found and fixed a concurrency bug.

Now i'm starting to get the codebase under control - and learning enough about it - i'm starting to get more wild ideas and think about other issues.

One is tooling - the bundled editor isn't too good, and there is already a java-based editor for tile maps called Tiled (although it's moved to C++ now - ugh - the original still works ok and doesn't need a pile of dependencies installed). So I had a bit of a play with jaxb and jxc and created an exporter for the current map format to Tiled's native format.

It works ok although bogs down (on this laptop) at this sort of scale - the map is pretty big.

Writing an exporter isn't much more work, although since i've gone this far i'm starting to think of other ideas to include at same time ...

Taller tiles
Taller tile images which sit on the same base square allow for things like trees and forests and posts you can walk behind. i.e. pretty useful for a designer.

I think this should be pretty easy to implement as a first cut, the rendering code only needs to align based on the height of the tiles, and the image storage needs fiddling with. A slight further complication is to avoid pop-in, but the server can send more of the map than is shown.

Taller sprites
This again is fairly simple and solving the problems for the tiles should help solving it for the sprites.
Multiple maps
I think that huge map is pretty unwieldy, 'rooms' are just defined as teleports to other closed sections of the map, and obviously that doesn't scale particularly well. Obvious solution is to have a separate map just big enough for each 'scene', and add the map id as a move/teleport argument. I think this loosely connected graph of separate regions has a more 'muddish' feel to it too.

I think that most of the game logic doesn't really need to change, as most entities will be tied to a given map so it doesn't need to turn into a 3d problem.

Layers
Another idea is to have multiple layers of rendering as a mostly cosmetic feature. I initially thought this would be pretty easy but to do it well will require some extra meta-data.

To keep the problem in two dimensions the entities will either have to be locked to one visual layer which might be a bit limiting, or some extra meta-data provides that information. e.g. a non-visible plane which indicates which layer objects are rendered on. Currently there can be behaviour attached to a type of tile that you're standing on and although this layer-indicator system would also work with that it might be useful to have a separate plane which defines the behaviour - although that is more design work.

But it could certainly be interesting, and allow for some interesting effects like parallax.

Binary protocol
Currently the protocol is a mix of binary (char) and strings. Actually it's a bit of a mis-mash of mis-match - each end is writing to a DataOutputStream, and each end is reading from a StreamReader. Although it works it isn't really supposed to, and having a DataInputStream on the other end would allow binary interactions.

Initially the layer stuff sounded good but the more I thought about it I wasn't so sure. I played with some taller tree tiles in Tiled and I thought it looked pretty nice. For an angled-down view just using a taller image gets you much of what you might want layers for without the extra overhead.

Tuesday 26 February 2013

de-awt-ed

``I'll just fix up a few little things'' turned into ``Another full-day of hacking'' on my fork of Dusk.

I finally managed to de-awt everything. Well there are a couple of missing features (text viewer/editor), but the last major window to convert is in:

To make this a bit nicer I think I need to modify the protocol so the server tells me more about the items such as item counts as it does with the inventory command. And there are other possibilities such as graphics, and "detailed description". It should probably also split up equipment and general inventory in some way or another ...

Well at least the layout didn't take any time today even if it looks it.

What took all the time was rewriting another big chunk of the client code map tracking and abstracting away the user interface from the client logic.

For the map code I again abstracted it into a separate structure and provided accessors and indices of various things, although now i'm reflecting on it I don't think some of the stuff I coded is even used since the algorithms that used them are gone. For example there was code to find entities by name - but internally i'm just using unique ids now so having an index by name it isn't required anymore. One major change I did was to just keep track of entities (players, mobs etc) using absolute coordinates rather than trying to keep them forever up-to-date with the current viewing window. Apart from being a great deal easier to use it is obviously more efficient. There were a lot of "x - offset1 + offset2" type things everywhere anything was accessed, and instead I just made the map to be relative to the top-left corner rather than the centre, and track the player location separately.

I also changed entity based actions to use id numbers instead of indexed names. Basically if there is more than one object of a given type on the screen then some messy code gives each one a unique number. The problem is the client and server do this independently, and I couldn't be stuffed finding out how it works - one of the benefits of the map abstraction was killing a pile of ugly code, and it was buggy anyway. Since the server and client already uses unique id's for everything I just added support in the server for doing targeted actions based on id instead. The client can always do the lookup if the command line needs to support it, and I guess I can now clean up that mess in the server too.

And finally the entire user interface and system interaction is hidden behind a re-usable interface, for the obvious sub-java/sub-gnu operating system option.

So far the de-awting seems to have made is more stable too. Although I also fixed some thread issues in the client as the game runs on a separate thread to JavaFX.

Monday 25 February 2013

Shopfront

Given the day started raining I spent most of it hacking on Dusk again. Coded up a shop-front.

Yeah the styling is naff, but it isn't meant to be better. The main window blurs when it's shown.

I gotta say the layout was a lot messier than I would have thought. VBox and HBox only allow consistent alignment for all items in the stack - which seems pretty pointless to me. I'd have thought a common use-case for a VBox would be a stack of things with different alignments. And I couldn't get GridPane or BorderPane to work very well either, although perhaps I could now with the following knowledge.

Basically to perform arbitrary alignment and expansion of cells within a vbox or hbox, one has to embed a hbox or vbox for each containee, set it to fill, and then set the containee alingment on that. It's just rather clumsy. As for the table view I had to hard-code everything to make it behave at all.

And learning a new toolkit is always a pain - probably took 5 hours to do this one simple window even though i've been working with layout based toolkits since gtk 1. And even then it seems to have some nasty javafx bug in which the table view in the Sell tab doesn't render properly. I really must try this stuff on another box to see if it is just something wrong locally like the shitty Intel IGP or it being 32-bit.

Playstation 4

Ok so I guess I do have a passing interest in the Playstation 4 hardware after all. Although I have only read a couple of articles about it and can't be bothered watching the press conference.

The unified GDDR5 memory sounds really awesome - I think it would make a great workstation. Memory bandwidth is a big bottleneck on any current PC, particularly with the separated memory spaces and the PCI barrier. Pity it's going to be a locked down proprietary system though, so unless it can run GNU/Linux completely then it really just isn't going to interest me this time. I really wonder if the time of the proprietary console hasn't passed ... it's hard justifying the expensive games and expensive blu-rays if most people are happy with flash games and youtube. For entertainment i'm more inclined to read a book, write software, or make something with my hands than play a game - i've got a few unopened PS3 games as it is (and no it isn't ironic that my latest foray into software is a game ...).

On the other hand, the hardware itself isn't particularly proprietary this time - maybe there are some customisations but it is basically just off-the-shelf AMD hardware. The unified memory is one thing mentioned with AMD's HSA plans, and is critical to their performance road-map, so with any luck we'll see comparable APU motherboards available for other OEMS. In the SteamBox perhaps? AMD are hinting at some 'good news for gamers' coming up at any rate. It's about time PC architecture got a bit of a rev-up, Intel has held it back for too long with their over-engineered-junk-as-a-competitive-strategy approach. Well fingers crossed anyway, although this is just a bit of hopeful optimism at this point.

And as an aside it's sad to see CELL BE go. Or it would be if you could ever have gotten a PC with one in it, and they kept up the development to keep it competitive. I learnt a lot about hetereogenous processing, SIMD, and parallel processing from my short stint with it.

On the software side - what's this obsession with "social" junk? Gah. No thanks. Wasted enough of my life on that shit in the past, and when I do want to interact with people I want to be with them. And when I don't i'd rather be properly alone. I can understand the Google's and other people-spying companies of this world wanting everyone to perform all interactions on line (whilst some rentier takes a cut of the cost!), but physically meeting friends is much more satisfying, private and totally free in all meanings of the word.

Early dawn of a new dusk.

Well I basically spent the whole weekend hacking on the Dusk server code. A lot of refactoring and code cleaning, fixing messy logic, abstraction and information hiding. Getting rid of the nasty hungarian notation, moving to modern java types and constructs, and so on.

Broke a lot on the way, but managed to fix some of it and found a few bugs here and there too.

Some of the 'new' Java features that have been particularly handy:

  • Switch on string. I didn't think much of the feature when I heard about it, but with some of the code having "symbol" tables with 50+ tests implemented using if(), the switch statement fit in very well. I did try converting the command parser to use a hash table but it required so many classes it blew out the code-size too much;
  • Generic containers just to clean up a lot of unnecessary casts;
  • The container classes other than "Vector". This replaced some custom container classes or eliminated a pile of code;
  • Iterators. Let me do nice things with the map (more below);
  • Subroutines. Quite a lot of code was just cut and pasted from place to place, and simply moving the snippets to parametrised functions just cleaned up a lot of clutter. Don't underestimate the power of subroutines;
  • foreach came in handy in many places;
  • inner classes allow for information hiding and better abstraction.

The Tile Map

So apart from just general code cleaning I also replaced big chunks of code with simpler or better implementations. One of the bigger pieces was the TileMap class.

Previously the code had a couple of 2D arrays to hold the tile numbers and the entities on the given tiles. Every bit of code (from anywhere in the class structure) that needed it just accessed it directly - sometimes with a lock, sometimes with the wrong lock, and sometimes with no lock at all. So apart from having a public array being accessed willy-nilly, most of the uses simply fell into the category of scanning the player-viewable area for information. i.e. ripe for code re-use.

As an aside, much of it just wasn't very well done code, it looks like whomever wrote it had some ArrayIndexOutOfBounds exception problems and kept poking it till it didn't crash then cut & pasted the result everywhere. For example:

int i,
    i2,
    i3,
    i4;
DuskObject objStore;
                
i=0;
if (thnRefresh.intLocX-viewrange < 0) {
    i = -1*(thnRefresh.intLocX-viewrange);
}
i2=0;
if (thnRefresh.intLocY-viewrange < 0) {
    i2 = -1*(thnRefresh.intLocY-viewrange);
}
for (;i<mapsize;i++) {
    if (thnRefresh.intLocX+i-viewrange < MapColumns) {
        for (i3=i2;i3<mapsize;i3++) {
            if (thnRefresh.intLocY+i3-viewrange < MapRows) {
                objStore = objEntities[thnRefresh.intLocX+i-viewrange][thnRefresh.intLocY+i3-viewrange];
                while (objStore != null) {
                    ... process ...
                        objStore = objStore.objNext;
                }
            }
        }
    }
}

And this example is synchronized on this - which is the wrong lock.

So apart from the curious convention of post-fixing almost every reference with "Store", and giving loop indices meaningful names like 'i2', the logic is rather convoluted. Took me too much effort to realise it is a simple 2D scanning loop over (x-viewrange, x+viewrange) and (y-viewrange, y+viewrange) with some bounds checking; which can obviously go outside the loop.

As this was repeated in a few places I decided to encapsulate it into the TileMap and provide an Iterable interface that lets me share that logic. It also allows it to hide implementation details (e.g. rather than a 2d array, it is a 1D array - and it should probably just use a hash-table anyway) and handle locking reliably.

Of course the primary benefit is that it just simplifies every use:

for (TileMap.MapData md : map.range(refresh.x, refresh.y, viewrange)) {
    for (DuskObject o : md.entities) {
        ... process ...
    }
}

MapData includes both the tile info and the entities on that tile, and may in the future include per-tile scripts and so on (i'm not sure yet as the script stuff needs a context - which is currently the main game object). The object itself (MapData) and the list is only allocated once on the iterator, so it is cheap and relatively gc friendly to iterate.

But wait, there's more! There were two other main users of the map which required poking around it's internals: visibility testing (i.e. who can see what) and path finding. So I also implemented these inside the map, and took the opportunity to improve the algorithms (although they might need tweaking).

For looking I used Bresenham's algorithm for testing of obstructions through the line of sight. It does give 'enhanced vision' in that it will allow for looking diagonally through gaps which was not possible before, but that can be tweaked if it is a problem.

For path finding I used an implementation of A* (I started with this one) which is restricted to moves in cardinal directions. Since traverse-ability testing requires script execution a callback is used so the map code doesn't need to know about such things. Actually it is perhaps a bit too powerful - it will find a route to any tile you can see even if it has to traipse all the way around the map to get there. But again this can be tweaked without having to change every bit of code that uses it.

In both cases the meat of the code is somewhat smaller than that which it replaced and it is much easier to re-use, at only a modest cost of a bit of plumbing. e.g. a very simple example which prints the directions required to get from start to end, only moving on empty tiles:

MoveListener callback = new MoveListener() {
    public boolean canMoveto(MapData md) {
        return md.tile == 0;
    }
};
for (TileMap.MoveData md : map.move(startx, starty, endx, endy, flags, callback)) {
    System.out.println("Move: " + md.direction);
}

Next?

Well there is still on-going renaming, hiding, and abstraction work in the server. Most i/o isn't implemented reliably (e.g. delete file + write RandomAccessfile). The script compiler/executor uses non-symbolic integers as opcodes. There's too much use of a try-catch to hide bugs rather than fixing them. And there's some bugs in visibility syncing with the client which i've had troubles with - probably ripe for a complete re-do because after too many failed attempts at understanding the code, maybe it's the code at fault and not me.

As for the client, it still has some awt windows which need replacing. The shop and equipment screens are the primary ones, and it could always use an inventory screen as well. Once i've had enough of poking the server I might look at that. One problem on the client is that I fairly regularly get some exception inside javafx which stops it rendering - requiring a restart of the application. Seems to be a javafx bug on this system (i'm coding on my laptop, which I normally only use for C).

And for efficiency's sake at some point the server protocol should be converted to binary, or at least have a binary option. Well, actually a more robust protocol needs to be created.

Then at some point there will also be work on a code release, a couple of issues to sort out first and I think the client should be awt-free before then too. But i'll try to do it before I lose interest and find something better to occupy my time!

Update: Just found out i'm back to work in a week so I might get a bit more in while it's hot in my mind but I need to wind down to prepare for work again too.

Saturday 23 February 2013

The hourly WTF?

Ok so a bit of "cut and paste" code-re-use is one thing, but I think we have a grand-prize-medal winner here ...

public void updateEquipment() {
    try {
        String strResult = "" + (char) 7;
        try {
            strResult += equWorn.wield.name + "\n";
        } catch (Exception e) {
            strResult += "none\n";
        }
        try {
            strResult += equWorn.arms.name + "\n";
        } catch (Exception e) {
            strResult += "none\n";
        }
        try {
            strResult += equWorn.legs.name + "\n";
        } catch (Exception e) {
            strResult += "none\n";
        }
        try {
            strResult += equWorn.torso.name + "\n";
        } catch (Exception e) {
            strResult += "none\n";
        }
        ... repeats a few more times ...

I'm not having a go at the original author - I think it was written a long time ago when he was inexperienced, but it's pretty funny nonetheless.

Friday 22 February 2013

More Dusk

Kept poking on the Dusk source code over the last few days, trying to put more of the "G" into the GMUD name.

I've converted the server list to an embedded Node, which handles login and character creation as well.

This is current the server/login window complete with a pretty shithouse stylsheet.

And if the server asks for it, the race.

I managed to fit these in at first by just screen-scraping some of the responses and changing them to graphical output, but I will probably look at extending the server protocol to handle it in a more controllable manner.

First I had to get the server built - which was pretty easy - except then I decided to move a big chunk of it to a different namespace. Well I got it done eventually but had to make a lot of stuff public - the code is pretty poor overall. I also spent a bit of time modernising the Java but only scratched the surface.

One thing I did need to extend the server protocol for was to "enhance" the battle display. So after a few hours refactoring the whole battle engine. Pretty much everything was done twice, by cut and pasting large blocks of code. I moved these into parametrised functions which halved most of the logic although I added some bugs too. Then I looked at adding a new message type which reports who did how much damage to whom.

Which let me add some damage bubbles ...

Of course being JavaFX they are animated: they drift away from the attacker and fade out to blank.

Apart from the old container classes (Vector everywhere) most of the code is a bit of a mess. Code and data is all over the place, and little things like object references are no limitation to who wants to use what. There is also quite a lot of it - from the script system to the command handler and the main game controller - so any real improvement will require a deep understanding.

But for example I just came across this sequence ... which is repeated about 8 times through a couple of classes:

    if (engGame.scrCanSeeLivingThing != null) {
        synchronized (engGame.scrCanSeeLivingThing) {
            engGame.scrCanSeeLivingThing.varVariables.clearVariables();
            engGame.scrCanSeeLivingThing.varVariables.addVariable("seeing", thnStore);
            engGame.scrCanSeeLivingThing.varVariables.addVariable("seen", this);
            blnCanSee = engGame.scrCanSeeLivingThing.rewindAndParseScript();
        }
    } else {
        blnCanSee = true;
    }

Apart from poking at some internal variable on another object, it's a prime candidate for a helper function. This sort of stuff is everywhere. The Hungarian notation is really shitting me off too ...

Wednesday 20 February 2013

Dusk - fx

I'm not sure exactly how I came across it but I found a blog DuskRPG about an old Java graphical MUD called Dusk with some source on the net.

The start of this week was hot and idle so I spent a lot of time just reading shit on the web. I should be back to work soon so I thought i'd "do nothing" for a bit. One thing I noticed was that the liberated pixel cup finally got judged - and the games look a lot better than when I first looked at it some time ago.

It looked interesting so i've contacted the blog author and also had a poke at porting it to JavaFX.

So a few hours down I have enough to play it with the main window running as JavaFX code, although the other popup windows are still pretty nasty wrongly-threaded awt.

Not really sure how far i'll get but i'll see how it goes. I have a few ideas I want to try to "modernise" the gui and take advantage of features in JavaFX although some of these will involve delving into the server code too.

I have a habit of going nowhere with game code, but at least this time it's already done ...

Thursday 14 February 2013

Quick and dirty Biltong Cutter

Boy, the gutter thing turned into a much bigger job - a load of wood-rot (part of the reason I was doing it in the first place), so I had to re-enforce/repair the fascia before I could even get to mounting the leaf eater.

Nearly didn't get to the biltong cutter - i'm a bit sick of the sawdust and noise and not having a workbench. But I had a couple of hours free so had a go at a "quick job".

Of course, nothing is ever "quick", particularly if you haven't done anything like this for a while. The main hassle was creating a curved cutting surface as the knife is curved. It's a bit rough but it works quite well. I could probably use a better axle but the one I have works. I could also do with a drill press.

The uprights are at an angle as I already had some wood with angled cuts in it, and I thought it might be stronger having the screws going across the grain a bit. The cutting block it positioned so the blade has the closest tolerance - although I got sick of sanding so it isn't perfect.

So the trick was to find a cheap/fairly robust blade. I tried finding old tools but that was pointless and in the end I was going through an asian grocer's knife section and found a bunch of cleaver type knives, some with holes already at the top/front. I went for the medium sized one at all of $6.90 which already had a ~13mm hole in it. I guess I could always re-grind it to have a straight, chiselled edge, but the curve adds a slicing action.

The only thing i'm wary of is mixing such a dangerous tool with alcohol ... i'm sure it'd make short work of fingers or toes!

Update: It works quite well and I've still got the appendages, but I decided to make a slight improvement. With no clamping support the uprights tended to drift apart slightly which made the blade a bit loose after a while.

I took the shim out and trimmed it to size and then put a bolt through the middle. I just happened to have a brand new bolt exactly the right diameter and length sitting around. It expanded the shim slightly to be a tighter fit with the axel mounting holes and also a better fit with the existing hole in the knife. Having a threaded bolt allows me to tighten up the gap between the uprights so the knife stays straighter during a cut. A few drops of grapeseed oil had it moving smoothly even when fairly tight. The curved blade works well with the slicing action and gives a bit more cutting power than a direct downward action does.

Not bad for 15 minutes after a warm afternoon boozing it up.

With the changes everything feels a good bit tighter and more controlled and subsequently it is a bit easier to use with extra-dry meat or other harder material. It would still be better to have a chisel point but the knife edge is ok enough. Perhaps in hindsight the extra $3 for the next knife size up with the thicker blade might have been a good idea too but for a $7 experiment i'm happy enough and it is nice and compact.

It also makes a great over-dried galangal (the only kind available at the moment) cutter or anything similarly hard one wishes to slice extra-fine.

Monday 11 February 2013

Hanger for Pots & Pans

Got sick of shovelling dirt - and besides I finished most of the hard stuff and need the electrician before progressing - so I thought i'd hack up a hanger for my pots and pans and get them out of the draws and cupboards they're choking up at present. Yep, a bit of physical hacking ...

It's something i've been meaning to do for a while - I had some salvaged jarrah which came up something wonderful with a bit of a plane and a sand down, and finished with linseed oil. I kept the design 'simple/modern', and just put a chamfer around the whole piece, there is a larger chamfer in the mid-section which is a rough attempt at hiding a piece missing from one side (it didn't completely remove it and it can been seen in the second shot, but it reached the limit of my tools). It's not very visible so not very important. In general I could've finished it a good bit better but a bit of lived-in rusticity just adds to the charm.

The hooks and chain cost about $50 - mostly from the ceiling hooks which are stainless steel (~24$ for all 4), but otherwise it was just a bit of elbow grease. This old jarrah is almost as hard as steel but luckily I didn't have to do much to it. Trying to locate the beams in the ceiling was a bit tricky and trying to measure square to the walls didn't work - the window end came through right on the edge instead of the middle. At least I know those are in the middle of the beams but i'm not sure about the other end. The anchor points are further away from the centre than I would have liked but I didn't have much choice for stability vs length.

I estimate the total weight is around the 30kg mark - pretty hefty but apart from some initial anxiety I don't think there should be any trouble with it holding up even if it is only anchored in pine. I was worried at first that it would cast too much shadow from the down-lights, but as it sits toward the rear of the kitchen bench it isn't a problem. Same with respect to head-clangers.

It's just under 2m long, and mostly over the sink anyway.

All in all, i'm "well pleased"[sic] with the result. The oil turned the wood from a deep brown-red to a dark chocolate, which works particularly well with the brass plated fittings.

Now I probably need something for the lids ...

But for now my next project is a toe^H^H^Hbiltong cutter, and I think I came up with a cheap and easy-to-procure source for the cutting blade (vs a bench plane blade, which rusts anyway). More on that when i've got it sorted.

It wasn't the only thing i've been up to, I filled all my bottles with homebrew (4x worts), did a batch of biltong, and did some work on one of the gutters today. I really should've written down the second spice mix recipe for the biltong because it's really tasty! From memory the differences were black pepper, pimento (all-spice), fennel seeds, and i'm not sure if coriander came along too. I'm still making some of it a bit too salty (i'm kind of mixing up various recipes on the net but I think i've worked it out for the next lot), although it goes very well with beer ...

Wednesday 6 February 2013

It's all down-hill from here ...

I'm a couple of weeks away from being officially 'middle aged', although it doesn't really feel any different from any time in the past 5 years or so. Probably not surprising as nothing has really changed in that time. I guess mainly i'm not going out as much and not riding anywhere near as much but otherwise i'm about the same weight/fitness, same grey/hairline and have a similar set of aches and pains ...!

One thing hasn't changed in a very long time is my cynicism in general - one nick-name at work back in the late 90s was 'Grumpy' - although these days i'm less reticent about verbalising it as bluntly as I feel like at the time.

However one thing in particular I'm getting more and more disillusioned with is the state of technology in terms of software. Despite enormous advances in hardware and information and cost, we still basically have software at about the same level of shittyness as we always have. If anything, it's worse due to the sheer volume of mediocrity dragging the bell curve down. Together with particularly stupid ideas like HTML5. Whilst there are a few gems I believe the core problem is the complexity of software. It just keeps going up - which just means software is always playing catch up and never reaching maturity.

Some people seem to really get off on this constant change - like a manipulative game which doles out worthless rewards piecemeal in order to turn your learning-by-play-for-survival instincts against you - mostly worthless incremental improvements or often just 'change for change sake' which seem to get people overly excited. But we've all seen this shit before - if everything gets better ever release then it must've been pretty shit to start with, and with a certainty whatever we have now will be shit compared to the future, so why all the excitement? It might appear to be rapid progress but in reality it's just spinning the wheels.

This complexity and constant (but in reality unmoving) change is really just a competitive tool to manipulate the public. Think of the fashion industry. On the surface it is vibrant and active but in reality nothing really changes and it just goes around in cycles and it's all about marketing and extracting money.

For example over the last 15 years i've seen an awful lot of man hours go into every system, but the differences to a 15 year old desktop computer are really quite minimal outside of details and performance due to hardware improvements. What improvements there are are really despite the software side of things not because of them.

So here's a few thoughts and rants on many topics in no particular order:

Apple mini ipad
Big mistake. After big jobby's filing-fingers comments it had to be something special, and a low-res screen/underpowered for the time hardware is not it. This severely tarnishes the 'best of the best' premium brand Apple likes to project and is the start of relegating them back to the niche from which they came. After all the "retina" bullshit it really had to have at least that + upgraded cpu.
Microsoft
Lots of stupid mistakes. Phone is a complete disaster, although bringing down Nokia and QT was a good move on their part (removing a huge chunk of the competition - if it wasn't illegal it surely should be). RT is a complete disaster.

Surface PRO is a dumb idea - mostly because it competes with their own customers even if it ever does sell. Which I don't think it will - it's just an overpriced underpowered machine which can't make up it's mind what it is. A business would be better off with a netbook and the general public just wants a dumb appliance.

Unlike some weak willied saps I don't mind saying I hate Microsoft. They set the tech world back at least a decade with their junk and illegal shenanigans and they continue to interfere outside of the open market. And if you don't think that isn't a valid reason for 'hate', I think you need to re-evaluate your value system.

Android
I wish it was a proper GNU/Linux and I wish it was a proper Java. After some initial 'wow, neat', my thoughts have definitely cooled based on it's limitations and roadblocks. It suffers greatly from being designed for 5+ year old hardware whose assumptions no longer hold even for a $50-outright phone.
Google
Google is NOT the friend of free software or 'open sauce'. They are just a user and abuser of it and their customers in general. I wish more in the free software world recognised this. They only contribute when they're legally required or where it suits them commercially or for marketing purposes. Which obviously works well.

They're also a general proponent of the "fuck the user, we know best" mindset which is infiltrating all of IT. Not that I don't sympathise with this substantially, but i'm not the one trying to win over and influence people.

ChromeOS
Yay, thin clients all over again.

Yay, netbooks all over again.

World has been there before. Even battery powered ARM devices are getting powerful enough now they can do much more than run lightweight frontends to network services. Well they could if the frontends were lightweight and not supporting such a heavyweight framework as ...

HTML5
This will be one of the biggest sinks of money and man-power in tech-history. The multi-national software vendors are just using it as a weapon to keep their competitors occupied whilst they cement their own technology. It is now so complex and large it may never be possible to create an implementation of sufficient quality and interoperability. Problems which have forever plagued the net since the first clone of NCSA Mosaic was made will never be resolved. The web is becoming more closed than ever - more and more sites are 'chrome-only' or 'firefox-only', and then only with the absolutely latest versions.
FirefoxOS
See ChromeOS.
SystemD(OS)
The authors don't like Unix and want to create their own clone of Apple's operting system. Sure why not, but why do they have to fuck up a GNU/Linux system to do it? Apart from the ego trip it seems to be about proprietising their brand of Unix and stealing a customer base from what used to be a different product.

Next time I "upgrade" or install a system it will probably be slackware (if i have the choice on the hardware in question, I am hoping it is ARM based). Whilst i'm still using Fedora on a few machines they will not be installed with anything more recent than the already dated version they have.

Java
Oracle need to make the browser plugin free-software or face it's extinction as a platform for Java delivery - not that it isn't that far off at this point. Mostly for security reasons but also for cost and platform support.

The browser plugin has been a PR disaster, but one must also temper it with the fact that for Mozilla, Google, and Apple - Java is a direct competitor. It is in their interest to make it appear as scary as possible as well - and they're sparing no effort there.

At least the GNU/Linux support for Java is finally absolutely first class and in some cases arguably the best of all platforms. As a developer this creates great freedom - it doesn't matter which GNU/Linux distribution I use for development, or which proprietary os the customer does. For me Java is the 'platform', making the system it runs on irrelevant.

JavaFX
Apart from the media stuff which sucks about as much as every other media api ... ever ... it's looking great. The Android and apple versions must be released for free (in terms of cost at least) - there's no real money (of the sort Oracle could justify) to be made in development toolkits anymore and there hasn't been for a very long time.
ARM
Just going from strength to strength. The A15 and big/little stuff looks very exciting but I really want to see some micro itx form-factor machines with desktop-class i/o and memory and first-class GNU/Linux support. The mobile/low power i/o & memory stuff is really hampering the performance where battery power is not an issue and too many machines are just disposable android computers.

There is far too many proprietary parts to ARM SOC's though - including the CPU itself.

Netbooks
Apparently ASUS is dropping them. Apart from some obvious microsoft influence on the decision ... I really just think it comes down to margins for the manufacturers. A cheap product doesn't make much money and with margins so thin in the industry already it just doesn't make any sense for them. Just add a bit more hardware and call it an 'ultrabook' and sell it for a much higher margin instead ...

Presumably we'll be able to get cheep/small laptops intended for the Chinese market for some time to come though, so they will never really 'die'.

Python
Anytime I see a GUI app written in python it just makes me groan. Whilst there are are couple of OK ones in general they remind me of AMOS basic back in the day, or tcl/tk. Sure you can write applications with it but in general they're shit and even the really good ones are noticeably less than the best on the platform. I figure this is mostly because the sort of people who choose python choose it because it's "easy", which means they're probably not very good coders to start with - because it's really no different to any other language. Still can't even do threads ffs.
AMD
Good hardware, software getting better, but I just don't know what's going on there. Can they deliver with their grand plans of the HSA? Don't know, don't know. HSA is very exciting but I'd be more comfortable if it wasn't a consortia of a who's who of the also-rans of the multinational user-abusing elite.

If it isn't some ARM SOC, I want my next laptop to be a GCN based APU with full GNU/Linux support but i'm not holding my breath (and with 2 thinkpads which are still kicking along fine, i'm in no rush).

OpenCL
Whilst I think it's fun and cool, it's still not ubiquitous enough for software developers to rely on. Its also too hard for most modern developers who just don't seem to be very good at their jobs to start with. I'm not sure if this is because programming has been dumbed down too much (when we did software engineering 1 at uni, the whole mantra was that coding was so boring it should be given to low-cost code-monkeys and only the high level design mattered - but that wasn't true then or now), poor education, people are just too lazy, there's better money for the type of people good at it elsewhere, or some other reason.

Still - regardless of all that it is too hard and too costly to develop for OpenCL in general so improvements need to be made somehow. Ideally something like the Sumatra project in openjdk together with project lambda which makes it relatively transparent.

The HSA stuff is the widest industry push for something a bit more substantial to try to break the homogeneous multi-core mould - intermediate bytecode, support for more languages and an UMA for cheap cross-processor calls. Still to be honest - more than one cpu scares the willies out of most programmers so I think even that is likely to be too much to ask.

OTOH computers are so fast these days single core programming is more than adequate for the majority of processing tasks anyway.

Time
... is an illusion, lunch time doubly so. I think time is not a dimension but merely a measure of passing state. i.e. one can only travel forward in time at a fixed-rate (relatively) as the only state which exists is 'now'. This does away with nonsense like parallel universes required otherwise. Whilst general relativity is a great model of the universe which fits many practical problems, like every other model it is only a model and not the mathematics and machinery on which reality actually executes. No matter how fine or reliably the measurements match.

Not that I have any evidence for it, I suspect that the universe is infinite of age and size and the popularity of the big bang theory (and most of cosmology in general) has it's roots more in Abrahamic theology than in hard science. After all a big bang still needs a starting point and cause.

I don't believe FTL travel will ever be possible, and humans will never leave the solar system (too much energy required). Stephen Hawking and their ilk dreaming of a star-spanning future for humanity is no better to me than believing in the sky faery of an Abrahamic god, or that advanced (i.e. god-like) aliens will save the day.

The earth
We only have one world, we'd better work that out soon or be doomed. I don't hold much hope. Humanity has been given a cruel legacy from it's evolution - it is just too effective at breeding and controlling the wild environment that it will clearly consume all resources before it learns to live within it's means. And the only practical solutions are too morally objectionable to be contemplated - i.e. population control. Our evolutionary training has even ill-equipped us for a modern world of relative safety and internationalisation.

Of course given we are on a single planet the population will be controlled one way or another by itself - famine, epidemics of disease, natural disasters, man made disasters, accidents, wars.

We're already seeing nature fighting back - anti-biotics will no longer work effectively very soon and the results will be catastrophic, perhaps cataclysmic. This will happen in my life-time. In the past individual groups might have died out or be decimated by localised disasters, but we will clearly face global catastrophes in the not-too-distant future. I suspect at some point in the not-too-distant future many of the hailed medical advances of the 20th century - antibiotics in particular - will be seen as a near fatally-dangerous mistake.

Whilst I reckon life is widespread throughout the universe (just look at how widespread it is on earth - anywhere with water + energy = life), "intelligent" life may itself be an evolutionary dead-end.

free will
I'm not sure whether free will exists or doesn't, but any system as complicated as any animal is so chaotic it probably makes no practical difference no matter what the physics suggests.

But I am convinced you have no soul.

Religion
Whilst adults are free to believe whatever brainless nonsense they wish, I think religious indoctrination of children is tantamount to mental abuse. Particularly the hell and eye-in-the-sky aspects.
Tablets
Whilst I think they're here to stay I see them as a somewhat disturbing trend away from a general purpose computer. Although they have some usefulness on the whole they are just throw-away devices used to deliver mindless entertainment to the unthinking masses.

The OLPC coming out with a tablet really put me off their whole project - a computer without a keyboard isn't useful enough for learning the skills needed for the future.

IT skills - including scripting and programming - is a huge competitive advantage to any industry that involves workers using a computer. Whichever country decides that this needs to be part of the core educational set (like it was when I was a kid, and not just learning a few arcane microsoft applications) will surely have a bright future.

Parallella/Epiphany
Well i'm basically waiting on the hardware before I get too excited on this one. Still don't have any particular application in mind but I'm hoping it's fun to code on for the entertainment value alone.
Patents/eye pee, etc.
This sort of extortion, commons-stealing, and rent-extraction is unforgivably a direct result of the corrupt political system we all have in the west. I don't currently see any solution to this problem whilst courts are involved.

It will just be an on-going cost of doing business which will be borne by the general public to the detriment of most and the benefit of very few.

The only hope is for China to ignore it all (as they are) and booming as a result (as they are), and the western countries starting to look at their own self interest instead of the interests of the pan-national rentiers to which they currently answer (hah, asif). Although the pan-nationals have their fingers in the pie over there too.

Given that the USA isn't far off a developing country as it is (run-down infrastructure, high infant mortanity rate etc) if they haven't already done something about it I don't see much chance for change. I just hope Australia's current obsession with the USA and it's demonstratively bad-ideas cools off a bit and keeps us from the same route.

Playstation 4
Who cares? Fuck Sony.
Work/Leave
Well i'm on my 8th week of leave and I gotta say i'm getting pretty comfortable with the idea. Pity it can't last forever ...