Showing posts with label wherigo. Show all posts
Showing posts with label wherigo. Show all posts

November 24, 2008

fun bits

a.k.a. OpenWIG bugs worth mentioning, and their respective cartridges

Srnčí důl:
the official Players call "OnSet*" before performing the setting. I.e., when you set task.Complete = true, then the player first calls OnSetComplete and only after that actually sets the variable.
The OnSetComplete event in Srnčí důl (Roedeer deep), for some wicked reason, checks for this behavior: if task.Complete == false then (do stuff) So if at the moment of calling OnSetComplete, it's already Complete, there be failurez.

Blair Witch:
so I took the latest and greatest version and headed out, to try and play this cartridge, which is probably best one in CZ, and also the most complex one. So it was kind of baptism of fire for OpenWIG. Plus, this time, i was a member of a group equipped with Colorados, so i could check the behavior against the "right" one.
Found two bugs. In one, i could see all my virtual companions long after we left them behind in a dead zone. The other, at first i didn't think that it's a bug. I just completed a simple task ... then all the coloradists spent half hour trying to complete the very same task and failing spectacularly.
Both bugs were rather easy to find and remove.
First one: when a zone deactivates, it stops evaluating position events. That means that if you deactivate a zone in which you stand, as far as OpenWIG is concerned, you'll stand there till the end of days. Because it will never again check if you are inside or not. It just remembers the last state.
Fixed by forcefully removing a player from a deactivated zone.
Second: in the mentioned task, you have to carry an object outside of an invisible zone that envelopes the visible zone in which you start.
The respective event asks if invisibleZone:Contains(Player). Welll..... Yes, if the zones overlap, the player can be in more than one zone at once. That works fine. But when doing that, I apparently overlooked something: it doesn't go the other way around. Player is in multiple zones, but only one zone Contains() the player. So when i was in the inner visible zone, the event never found out that i was also in the invisible zone, and let me throw the task object away without hassle.
Fix was fairly trivial, i just needed to override zone's Contains method... ah, why would i write all this, you can figure it out.

...and for a time, it was good...

Petřínská Wherigovka:
This cartridge also has that habit of deactivating zones that you stand in. But it turns out that when fixing the problem from Blair Witch, i overlooked something again.
There are two internal states for a zone: contain says whether you are present in (close to, distant from) the zone, and ncontain aka "next contain" says whether you are going to be present in the zone in the next five seconds, unless something happens. So most of the time it's the same as contain.
When "forcefully removing" the player, i reset the value of contain, but not ncontain. In the next timestep, zone realized that the player is going to be inside it real soon, and invoked the OnEnter event.
Which had a rather lengthy dialog. Which ended in a question. Which, if answered correctly, would deactivate the zone. Which would lead to another OnEnter... you see where this is heading.
Also i found out that even when the zone is inactive, quite a lot is going on in it.
So i put a stop to it, and that's the end of this nasty little bug.

...or is it?

May 22, 2008

openWIG status report

Version 0.2.99 was released sometime this night, as opposed to what I wrote last week.
It has pretty navigation and crude but functional reading from filesystem. Everything important is on the project page, follow the link on your right.
...oh, and did I mention that we can now decode the GWC format? Well, we can. Feel free to load your memory card with cartridges and head outside.

April 18, 2008

news

OpenWIG development finally slowed down as I approached the more difficult problems - zone and distance detection.
However, they now seem to be finished and working nicely on my SE K610i.

I even implemented "slow hysteresis" to compensate for GPS fuzz: when you are about to walk into a zone (where "zone" is not Wherigo.Zone, but a well defined area, e.g. the proximity space around a Zone, the inside of a Zone, or maybe the space so far away that it's even outside the DistanceRange), OpenWIG waits for five consecutive position samples that confirm your position in the new zone, and only then acknowledges the new position.
It's too late for me to be able to explain it in simple terms, but it actually is simple. And it works surprisingly well, at walking speed at least. But it is five seconds slow. I'll see what I can do about that.

Version 0.2.4 includes precise zone detection, distance detection, OnProximity and OnDistant events (last two from the "basic set" that is used in every other cartridge)

...and... (drums, please) navigation!
Yes, ladies and gentlemen, OpenWIG will now tell you exactly how far away are you and what direction you should take. The instructions are still rather crude, and they are displayed even when you are inside the zone (you can just disregard them, they don't mean anything inside a zone. i use them for debugging), but it does work.

Get it while it's hot!

April 10, 2008

they are on to me!!

[panicks] Yaaaaaaahh!!! They're coming! ... must ... keep ... ahead .... !! [panicks again, runs around in circles]

In other news, OpenWIG 0.2.3 is out and it supports various kinds of Inputs, as well as few more dummy functions.

April 7, 2008

OpenWIG: GPS support ready, gwc format possible

Version 0.2.0 of OpenWIG has crude support for Bluetooth GPS modules. Plus a Play Anywhere mode, so you can play the included Zooventure Level Two regardless of where you live.

In other news: misch of geocaching.cz said that the gwc format doesn't look at all difficult to him. And that he would probably be able to decode it.
That means that OpenWIG will probably have support for original Wherigo Player cartridges, and that means that you will be able to play full-featured Wherigo on your mobile phone!
Isn't that just wonderful?

April 5, 2008

expert at making things more complicated

Oh Me Oh My.

For whatever reason, Wherigo is designed in a way that perfectly maps to J2ME's gui handling. Commands, actions, dialog boxes, it all looks like somebody designed it to work in a midlet.

Except for one thing.

To quote Wherigo Advanced Concepts on the subject of MessageBoxes and Dialogs:
The Wherigo Player automatically cancels any message box that is buried by another user interface element. This means that the message box will not remain on the screen even after all other UI elements have been closed. However, the message box script (if one exists) will still execute. The author can override this by creating a condition to specify what should happen if the 'Cancel' button is pressed. These conditions will work regardless of whether the player intentionally presses 'Cancel' or the message box is automatically canceled by the application.
Funny, I thought, this is going to be rather tough. You have to keep a return value from the message box, but anything can close it anytime. Hello and welcome aboard, race conditions. And what's even better, Lua VM is thread-unsafe. And it would be dumb to lock the whole VM for as long as the dialog is on, because that can be quite a long time.

On the other hand, it's quite a dumb idea to automatically cancel the dialogs when another comes. What if the user doesn't have time to read it? But ... who am I to judge :P

So let's restate the problem.
  1. Midlet UI works in non-blocking, fire-and-forget mode. Which is basically a good thing for an UI to do, but...
  2. ...we need to keep return values. Therefore we must block on the dialog.
  3. Anything can close the dialog anytime. I.e., another thread must tell the first one to continue.
  4. Lua VM is thread-unsafe, therefore the two must somehow arrange locking. Plus locking of the dialog threads, because a third dialog can come at any time and kill the two.
I devised a clever scheme, where the VM is locked by a mutex (did you know Java doesn't have mutexes?), but the dialog unlocks it, and after it's canceled, reacquires the lock. Plus some regular java synchronization stuff to display the dialog properly, make it block etcetera.

Strangely enough, it worked, and it worked really well.

Too well, actually.

I apparently missed some of the Advanced Concepts.
in Wherigo, a message box does not pause the cartridge. Instead, the game continues to run while the message box is still displayed on the screen.
Just like midlets do. Fire-and-forget, anyone?

It actually does work like that. Dialog is put on screen and the script continues happily on its way. Return values? No sire. There are callbacks instead. Who could have thought?
(anyone who would try it in the builder ... oh well)
In fact, the very Wherigo Level Two cartridge I use for testing is relying on this "feature". Instead of if/elseif conditional blocks, it just displays messages over one another, stopping at the right time.
I was very surprised that OpenWIG showed more messages than the emulator. I even thought that it's a bug in the emulator, or some kind of unspecified if/elseif handling - which would be very, very bad.

Nope, none of that. Once again, I made the problem more difficult for me. If I didn't want to do it "properly", it would have been easier, and correct at the same time. Folks at GroundSpeak apparently don't do things the "proper" way, but the "practical" (easy for the programmer) way. I'll have to get used to it.

But auto canceling the dialogs? Come on. That is dumb. Really.

Wherigo midlet ... or is it?

Once upon a time, there was Wherigo. It was closed-source, closed-format, and worked only on PocketPCs (and some kind of obscure navigation device). It did not work on cellphones and the developers apparently weren't interested in making it work.

Turns out, however, that the Wherigo Builder produces plain Lua source files. It can't be too hard to make that work on a mobile phone, now can it?

Well, let's hope not. Enter matejcik, who just recently bought a bluetooth GPS module to use with his phone. And whose idea of fun is, among other things, staying up late (or early, you might say) coding weird stuff.

Working name of the project is OpenWIG. As of now, it can run nearly all of Zooventure Level Two from the tutorial.
No GPS connectivity yet, but you can input coordinates by hand. I might keep this feature, as it would enable folks without GPS-enabled mobiles to play. Then again, I might not - you know how things go, cheaters are everywhere and this would only make it easier for them.

You can't load your own cartridges yet, and you will probably never be able to load gwc files, as the format is closed and I have no experience in reverse engineering. But once the loading functionality is there, I will probably set up a web service that would take your sources and compile them to OpenWIG-friendly format.

Heart of the midlet is called Kahlua and it is a Lua virtual machine for J2ME. It eats Lua 5.1 bytecode compiled files and works pretty damn well, considering its size. It is also fast enough on all phones I tested.
(Then again, it's not like the Lua scripts in the cartridges do a whole lot of work. Setting variables, conditional branch here and there, that's about it.)
And as an added value, the guy who wrote it was very helpful and the (two) bugs I reported were fixed immediately.

No download link today, but you can find some testing versions in this thread (in Czech).

Update: check out OpenWIG's Google Code page.