About Me

Michael Zucchi

 B.E. (Comp. Sys. Eng.)

  also known as Zed
  to his mates & enemies!

notzed at gmail >
fosstodon.org/@notzed >

Tags

android (44)
beagle (63)
biographical (104)
blogz (9)
business (1)
code (77)
compilerz (1)
cooking (31)
dez (7)
dusk (31)
esp32 (4)
extensionz (1)
ffts (3)
forth (3)
free software (4)
games (32)
gloat (2)
globalisation (1)
gnu (4)
graphics (16)
gsoc (4)
hacking (459)
haiku (2)
horticulture (10)
house (23)
hsa (6)
humour (7)
imagez (28)
java (231)
java ee (3)
javafx (49)
jjmpeg (81)
junk (3)
kobo (15)
libeze (7)
linux (5)
mediaz (27)
ml (15)
nativez (10)
opencl (120)
os (17)
panamaz (5)
parallella (97)
pdfz (8)
philosophy (26)
picfx (2)
players (1)
playerz (2)
politics (7)
ps3 (12)
puppybits (17)
rants (137)
readerz (8)
rez (1)
socles (36)
termz (3)
videoz (6)
vulkan (3)
wanki (3)
workshop (3)
zcl (4)
zedzone (26)
Saturday, 02 March 2013, 06:03

Binary Protocol

So I mowed the lawn and swept the yard and did some of the things i've been neglecting for a few weeks. Although now with no milk in my coffee I wasn't in need of the shop ...

By late afternoon i was a bit bored so I had a look at the binary protocol work I had started.

I decided to change tack rather than use the manual serialisation I had started. It was a variant of Externalizable, which although the fastest mechanism requires the client and server to have total knowledge of each end. Being java there are other possibilities such as sending the decoding library to the client at run-time, but I wanted to keep things simple.

I started creating general purpose containers because I saw I was just re-typing the same stuff again, and there was a fair bit of re-use possible. After a few iterations I refined it and came up with something i'm pretty happy with. Basically it's a typed and tagged data structure which can be encoded in such a way that it can only be decoded one way. It is a bit like BER encoding but stripped to the bare-bones without any of the complication only a committee and the requirement to solve every possible conceivable future use can provide. But I can also include custom objects for efficiency or convenience sake.

So this defines the syntax - defining, encoding, decoding, and access.

But the semantics are completely separate and are defined by the application. This is very important as for example it allows me to create messages with variable content or new messages that the client/server can ignore if they wish - without breaking the protocol exchange.

DuskMessage

So I basically have a thing called a dusk message, and every dusk message has a type and a name. The type defines the container, and the name is application specific. They are encoded on the wire as 2 separate bytes, limiting each to 256 which is more than enough for an application-specific protocol.

DuskMessage {
    byte type;
    byte name;
};

This on it's own is enough to pass simple notification messages that require no arguments. Then there are the simple types, which includes byte, short, int, long, float, and string.

ValueMessage<T> {
    DuskMessage;
    T value;
};

And I created a couple of list types, one is just a list of strings, and the other is a list of DuskMessages (i.e. 'any's) which is how more complex datatypes are created without requiring custom types.

ListMessage {
    DuskMessage;
    List<DuskMessage> value;
};

(etc, you get the idea)

List are just encoded in the obvious way - a length (short), followed by length-items of the DuskMessage. I've got some simple accessors like getByte(int name) and so on for easy client use.

There are also some custom types such as the map and entity updates which occur very frequently which should benefit from the reduced protocol and run-time overhead. I just hard-coded these into the system but with a small amount of work it would be possible to turn it into a reusable and extensible library where customisations were provided by the application code.

And finally I created another copy of all of these which also contain an ID - for messages which are intended for a specific Entity. They don't occur very often but it provides a bit more flexibility and efficiency for a small coding overhead.

Of course when I went to use it there were bugs in my code so I then wrote some protocol dumping routines which dump to a human-readable format. As a human never needs to read it other than for debugging there isn't much point sending a human-readable format for any other reason.

DuskProtocol

The semantics are then defined by the DuskProtocol interface. This is just a pile of integer constants which define the names to use for objects. Any class in the client or server that wants to use the constants just 'implements' the interface to gain access to them. There are two sets of constants.

MSG_*

The message constants define the message type and are set on the name of the highest level message. For simple types this is all they contain but the list can contain others. I decided to make these globally unique, although they could also be made unique-per-container-type. I tried that at first but it just got too messy and complicated to manage to make it worth doing. The more I worked on this the simpler it got, which is always a nice side-effect.

FIELD_*

The field constants define fields in compound (ListMessage) messages. These only have to be unique to each message type. I initially tried to work on creating a global namespace for them where I could pick and choose what to include but that just complicated things again and all it did was save some source-code space and one-off typing. I will move to per-message or at least related-groups grouping, and start each group at 0. Otherwise it's just unmaintainable.

So for example the player info update which is the most complex message (all the str/dex and so on) has some constants like:

    public final static int MSG_INFO_PLAYER = 15;
  ...
    public final static int FIELD_INFO_CASH = 0;
    public final static int FIELD_INFO_EXP = 1;
    public final static int FIELD_INFO_STR = 2;
    public final static int FIELD_INFO_STRBON = 3;
  ...

Currently i'm sending all of them every time - as the previous version did - but I can cut out things which aren't changes now, without having to change the client code (if i implement it the right way).

I did have a thought of having the server send some meta-data in an initial protocol exchange (say, allowing symbolic names for all messages and fields), but what the fuck for? It's already engineered enough to work, it doesn't need more than that.

So why bother/why not use another library/etc?

Firstly i find this kind of problem solving fun - it's just a never-ending puzzle trying to aim for a good solution knowing there are always trade-offs.. I've also done it quite a few times in the past - from LDAP which uses BER, to object serialisation in Evolution/camel, to using BerkelyDB, and plenty of other places besides. It just keeps cropping up and although I know this wont solve every problem it works for this one.

What I don't find particularly fun is learning how some behemoth general-purpose library works in the first place, let alone learning it's bugs and limitations. Even something as "trivial" as json requires some rather large library, and with all that it doesn't even interoperate reliably without fucking around.

For the application itself, as mentioned having a protocol with atomically-decodable messages allows for extension without completely breaking the protocol.

Having dynamic messages means I don't have to write code to handle dynamic messages into a custom protocol; it's already provided. Field access requires code for each field, a general list can be iterated - potentially reducing code required too. All the parsing and i/o handling is done and all I have to do is use the objects or their accessors.

It also means the encode/decode is in one place, and not scattered throughout the code as printf statements. So I can also force encapsulation at each end by forcing communications through this choke point. Which provides all sorts of benefits ...

... such as if i should decide to change the wire protocol in the future, or more likelty to support "web friendly" text-mode protocols.

In DuskZ

So I didn't just design the protocol syntax last night (ok it stretched into the night a bit - nothing on tv), I implemented it and changed DuskServer and DuskZ to use it. And debugged it enough to the point that you can log in and play some of the game ...

At this point the client is still talking the original protocol outward (i.e. a command line!), but I will need to change that to support some required features. For example scripts are able to ask the user questions but at the moment do some really nasty hackery like telling the client to pause, then ask the question, then flush the incoming stream, then hope it got it right. That can all go.

And the server protocol still has the same basic structure with only some minor tweaks.

There are other messages which could be combined in a more general 'update some object' type message. e.g. set range could become an optional field in an 'update player' message (although it looks like range isn't sent anyway). And others that could be combined for other reasons, such as wanting an atomic change of state, such as entering a battle - rather than sending a bunch of messages for each individual entity. Fortunately with the simple design I can just as easily embed messages inside a list as a field.

I also had a think about the auth protocol - right now it just creates a new user if you didn't exist, but it might be useful to get the player to confirm their password, and also go through the "new user" stuff like choosing a race all in one go.

Before i commit I want to clean up some of the naming conventions (netbeans refactor tools have had a work-out this week, although they're not bug free they work surprisingly well with 'broken' code), see about moving some of the fields to grouped messages, and change the login stuff. The login stuff goes a bit deeper so will require more work.

Update: So I managed to do most of what I intended - boy it was a lot more work than I thought. Getting the login working at both ends took a bit more thinking than I expected, but I managed to fit in a query mechanism that lets the game query the user for arbitrary values (currently: an item from a list) and the same convention is used during user creation to ask for whatever is needed. It took a while to work out how the current code needed it all to work too, and then I merged some of the message types (e.g. resize map + update images became map init), and then had to fix the client. It isn't quite done but it's enough to login and play around a bit.

Here's a protocol dump of the client creating a new user. It still goes through the same single login window I did before, but the client behaviour can be altered quite freely without changing the protocol. e.g. it could instead show 'unknown user', with a button for 'create' which runs a setup wizard locally, and then creates the user at the end.

sending: MSG_AUTH ListMessage name=0 value = {
        StringMessage name=3 value=x username
        StringMessage name=4 value=x password
}
state=Username: MSG_AUTH ListMessage name=0 value = {
        ListMessage name=2 value = {
                ListMessage name=0 value = { name = name of response string below
                        StringMessage name=0 value=Choose race
                        StringListMessage name=1 value= {
                          'lizardman'
                          'ork'
                          'indian'
                          'demon'
                          'elf'
                          'darkelf'
                          'halfling'
                          'dwarf'
                          'human'
                        }
                }
        }
        EntityIntegerMessage id=-1 name=0 value=3
        StringMessage name=1 value=Insufficient information to create player.
}
sending: MSG_AUTH ListMessage name=0 value = {
        StringMessage name=3 value=x
        StringMessage name=4 value=x
        ListMessage name=2 value = {
                StringMessage name=0 value=human name = name of choice above
        }
}
state=Username: MSG_AUTH ListMessage name=0 value = {
        EntityIntegerMessage id=195 name=0 value=0
        StringMessage name=1 value=Login ok.
}
state=Ready: MSG_CHAT StringMessage name=7 value=DuskZ Server 3.0 dev ...

So fairly clean and concise, and no screen-scraping required. And the query can include as many questions as needed, ... or even more complex content with some appropriate glue (such as a web form using the WebView?).

Tagged dusk, hacking.
Friday, 01 March 2013, 02:47

The brain dump

Last night I was pretty exhausted - the neighbours had some bricks delivered around 7am which woke me too early after what was a pretty lousy night of sleep. I got up with the idea of turning off the watering system (starts at 7am) after it had done the pot plants and kind of forgot about that and ended up hacking for nearly 15 hours straight.

Ok so it was probably a bit obsessively intensive, but i'm pretty surprised I still get such a level of buzz out of hacking code after 25 years of doing it for fun. In terms of effort and intensity, it could have been any other xmas holiday from any of those previous years. On the other hand i'm writing more and better code than ever before because the platform is fuller than ever before. The only downside is that I can't keep up the intensity for as many consecutive weeks as I used to and end up with aches and pains from sitting still for so long.

But as I intended to take a bit of a break for a few days I thought i'd jot down some feature ideas, todo's and wishlists in my engineering notebook (a paper one) while the ideas were still hot.

As I wrote things down my memory started to vanish very rapidly - as if waking from a dream. I got the main feature points down fairly completely but I was pretty stumped at the todos. Although only minutes before I had a mind full of all those little refactoring, renaming, and tweaking ideas for improving the codebase, by the time I went to write them down I drew a near blank. I've experienced something similar before when I left the Evolution project; as I wrote all my knowledge down all the anxieties from keeping track of the 'known bugs' and 'future plans' in my head just melted away. But it wasn't quite so abrupt, although both instances were very cathartic. To be honest i'm still surprised I can keep so much in my head for weeks at a time - when I often forget where I put a screwdriver only a minute prior.

So it was a very good idea to write it down and let me get a good nights sleep. And although my brain is now bereft of most of the details I managed to write most of them down, and i'm sure the others are in the source as FIXMEs or will come back when I get into it again - if they were important.

Tagged dusk, hacking, philosophy.
Friday, 01 March 2013, 00:38

Scrollbars!

So apparently one of the side-effects of the touch-interface 'revolution' is the abolishment of scrollbars.

Well fuck that for a poke up the arse with a glowing poker.

Even before the latest firefox came along with a serious bug on my *ainol tablet (I love it, even the the logo includes a diagrammatic anus) which makes it almost unusable - flicking the screen normally-but-not-always makes it flick in the wrong direction - this no-scrollbar idea makes the device itself very clumsy for reading any web pages more than about 3 screens high. The android browser is just the same. And given some of the pages I read are dozens of pages long, i'm faced with a usability nightmare.

Just bring the friggan scrollbars back ...

It's probably related to another annoying "web 3" feature - infinite scrolling screens that load on demand. They might solve a technical problem and have a bit of 'wow' factor, but they are not a usability improvement. And they kill some pretty important features we've come to expect like searching within a page. But I suppose we have to get used to this sort of dumbing down of the internet - such a big chunk it is all about advertising wrapped in entertainment; not learning, education, or information.

While i'm ranting about firefox mobile i find it pretty much a pain to work with even without that killer bug - there are too many small buttons too close together, the tab system is really annoying, as is the click-to-title-bar-to-go-to-another-screen thing, with the popup keyboard always getting in the way. It has a habit of zooming far too often when I go to move around - a mis-fingered 'scroll' turning into a 'press'. If we already have a two-finger zoom, why not bloody stick to it? I just don't see the point of overloading gestures to the point of confusion. Well here's two fingers for the designers: Y, and while i'm at it: !). Mouse/keyboard users have other mechanisms for this.

The whole point of "touch" is it is supposed to be natural and "intuitive", but if you have to concentrate hard every time you try to press on something it has lost any edge it had.

I don't really know the answer for the tiny-button-problems as it would need some serious thought but for all the serious thought the UI designers have put into the current offerings they still have a distance to go. The only practical thing I can think of from the top of my head is an icon/menu bar which POPS onto the screen (doesn't slide, doesn't fade, doesn't push the content over to one side, doesn't fucking animate) and has nice big buttons for the most useful functions. You know, like the microsoft 'charms' thing, although it sounds like they overloaded 'gestures' to the point of absurdity (i'd really like to know what that dickhead in the 'clean up the party' ad is supposed to be doing when he draws a circle and a line on the photo near the start). Gestures suck because they're completely non-discoverable and require a lot of practice to get consistent with.

But pressing inside a page should be reserved for links or focus. Not for zooming-sometimes-in-sometimes-out. It's just too easy to do it by mistake.

Inflexion points

Hmm, and on a completely unrelated note, I think i've hit one of those inflexion points where I suddenly change a food forever. It's getting close to the point where my coffee goes black, strong, sugarless. I use a Baletti stove-top coffee maker which makes great coffee easily and cheaply and with the right coffee, amount of milk and temperature it's pretty near to a decent 'bought one', but it's a bit hit and miss. Yesterday I ran out of milk and although I usually can't stomach the black coffee I managed ok. About the time I started using one of these machines my coffee went sugarless - I can't stand even a small amount of sugar now. Although a little sugar and milk is still needed in tea, but I don't drink that as often.

It reminds me that one day after having had cornflakes every morning for breakfast for years I suddenly decided it was too sweet and decided I vaguely remembered vita-brits being pretty nice. Can't stand cornflakes now, although I could probably go some sugarless vita-brits once in a while. Although these days breakfast is usually left-overs, coffee, toast, or often just reading my morning round of blogs and organising my on-screen workbench.

Hmm, my nice neighbours are getting some work done in their yard next to this room, I should go mow the lawn or something before I get rooted to the chair for another day.

Tagged biographical, rants.
Thursday, 28 February 2013, 11:46

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.

Tagged dusk, games, java, javafx.
Thursday, 28 February 2013, 07:38

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.

Tagged dusk, hacking, java.
Thursday, 28 February 2013, 02:06

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!

Tagged dusk, games, hacking, java, javafx.
Wednesday, 27 February 2013, 09:51

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.

Tagged dusk, games, hacking.
Tuesday, 26 February 2013, 09:12

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.

Tagged dusk, games, hacking, java, javafx.
Newer Posts | Older Posts
Copyright (C) 2019 Michael Zucchi, All Rights Reserved. Powered by gcc & me!