davidn: (ace)
As it's been at least eight hours since I mentioned this last, I want to mention that the MBTA officially launched their real-time bus information yesterday, which hopefully means that future feed updates won't break this entirely any more. I would now be very grateful for the inclusion of the CT2, if I hadn't moved house and therefore passed the point where it would be useful to me in the time it took to get it up there.

They now have an application showcase, and I'm in it with a reworking of my bus tracker in a mobile-friendly page called Track the T. I was also given a passing mention on boston.com for it yesterday (I had wondered why the 558 seemed so disproportionately popular compared to the other routes). The addition of a Facebook button does wonders for addictiveness of checking its popularity - about 30 people have shared it so far and I haven't even promoted it myself yet.

Speaking vaguely of other works of mine (but unrelated in reality), I'm thinking of entering the inherently mockable Kamelot "Poisoned Pen" poetry competition with an expectation-defying meta-epic in limerick form, ending with the line "Roy Khan do what Vanderbilt Khan't". But it'll need a bit more fleshing out before then.
davidn: (rabbit)
Have I mentioned how much I love MMF recently? Ever since I discovered it through its predecessors, I've just taken it completely for granted that I can put sketches of applications together almost instantly without needing to worry about the underlying engine, and it can do a surprising amount in terms of complexity before it begins to get unwieldy. If regular programming languages are a blank canvas with which you can do anything, and most game creation systems are colouring books, MMF just hands you some brushes that might be a tiny bit large for very specific situations. (While ZZT gives you some potatoes.) And in theory, soon you'll also be able to change the export settings and have things immediately in Flash and Xcode (although the instantness of them may be some way off yet).

Blame it and the fraction of a gestalt entity known as [livejournal.com profile] teogames, then, for this (if it makes you or me feel any better about it). When a discussion about a sliding puzzle on Professor Layton got started, I recalled that I had gone as far as to write a tree-based solver to get past it for me. I then realized that in the solver, I had the perfect tool with which to create my own diabolical challenges and verify they were at least possible, and a competent recreation of the puzzle style was done in just over an hour.


I'm not really sure how I got here


I have called this FISP for now. Three of the letters stand for "Impossible Sliding Puzzles". Drag the shapes about with the mouse, with the aim of squeezing the yellow one around to the goal space - the one available level is what I would consider one of the easiest puzzles that I'm going for with this project, and it's solvable in at most 19 moves.

The dragging of the shapes is still a bit tuggy if you get caught on other shapes... I'll have to put a bit more effort in to get rid of that.
davidn: (prince)
This is something I wrote for Clickteam's site as a summary of what people could expect from the Flash game sponsorship market. I should warn that it's fairly immense even by my usual standards, but if you're not interested in the process - I sold a Flash game! CannonBob is the first game-related thing that I've sold on to a larger entity.

And this is how it happened... )
davidn: (prince)
Marking about the fifth game that I've released since starting my alleged current project, I battered this puzzle/observation thing out in MMF over the last week after taking the concept from a game that I was doing for another site. Buying the Commodore 64 book had got me in something of an 80s mood - I came up with the entire "storyline" for it on Tuesday morning and it was done by Friday. I wanted it to be a bit... crazier and take itself less seriously than some of my other games, striving for a mood that was something like the random shareware games that I was fed on while growing up.


Special Agent Bunnet versus Doctor Dishwater


The aim is simple, as described in the story - deactivate the bombs by finding the buttons that don't have duplicates anywhere else - but the field you have to search through gets gradually larger throughout the game. About ten people have reached the end so far - one of them in four minutes, which surprised me as my own record's closer to five. Hopefully it's the kind of thing that you can use to distract yourself for lunch - then to forget that lunchtime ended an hour ago.

What I'm interested in is whether this sort of anti-pairs game is something that anybody's done before - it's such a simple idea that I feel that they must have, but I can't name anything myself (though perhaps you could argue that it's just a variant on the hidden-object click-em-up genre).

I'm also aware that this game's title starts with "Special Agent", further cementing the theory that I only have three game titles that I'm going to be using for the rest of time.
davidn: (prince)
This week I received a rectangular anachronism through the post. I had suddenly remembered about the very first programming book that I had ever seen, the catchily-titled The Times Book of Computer Puzzles and Games, and had gone on a search online for it a couple of weeks ago. I was surprised to find the 26 year old book still available, and now that it's arrived, equally surprised that it's in such good-as-new condition. It's a collection of program listings for little Commodore 64 games that were sent in to the Times, aimed at computer hobbyists who might want to try them and pull them around - an open source X-Box Live Arcade of the 80s. Of course, it arrived with the notable lack of the accompanying tape (though now that I come to think of it, I'm not sure what I expected to be able to do with that these days) so I was going to have to put some effort in myself to bring these things back to the world.

After looking at the first few fragments of Commodore BASIC, my initial overwhelming feelings of nostalgia were quickly replaced with wondering how on earth people used to seriously program with this. The C++ family, so incomprehensible to people who look at it for the first time, seems beginner-oriented compared to having to POKE seemingly random collections of numbers into memory, keeping track of variables with names like ZC$ with no concept of scope. And when a program begins (as one does) with "GOTO 10051" followed by "GOTO 204", you know it's not going to be easy to follow the program flow.

To avoid all this, I had hoped to take advantage of some modern inventions that would save me from the traditional method of clunking through thousands of lines on the Commodore's tank-like keyboard, but the first attempts at OCR on the book's tiny 80s typeface came up with this masterpiece:

1 OTH OHUNTING 10iO RESTORE
? RIH OOPYRIGHT J. R. JOOKSOO
5 OOTO IGOS1: REM GETOP 1OEO E$=“
K9? GOTO QO4 ” l
BOO X3=G(ZP+481 1025 LET H$=“ ABCOEFGHIJK ”: LET IS
?O1 X4¤INT£X3{25b1: X3=X3·256*X4: PO =" OBOOEFGHTJK “
EO4 REO EMO OF NOTE SOBROOTINE 3
1GGG RER SHOOTING
1005 REM ? J. R. JOEKSON
100? OIR X${501: DIM PANTS OF 112O DATO 255,56,36.255,255,255,0,0


So I took that as a message that I was going to be typing these in by hand. Fortunately, some wonderful person has developed an actual Windows IDE for the Commodore 64, so that you don't have to use the actual machine's more... eccentric layout, and (for example) have to remember that "Inverted heart, inverted pi, four inverted Qs" means "Clear the screen and get ready to type somewhere". After about forty lines even in that, I was beginning to appreciate how little I actually missed the program distribution method of typing in twelve columns of code character by character, knowing that you don't have a debugging method if a single character is wrong, and armed this time with the author's name, successfully found tape images of some of the individual programs, including the one I was attempting (but I'll have to provide most of them myself).

SHUNTING, then (and neither OHUNTING nor SHOOTING - or to give it its full imaginative title, "Train Shunting Puzzle"), is a Laytonesque little conundrum set by the Reverend J. R. Jackson. In it, you start with a train in the siding, some carriages in the depot and some trucks in the station, and because British Rail only has one train capable of movement at any one time, it's up to you to trundle around connecting and disconnecting the carriages with the aim of swapping the trucks and carriages round and leaving the train back where it started. Just to top it all off, the right side of the screen is taken up by a tunnel which only the train can enter, for reasons that are left unexplained.

And I'm proud to say that - after setting the emulator speed up to five times normal to prevent being driven mad by the little animation every time a move was made - I successfully did it, in only about double the moves he expected me to. I'm not entirely sure how I did it, either, I just seemed to rely on luck - but solving it at all is good enough for me by this point, seeing as if we measure from the first time I ever saw it, it took me roughly twenty-one years.
davidn: (skull)
UPDATE lcmr.content_relationship SET content_entity=
(
	SELECT TOP 1 ce_id
	FROM lcmr.content_w_xms_name newContent
	WHERE newContent.content_type=130
	AND newContent.xms_name='Badger Mushrooms'
	
)
WHERE id IN
	(
	SELECT lcmr.content_relationship.id
	FROM lcmr.content_w_xms_name newContent, lcmr.content_relationship
	INNER JOIN lcmr.property_value
	ON (lcmr.content_relationship.id=lcmr.property_value.id)
	WHERE property=13
	AND lcmr.property_value.content_instance NOT IN
		(
		SELECT pvForExisting.content_instance
		FROM lcmr.property_value pvForExisting,
		     lcmr.content_relationship crForExisting
		WHERE pvForExisting.id = crForExisting.id
		AND pvForExisting.property = 13
		AND crForExisting.content_entity IN
			(
			SELECT TOP 1 ce_id
			FROM lcmr.content_w_xms_name newContent
			WHERE newContent.content_type=130
			AND newContent.xms_name='Badger Mushrooms'
			)
		)
	AND (newContent.content_type=130
	AND newContent.xms_name='Badger Mushrooms')
	AND content_entity IN
		(
		SELECT TOP 1 ce_id
		FROM lcmr.content_w_xms_name oldContent
		WHERE (oldContent.content_type=130)
		AND oldContent.xms_name='Cow Exploding'
		)
	)
;
DELETE FROM lcmr.property_value
WHERE id IN
	(
	SELECT pv.id
	FROM lcmr.property_value pv, lcmr.content_relationship cr
	WHERE pv.id = cr.id
	AND property=13
	AND content_entity IN
		(
		SELECT TOP 1 ce_id
		FROM lcmr.content_w_xms_name oldContent
		WHERE (oldContent.content_type=130)
		AND oldContent.xms_name='Cow Exploding'
		)
	)
;

A masterpiece. (This is just one of them - it has to do all this about 32 times for different locations.)

Note the fair amounts of repetition - SQL is not my strong point, and this probably does things 100 times slower than they could be. It might be possible in about four lines, I don't know.
davidn: (rabbit)
I was at a meeting with the department of transportation yesterday evening - I'd found a reminder about their invitation to developers when I went to look for updates on the bus feed, and went along to find out what the other people working with them were doing. It was the closest to a suited board meeting that I'm ever likely to get - it was held around a long table in a dimmed conference room, with a whiteboard in a cabinet and everything, at the top of a tower after everyone else had gone home, like being part of some secret transportation illuminati. No, of course it wasn't, it was just talking about buses and how to improve the information that we gather from the feed, but you've got to allow me some sort of illusion of importance - particularly as there were some things discussed that we were asked not to mention to anyone else just yet, because the plans for them aren't quite worked out.

In the morning, I got an email from the manager who'd organized the meeting, saying he'd looked at my bus tracker, that he himself had used it in the past and that I should be promoting it more. So I'm going to finally get a few real domain names for myself, including one for the tracker specifically - I just need to work out what to call it. Track the T? Watch the T? MBTA-watch? BostonBusTracker? wheresmysoddingbus.com? I'd welcome any outside suggestions.

Later the same evening, I got the chance to actually see it working for the first time - from the flat and in the office, I'm nowhere near any of the buses covered by the available routes, but yesterday we were in a cafe with the 66 bus route right outside through the window. From there, I could load up the countdown page on a borrowed iPhone, and just look at it when there was about a minute left and say "There's going to be a bus going that way behind me... now". >Zoom.< (Actually, that's not really an appropriate sound effect for most of the buses - it should be more along the lines of "Wheeze, cough, splutter", but that's not as impressive.) It sounds like such a little thing, but after just having to wait blindly to be picked up for so long, this thing is like having a window into the Matrix and seeing how it's working underneath. It feels really special to be one of the few people who know that it's available just now - but my duty now is to remove that exclusivity by spamming it around to as many people as possible!
davidn: (Jam)
Coders, help me out by confessing so that I'm reassured I'm not the only one...

If you're working on a project that has a significant compile time (say, five minutes or so), and you set it going and then realize that you've forgotten to change one thing that you want to get in... do you stop it, or do you - as I do - seize the opportunity to prove your superiority, leave the compile running, zoom to the file in question, and race the computer to make the change and save the file before the build grabs it?
davidn: (ace)


Don't fall asleep with excitement, but - remember when I posted about the Massachusetts department of transportation making some of the bus locations available to people? They added twelve more routes to the trial feed last week, including one that Whitney uses to get to work. So I spent an evening working altogether too hard on the bus arrival time tracker that I'd previously done up for it - it's now been included in its own section on my site. You can give it a try here, for example:

http://www.clickteam.info/davidn/mbta.php?stopId=927&routeId=66&update=true

I haven't really made the Javascript updating very robust yet, which is why it's still only an option in the URL (it just counts down from whenever the page was loaded, without checking the actual feed again) - but it looks nice!
davidn: (rabbit)
My giant floppy ears were alerted to a promising development in the MBTA yesterday by the Livejournal community that was set up to moan about its usual ineptitude - they've got together with some sort of national online service provider called NextBus to provide an experimental feed that makes the GPS locations of its buses freely available.

What this means in less dull terms is that it's now possible for people who are web-inclined to tap into that feed and find out where buses are and how long it's likely to take them to arrive at their destinations - and therefore yet another project has been added to my already groaning pile. Only five routes are represented during the trial period and none of them are anywhere near the places I actually travel in Boston, but I spent some time yesterday creating a small page to collect the predictions for individual stops together, then didn't sleep at all due to having some terrible nightmares about buses.

I'm very much looking forward to it being expanded to the rest of the system and taking the guesswork out of the CT2's largely fictional timetable - for now, I've tragically been spending my compile time watching the 111-117 buses race each other to Broadway and Fourth Street remotely via the Internet.
davidn: (savior)
Over the last couple of weeks I've finally been updating my personal page - it was something that it had needed since it was made, really, mostly because it used to be just a big table of stuff that I threw together at random and tried to arrange so that people could find the actual worthwhile bits. I've now replaced it with a list of games I've made (probably the most worthwhile section), music and writing (mostly taken from this journal), categorized to make it easier to pick through.

The new, shorter, still cheap-as-free redirect URL is:
http://www.davidn.co.nr
All comments are welcome.

Some of the other things that were on the old page might make it up eventually, but I've tried to keep to the things that are actually presentable for now. For example, I'm not sure if the older mini-games like Kommon Room Kombat will ever go up - mostly in that case because that one would now probably be counted as personality theft to add to the photo theft that made the game possible. And image sharing sites were invented just after I put together the wedding photo album, so that'll probably be entirely replaced as well.

Indeed, most of the content comes from RSS feeds - the journal on the front page and entire music section are both CSS shells around content made up from feeds from elsewhere. Therefore, the entire Internet is now my database and I am truly one with the Matrix.
davidn: (prince)
Boss monsters are usually a bit of a headache to write. You have to think up a cocktail of attacks, weak points and strategies that are balanced to be difficult to cope with at first but possible to learn through experience, and then write the whole thing's behaviour, which can often get quite complex. As evidence that I'm still working on the game, this is the seventh of the bosses I've made, and at the moment it's called Beam Stack.



The general approach that I'm using for bosses in this game is treating them as loose sort of state machines, with one string called State which is the main thing that decides how the boss should behave at any time, along with a heap of other variables on the object that describe more of the details of those behaviours. By making at least one of the possible actions in each state being to change the contents of State to something else (and having what it changes to possibly dependent on other conditions), the boss can move between behaviours in sequence.

A more in-depth explanation of how it all works, for the benefit of those interested, coders, ZZTers, and the insane )

And all of that goes together to form the thing that you see in the video. After I first set it up it took me ages to get past it the first time, but now I can do it fairly reliably - if other people find the same thing, then that's just the right difficulty of boss I'm aiming for.
davidn: (rabbit)
I have to wonder if solving a completely insurmountable Professor Layton puzzle by writing a program to work out the solution is considered cheating. They throw the original Knight's Tour problem at you, for goodness' sake - you're going to have to offer a lot more than 99 Picarats for me to work that out unaided.


Brute-force, the source )

Output and solution. Completely safe to look at, you'll never remember it )

Additional challenge: Do it in ZZT.

DrumWriter

Mar. 24th, 2009 08:40 am
davidn: (rabbit)
The trouble with having gone with MOD as my music format of choice nearly ten years ago is that almost immediately when I started, it became obsolete and every other popular music package sprang up using MIDI-based formats. Even though you would think that music formats couldn't be all that different from each other, I haven't yet found a MOD to MIDI convertor that does what I need it to (Modplug's own MIDI import and export is particularly awful), which is a problem when I put up tablatures of my songs because I have to convert them all by hand. Often this results in being able to improve on some parts of the original that I might not have got quite right the first time, or introduce a couple of new ideas, but it's the sort of thing that's very programmatic for the most part.

So I invoked my philosophy that the good thing about computers is that you have the tools to automate repetitive tasks on them already at your disposal, and decided that I could at least attempt to get it to lay the groundwork itself and rewrite the drum parts in MIDI for me. So the idea for a new Java project was born in the form of DrumWriter, and the basic plan was simple - find something that could read MOD files, find something that could write MIDI files, and then nail them together into a sort of musical chimera.

Reading a MOD

My first target came in the form of a library called JMOD that seemed incredibly difficult to get hold of even though it came up on a search - the best link I found was to that beta version of it. Almost immediately I came across one of the disadvantages of unfinished open source software, that being that it was unfinished - I spent a while wondering what I was doing wrong while loading my .IT song files until I went in to check exactly what it was doing on loading them, which was to make up 64 completely blank tracks and then return them without so much as looking at the actual structure of the file. I didn't have a way around this because adding that would have required a knowledge of the IT file format, which is what I was using someone else's library to avoid - instead, it's not too much of a bother to use Modplug to save them as the very similar XM files (which JMOD can actually read and not just pretend to) before using them.

The second problem was that the format of the samples within the file wasn't what JMOD was expecting - I'm not sure if this is an oddity of Modplug compared to the original Impulse Tracker or not, but it made it just throw an exception on trying to load them. This was a bigger problem, and I ended up just completely removing all attempts to load any samples from the code and recompiling JMOD into my own patched version, seeing as it was just the song layout that was important to me and I wouldn't actually be using it to play back the file. After those two fairly major obstacles were out the way, I could load in a finished MOD file and run through it to recognize when individual drum samples were played, constructing an internal sort of piano-roll arrangement.

Writing a MID

The second half of the exercise required taking the drum pattern that I'd gathered in the MOD and then writing it out to a MIDI file. My first choice for this was Java's own MIDI library in javax.sound, but I quickly learned that this was not intended for humans to understand - adding notes to a file involves constructing a MIDI message byte by byte and then inserting it manually into a sequence, which isn't the most intuitive of ways to work. (Despite their simple sound, MIDIs are very complex and hold a lot of information - MODs are solid and wonderfully logically laid out by comparison.) After searching for an alternative I quickly came up with JFugue.

JFugue uses a rather unusual string notation that isn't at all far removed from ZZT's idea of a music format, a set of characters that together represent notes and durations (though it also has to worry about instrument, channel, and so on). As you can see from the examples, it even provides special methods for writing percussion tracks, inventing the concept of layers to get around some awkwardness that MIDI usually has with this. It's a free library, but gets you by putting a price on the manual for it, so I just muddled through with the Javadoc of it to help me through. And after some hammering, I got it to generate a set of rhythm strings based on the drum patterns I had from the first step (one for each type of drum), convert those to a combined music string using the relevant drum instruments, and export the whole thing to a MIDI file (a step that took me much longer than you'd expect, because it's curiously a method of the Player class and I couldn't find it for ages.)

The combination of the two

There was one last oddness that I had to get past, and that was in the import into Guitar Pro 5, which uses its own format but can import MIDI (making the entire chain IT → XM → JMOD → DrumWriter → JFugue → MID → GP5). For some reason, the MIDIs generated by my program come out far too fast when imported - and not just in tempo, it was that the notes are treated as hemidemisemiquavers when they should be rather a lot longer. I got around this by simply making the conversion step with JFugue output notes with the duration of crotchets when they should be semiquavers (therefore four times their intended length), which works when imported, though I'm not sure why.



This is part of the result of running it on a song that I'd converted to tab myself previously - the one that I did by hand is the lower score, and the upper score has the same piece of music converted by this new drum writer. As far as the notes played go, they're aurally identical - you can see a slight difference at the end because the drum writer only ever treats anything as a semiquaver (I think Guitar Pro combines long stretches of rests itself), but this doesn't make a difference to the sound because percussion instruments don't have a concept of how long they're played for, and I only ever made them longer in the original version to make the score more readable.

Another problem with its readability is the way that the events on the tab layout below the stave are scrunched up together, without having a line for each drum like I laid them out when I did it myself. This isn't a huge issue because I shouldn't need to edit them a whole lot - it's something that would be nice to correct, but I can't see a way of doing it, because representing drums as a tab is a feature of Guitar Pro 5 that I can't directly save when I output a MIDI, and it seems to just put the drums in numerical order from the top down on every beat.

The other large detail missing is the dynamics, which are generally handled a little differently in MIDI compared to MOD, but I might be able to just convert them over note by note (GP5 does it this way as well - the more faded a note is on the score, the quieter it is).

Since last night I've also completely misnamed it by extending it to handle melodic instruments in a basic fashion as well - this is the result of running it on a song that I have in progress at the moment, with just the drums, bass and harpsichord parts turned on. For something automatically generated from a completely different format it's pretty convincing.

Expand Cut Tags

No cut tags

May 2020

S M T W T F S
     12
3456789
1011121314 15 16
171819 20 212223
24252627 28 2930
31      

Most Popular Tags

Syndicate

RSS Atom

Style Credit

Page generated Aug. 14th, 2025 05:10 am
Powered by Dreamwidth Studios