Jump to content

Play Anywhere?


themonkey

Recommended Posts

Play anywhere is tricky. You have to wait until the cartridge is initialised, which unfortunately isn't yet the case when cartridge:OnStart runs :), and then move all of the zones by an amount equal to the distance between where you are and the theoretical cartridge starting point. This typically requires a timer which expires after 1 or 2 seconds, and you put the zone move commands in the OnClick handler.

 

However, because those commands require arithmetic, you can't write them in the Groundspeak builder. You have to build a chunk of code and paste it into the cartridge just before you compile it.

 

Earwigo has a function to add play-anywhere code when it generates the Lua file - you just pick the "Play anywhere" option from a dropdown list.

Link to comment

There's an odd section of code I use in Whack-A-Lackey to hook into the OnStart method. I saw it the tutorial cartridge's code:

for _,v in pairs(_G) do
if Wherigo.ZCartridge:made(v) then
   --Your OnStart code goes here.
 break
end
end

This isn't placed in any sort of method; it's just inline code in the Author Functions section. It's odd because it references an array variable _G. I haven't tried to figure out what _G contains, let alone its type. However, this does seem to work properly for determining if everything has been created.

Link to comment
There's an odd section of code I use in Whack-A-Lackey to hook into the OnStart method.

Interesting. Does this code runs after the cartridge's OnStart handler? Perhaps the inline code runs after whatever code is in the "require Wherigo" command.

 

Edit to add: it works! That's really cool. It means I no longer need to use a timer to wait a couple of seconds until everything is initialised. And 40 lines of PHP code less to maintain.

 

Further edit to add: You don't need that "for" loop. You can just place your play-anywhere code, or any other code that you want to run when the cartridge starts, in line. It can probably go anywhere, although the obvious place is in the Author Functions section. I'm tempted to say "duhhhhhhh" at myself for not thinking of this about a year ago. It's a pretty straightforward thing to imagine that code which isn't inside a function, will run at startup.

 

This opens the possibility of making play-anywhere cartridges within the Groundspeak builder and without losing any code when you carry on editing. You just need to have the start point set to

cartXX.StartingLocation = Wherigo.INVALID_ZONEPOINT

(in fact this can perhaps also be done in Author Function code, I haven't checked it), and then include lines like this:

local d_latitude = Player.ObjectLocation.latitude - 50.49983	--the non-play-anywhere latitude
local d_longitude = Player.ObjectLocation.longitude - -112.250333333333  --the non-play-anywhere longitude
local d_altitude = Player.ObjectLocation.altitude - 0

if zcharacterCat.ObjectLocation then zcharacterCat.ObjectLocation = ZonePoint((zcharacterCat.ObjectLocation.latitude + d_latitude), (zcharacterCat.ObjectLocation.longitude + d_longitude), (zcharacterCat.ObjectLocation.altitude + d_altitude)) end
--etc for each character

if zitemBox.ObjectLocation then zitemBox.ObjectLocation = ZonePoint((zitemBox.ObjectLocation.latitude + d_latitude), (zitemBox.ObjectLocation.longitude + d_longitude), (zitemBox.ObjectLocation.altitude + d_altitude)) end
--etc for each item

zoneonlyzone.Points = {
 ZonePoint((50.4516706105383 + d_latitude),(-112.228077468871 + d_longitude),(0 + d_altitude))
, ZonePoint((50.4516706105383 + d_latitude),(-112.233077468871 + d_longitude),(0 + d_altitude))
, ZonePoint((50.4566706105383 + d_latitude),(-112.233077468871 + d_longitude),(0 + d_altitude))
, ZonePoint((50.4560559411133 + d_latitude),(-112.229032516479 + d_longitude),(0 + d_altitude))
}
zoneonlyzone.OriginalPoint = ZonePoint((50.4541706105384 + d_latitude),(-112.230577468872 + d_longitude),(0 + d_altitude))
--etc for each zone

 

That's quite a bit of code to maintain, especially with lots of zonepoints, but I've got Earwigo to generate it. :huh: An alternative for the zonepoints would be a function to extract the current point from its containing array, update the coordinates, and put it back. I'm sure someone will be along in a minute to write that (I don't have a Lua compiler handy to check the syntax, and Lua is not on top of my mental stack at the moment).

Edited by sTeamTraen
Link to comment

Pleased to make your day. I'll clarify some things for others:

 

Before, you may have been thinking about the Wherigo code structure wrong. When the cartridge starts, the Wherigo Player actually runs through ALL lines of code, from top to bottom, of the cartridge. This is why the media instantiation is always first, then the cartridge object (it could use media), then zones and other objects in order of what could be added to another (e.g. an item could be added to a character, so character instantiation would come before the items).

 

The functions aren't executed because they haven't been called. Instead, their names and locations are registered. However, when the parser comes across code that isn't in a function (for those keeping score, yes, the cartridge, zone, etc. instantiation at the top of the cartridge isn't in a function), it'll run it immediately. So please, put that type of code at the very bottom of your author function section as a general rule. You don't want to make a mistake calling one of your functions before the parser gets to it (i.e. you don't want to call a function before its definition is parsed).

 

It's my guess that the Player calls an internal function to instantiate (and load) a cartridge. Its return type needs to be a cartridge object. The "require Wherigo" reference at the top of a cartridge, I'm sure, includes all sorts of fun, needed functions. For instance, a function to list all active, visible zones or items and characters as well as functions to save and restore cartridges.

Link to comment

It's my guess that the Player calls an internal function to instantiate (and load) a cartridge. Its return type needs to be a cartridge object.

There's probably no need to call a function. The last line of the Lua file is

return cartMycart

which tells me that Lua's main code execution thread does it all. :)

Link to comment
There's probably no need to call a function. The last line of the Lua file is
return cartMycart

which tells me that Lua's main code execution thread does it all. :blink:

Which is my point. I'll concede the possibility of instantiating a cartridge inline; I guess at that point it's a stylistic difference whether you'd prefer a separate function to instantiate the selected cartridge or not. Either way, after the Player instantiates a cartridge, it needs that cartridge object returned so it can populate the UI.

 

It's fun to guess how all this fits into the Player and how that works.

Link to comment

that's all nice and fun (and obvious to me ;e) ), but now i no longer understand why the code in OnStart won't work in the same way the code in author functions does.

 

before, i thought that when OnStart runs, the GPS position is not yet known to the Wherigo engine. That makes sense - the engine must actively populate the Player object with the coordinates, so maybe it runs OnStart first and populates the position afterwards.

 

but i think that OnStart runs -after- the author scripts, because if it did run before it, that could seriously mess things up.

so why do author scripts see the position and OnStart doesn't?

Link to comment
but i think that OnStart runs -after- the author scripts, because if it did run before it, that could seriously mess things up.

so why do author scripts see the position and OnStart doesn't?

Perhaps OnStart is called from Wherigo.ZCartridge() ? I imagine that a few print() statements might reveal that.

Link to comment
Hmmm. Doesn't Lua have some kind of multipass capability?
well, technically yes, you could call compiling first pass and execution second pass. but that's not relevant here, because functions are first-class values.

the following code

function cartSomething:OnStart()
  (something)
end

compiles to "set item 'OnStart' of table 'cartSomething' to value 'compiled function chunk 0xdeadbeef'", so you don't know which function will end up as OnStart before you actually "run" its definition.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...