+themonkey Posted December 1, 2009 Share Posted December 1, 2009 I've gone through most of the tutorials, and have been trying to build one as I go through, but I need to build a play anywhere cartridge. Is this implemented toward the end of the building process, or am I missing something? Thanks, Holly Quote Link to comment
+Delta68 Posted December 1, 2009 Share Posted December 1, 2009 Set the main co-ordinates as 0 and 0 Mark Quote Link to comment
+sTeamTraen Posted December 1, 2009 Share Posted December 1, 2009 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. Quote Link to comment
Ranger Fox Posted December 1, 2009 Share Posted December 1, 2009 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. Quote Link to comment
+Fish Below The Ice Posted December 1, 2009 Share Posted December 1, 2009 I haven't tried to figure out what _G contains, let alone its type. I believe that lua provides this as a the list of global variables available to your program. See http://www.lua.org/manual/5.1/manual.html#pdf-_G Quote Link to comment
+themonkey Posted December 2, 2009 Author Share Posted December 2, 2009 I don't think I have the capacity to build a play anywhere cartridge. I wouldn't know where to plug the code in let alone how to write it. So I guess I'll stick with Tour Guide type cartridges. Thanks for the help, though. Quote Link to comment
+sTeamTraen Posted December 2, 2009 Share Posted December 2, 2009 (edited) 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. 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 December 2, 2009 by sTeamTraen Quote Link to comment
Ranger Fox Posted December 3, 2009 Share Posted December 3, 2009 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. Quote Link to comment
+sTeamTraen Posted December 3, 2009 Share Posted December 3, 2009 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. Quote Link to comment
Ranger Fox Posted December 4, 2009 Share Posted December 4, 2009 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. 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. Quote Link to comment
matejcik Posted December 8, 2009 Share Posted December 8, 2009 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? Quote Link to comment
+sTeamTraen Posted December 8, 2009 Share Posted December 8, 2009 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. Quote Link to comment
matejcik Posted December 8, 2009 Share Posted December 8, 2009 that is actually impossible ;e) first you have to call ZCartridge, then you define OnStart. at the point where ZCartridge is called, OnStart doesn't exist. (and it wouldn't help the case anyway - either you do have the position before loading and running the bytecode, or you don't) Quote Link to comment
+sTeamTraen Posted December 8, 2009 Share Posted December 8, 2009 that is actually impossible ;e) first you have to call ZCartridge, then you define OnStart. at the point where ZCartridge is called, OnStart doesn't exist. Hmmm. Doesn't Lua have some kind of multipass capability? Quote Link to comment
matejcik Posted December 8, 2009 Share Posted December 8, 2009 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. Quote Link to comment
+sTeamTraen Posted December 9, 2009 Share Posted December 9, 2009 Good point. So, what's your explanation? Quote Link to comment
matejcik Posted December 9, 2009 Share Posted December 9, 2009 i have none! (or maybe you're wrong and it does work in OnStart after all ;e) ) Quote Link to comment
Recommended Posts
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.