[WIP] Ardu Valley - Harvest Moon / SDV clone


#1

so having finally cleaned out my two WIP’s to release, I can start on an idea I have had for a while. This is going to be my work in progress for an attempt at making a semi interesting clone of harvest moon. Eg, a crop growing, relationship making time sink.

I’ve done some prelim on the first bottleneck (EEPROM for a save file) and I think I can fit all the stuff i need to save in (crop positions and state, animal position and state, NPC relationship values). The trick will be how much content can be fit into the program memory, etc. Anyway, it should be a great technical challenge.


(Ash) #2

As a lifelong Harvest Moon and Stardew Valley fan, I can’t wait!


#3

Can anyone shed some light on the state of the art for gray pixels. I have seen a bunch of examples but they all seem to relate to the dev kit. Any experiments so far have just resulted in flickering screens etc.


(Mike McRoberts) #4

As far as I can tell that is as far as they got. The pin that may allow this is not broken out for reasons unknown and the manufacturer is unwilling to improve the product to make it so.


(Ash) #5

Well they are more than willing, Kevin just has to order something daft like 100,000 screens for them to do so!


#6

Fair enough, I have managed to get gray coluring happening, but it only works if you are doing just a tiny area and have almost nothing in your update loop. Also you need to flog the FPS, so it is a moot point, I guess it will be all b/w. On the plus side, that means more progmem.


(Josh Goebel) #7

Huh? The hardware is more than fast enough if done right. The megaman demo can run using only 20% CPU or so and it’s full screen animated greyscale. The best use for greyscale though IMHO (considering the sync issues) is for like a few sprites and then have a special render loop that constantly re-renders them properly outside of the normal FPS loop. (rather than trying to do fullscreen greyscale)


#8

I could not get the megaman demo to run, or maybe I am confusing it with a different demo.


(Josh Goebel) #9

It’s just a demo, not something you’d base a game on, and it doesn’t look great because of vsync issue. Greyscale is easy though… basically you just blink a pixel on and off between black and white as fast as you can (for one shade of grey). So a simple greyscale system just has to know which pixels are are “grey” so it can switch the grey ones between white and black as fast as it can. White always stays lit of course.

And of course you probably need a custom render engine since otherwise you’d need like 2k to buffer a 2 bit screen buffer instead of 1 bit.


#10

OK, I have set up the primary data structures for the game and written the save/load routines.

…ouch. This is the EEPROM breakdown.

Farm: 747 bytes
Player: 69 bytes
NPCS: 32 bytes
= 846 Bytes

So not a heck of a lot of wiggle room. Also with those structures sitting in RAM and that pesky sBuffer we’re hitting 82% of RAM already. I’m going to have to calloc my data structures to avoid the USB write issues already.

But, all that money (EEPROM bytes) buys us the following.

32 NPC’s, we only need to store their affection levels, which is a single byte.

storage for the following tools with 4 levels of available upgrading (2 bits per tool). Axe, Hoe, Pick, Watering Can, Pail, Shears, Scythe, Fishing Rod.

Players money (4 bytes).
total days through game (2 bytes). This is enough for 65535 before wrap around, probably could get away with one byte.

Players lumber (1 byte)
Players stone (1 byte)
Players max stamina (1 byte)

8 character names for player, farm, dog, horse. (32 bytes)
2 bytes for horse and dog affection.

A max 10 item backpack, (items are 2 bytes, 1 byte for ID and 1 for quantity).
An item in the hand and a tool in the hand.

The farm has the following.
a 24x16 field for planting crops. This is far and away the biggest user of space. Each crop tile is a byte, with 4 bits for ID (enough for 4 crops each season and 3 extra) and 4 bits for growth stage.

16 x 3 bytes to indicate if a crop tile was watered. If you don’t water the crops, they don’t grow.

Space for 8 chickens, 8 cows and 8 sheep, each with an 8 character name and a byte to store affection.

space for 16 trees in an orchard. Each tree is a byte (2 bits for ID, 6 bits for growth).

A 20 item storage chest and a 20 item fridge to put stuff into. 80 bytes here.

So yeah, These are the features I want to support. The next step is to see how much space it takes to store the farm and associated menu screens in progmem. That will give me the ‘rest of game’ budget. If there is not enough space, it will go from farming/dating game to just ‘farming game’


#11

Yeah that was the problem i ran into in testing as well. Flickering does not look easy. I really only want the grayscale for screens with character faces and dialogue, so it would be possible to only alloc a massive buffer for those moments, but probably out of the question. I am going to proceed as if it is not possible, as I think I will be hard pressed to fit the game i want into the space i have without thinking about grayscale.


(Josh Goebel) #12

You don’t need a 2kb buffer to do greyscale… that’d just be one way. You can just redraw your ENTIRE screen very quickly technically (that’s exactly what the megaman demo does) between the grey on and grey off versions of your images… of course you will burn thru more flash storing two versions of your image, so there is that to consider.


#13

Yeah i already am at the point of removing the intro animation to save bytes, I think using extra is probably not an option. We will see.


#14

I am working with procgen for drawing sprites. Instead of storing an 8x8 sprite, i store a seed, a shift and an xor value and use those to generate the bit pattern on the fly. So far it is looking promising. It allows me to store an 8x8 sprite (8 bytes) as 3 bytes instead, more than 50% storage increase.


#15

Shower thought. If you need a lot of RAM to calculate stuff and the pesky sBuffer is taking half of it. Use the pesky sBuffer as a heap to store calculations in either before or after your render pass.


(Josh Goebel) #16

Sure, with the default libraries you can use that RAM for absolutely anything you wanted to if you aren’t actively painting it to the screen with display(). The fact that it hasn’t really been discussed before points to the fact that most things need persistent storage not temporary (between frames) storage.


#17

What is the smallest way ‘in terms of bytes’ to test if a block of 8 bytes are all zero.

Currently the winner is just a simple for loop. I tried casting the memory into two longs and testing for 0, it is just smaller than the for loop for the first 4 bytes, but adding the offset for the second 4 bytes makes it bigger.

Anyone have ideas? I am mostly interested from an academic POV, but for every byte saved a fairy gets its wings.


(Josh Goebel) #18

The only thing smaller might be a for loop to OR (bitwise) them all into a single value and then test against 0 at the very end (outside the loop). But really if the compiler is being smart I can’t see how that would improve things any.


(Josh Goebel) #19

That’s probably the wrong question though… there are probably much lower hanging optimization fruit in your code than this kind of question.


#20

I already tested the Or version, it works out about 10 bytes worse than the 4 loop.

Yeah I’m not asking it because i want to squeeze bytes yet, I was just curious if there was a better way I wasn’t aware of, which is definitely the right question, because I might learn something I can apply all over.

I made a version using goto/label that looked promising but would up identical to the for loop, which makes sense actually.

Also yeah, I have found the best optimizations I get so far are from code re-organisation to cut down on excessive repeating of boolean checks