Search This Blog

Lemon Merengue Python

[Originally written September 4 2020]

Ready to dig into my next project, I located the lemon script, and as my means of deciphering it, I sort of translated it into pseudo-Python. What can I say? I have a degree in computer science, so the easiest way for me to understand code is to translate it into other, more familiar code. Even for those who aren’t well versed in programming, it should be somewhat easier to read.

So the question is, just what is obv0? A look in the developer reference tells me this is a generic object variable, which is stored in the object and exists outside the scope of the scripts. So what’s it do here? My best guess, based on that script, is that obv0 for the lemon flags it as eaten (1) or not (0). This will need to be modified to remove the pain increase, and possibly to make the lemon invisible after being eaten.

Next up is the drop script. This appears to use some clever bitwise operations. For those who are not programmers, this means that it’s doing stuff with the numbers written in binary, one digit (bit) at a time. The ATTR values may look rather random, but they’re not – they’re powers of two, which means something magical happens when they’re written in binary!

DescriptionATTR valueBinary
Creature carriable100000001
Hand carriable200000010
Hand activatable400000100
Can carry things800001000
Invisible1600010000
Floats on screen3200100000
Limited to room (wallbound)6401000000
Limted only by ground (groundbound)12810000000

Each one is indicated by a 1 sitting in a different slot. So when you add the ATTR values together to set the attributes, you’re really setting a bunch of binary flags. For example, an attribute of 6 is created by adding 2 and 4 (hand carriable and hand activatable), the meaning of which isn’t immediately clear… but in binary, it's 00000110 – readable quite easily as long as you know what each slot corresponds to; both the hand carriable slot and the hand activatable slot are “on” (in other words, set to 1). Bitwise And (andv in CAOS, & in Python) and Bitwise Or (orrv in CAOS, | in Python) create a number by doing something in each slot based on the two inputs: for And, if both inputs have a 1 in that slot, the output has a 1, and otherwise it outputs a 0; for Or, if either input has a 1 in that slot, the output has a 1, and otherwise it outputs a 0. For example:

0111
AND
1010
0111
AND
0011
0111
OR
1010
0001
OR
1000
0010001111111001

This script, if the obv0 variable is 1 (the lemon has been eaten), Ands the attributes with 252 (11111100) and then Ors it with 16 (00010000). Essentially, this means that, first, both of the carriable flags are turned off, and then the invisible flag is turned on. It then waits a moment and moves the lemon somewhere else, and starts a timer. 

Which leads us to the timer script. When the timer’s up, it generates a location somewhere on the lemon trellis, puts the lemon there, marks it as uneaten, and does some bitwise operations to turn off invisibility and turn back on carriability. 

So if it didn’t go straight back to the trellis, where did it go? Based on the coordinates of the trellis I’ve confirmed the (0,0) coordinate is located in the upper left corner of this image, which is to be expected given that that is apparently a rip of the background straight from the game engine. 

The drop script moves the eaten lemons to (571, 1084), which is precisely here. Because apparently hiding the eaten lemon behind a rock is easier than simply using an invisible sprite? And suddenly, flying lemons make sense. I’ll have to fix that when I make my tweaked lemon.

And the final scripts for the lemon are “extra activate 1” and “extra activate 2” – which appear to be scripts intended for the creatures themselves? At any rate I don’t think I need to bother with them now.

So to sum it all up, the problems with the lemon are:

  • An eaten lemon remains visible until dropped. That means it has the same problem as the carrot seedlings: a creature eats it, thinks it still has food in its hands, and then is confused when it can’t eat it.
  • When dropped, an eaten lemon is hidden behind a rock until it’s ready to be moved back to the trellis.
  • Lemons cause pain when eaten, teaching creatures that eating hurts. Not good!

My plan was fairly simple. First, I’d remove the pain increase. I would add a blank sprite, and when the lemon was eaten, I’d flag it invisible and switch to the blank sprite, and rather than hiding behind a rock, I’d move it directly to the trellis. Of course, for debug purposes, I wouldn’t actually use a blank sprite until I’d verified the behavior! Instead, I used a placeholder – which is pictured here not being properly invisible. This led to an immediate crash. While no harm was done other than losing everything since the last save, it was a good demonstration of why I chose to work in a VM with a backed up test Norn.

As much as I prefer the BoBCoB interface, I ended up moving to CrEd32 due to numerous problems I encountered – my inject screen image wasn’t properly attaching to the COB, I couldn’t use BoBCoB’s inject function due to runtime errors that I wasn’t able to solve, and of course, BoBCoB doesn’t have a classifier calculator. 

I feel like this will probably be my usual workflow for this process – build the framework in BoBCoB because of its friendly interface, and then go to CrEd32 for the serious editing and debugging work.

I struggled for a while with various issues, slowly hammering out all the problems. I couldn’t get the lemons to inject in their invisible state correctly, so I made them inject as ready-to-eat fruits. I had issues with lemons hopping back to the trellis when dropped uneaten, fixed by fiddling with attributes. I had issues with lemons occasionally hopping to places they shouldn’t – I corrected this with a redundant script (the invisible lemon gets put on the upper left corner of the trellis, and then it gets moved to a randomized location on the trellis when it becomes visible again) so that even if one script misfires, the other will get it where it needs to go. I had issues with lemons not being visible or grabbable when they should or vice versa. 

I got it into a decent state but went back and changed my mind – why should I stick to the original lemon recycling model? Jessica’s carrot proves that you can just delete and recreate objects, and indeed if I was programming this game from scratch today that’s exactly what I’d do! So I went back and cleaned it up even more. In the end, Betty the Beta Norn and Bob the Beta Grendel did their jobs very, very well, and I was satisfied with the results of the beta test.

Download the Updated Lemons

No comments:

Post a Comment