PC Engine Farming Sim: A Dev Diary?

Post Reply
User avatar
tekk
Posts: 20
Joined: Fri Apr 19, 2024 5:17 pm

PC Engine Farming Sim: A Dev Diary?

Post by tekk »

I'm burnt out on writing oauth code in zig, so this is another project I've had kicking around in my head for a while.

For those who want to follow along
The PC Engine (TurboGrafx in the US,) was the first widely available "16-bit" (we'll get to this,) console. It was also the first console with CD support, for what that's worth, and this'll be important later. It was the offspring of Hudson, that company who makes Bomberman, and at the time Japanese electronics giant NEC.

What are we working with?

1. A hell of a 6502. Namely the HuC6280. It runs by default at ~7MHz and includes additional hardware like the system's sound and I think IO chips. One gotcha for people who know the 6502: the HuC6280 includes an MMU and by default the zero page is mapped to $2000. Yes it's confusing. This means that most cartridges didn't have to worry about their own mappers though, which is nice.
2. 8KB of RAM.
3. A video processor which can handle higher resolutions than any of the other 16 bit consoles at its max and depending on your definition more simultaneous sprites than the SNES. That last one is a big part of why there were so many awesome shooters for the platform. It's got a beastly 64KB of video ram, on par with the Genesis/Megadrive.
4. A sound chip with 8 programmable waveforms.

One notable weakness is that the games came on "hucards", which are credit card sized PCBs, similar to the ones that were around for the Master System. These are cool bits of hardware but they hurt the system's expandability and particular no games ever included a battery for on-card saves. This brings us back to the CD addon! The CD addon included 2kb of battery backed ram for saves. Everything else needs to be based on a password. This is another reason arcadey shooters were popular.

What's development like?

Fun! There are two major development kits for the system, plus one extra. First is HuC, a C development environment that's pretty sweet. Here's a hello world for a sample (taken from https://obeybrew.com/crashcourse1.html)

Code: Select all

#include "huc.h"

main()
{
	set_color_rgb(1, 7, 7, 7);
	set_font_color(1, 0);
	set_font_pal(0);
	load_default_font();
	put_string("Hello, PCE World!", 8, 13);
}
I think the latest version is here: https://github.com/pce-devel/huc

The other major development kit is MagicKit+PCEAS. This is in assembly and I don't have a hello world to hand, but this is what I plan on using.
The story here is kinda messy. The best option I've found is to get pceas from here: https://github.com/nop00/pceas , and you'll probably want the magickit demos from the magickit site: http://www.magicengine.com/mkit/download.html. As for magickit itself, the "linux" versions floating around are all kinda gross. This is my cleaned up version, I haven't tested it yet but I think it'll work: https://git.sr.ht/~tekk/magickit/tree

There's also HuDK. It seems pretty sweet but people don't seem to use it and the docs are pretty barebones. It's here: https://github.com/BlockoS/HuDK/.

All of these (as far as I've found) should compile basically anywhere, for what it's worth. Linux, OpenBSD, probably even Haiku. I bet you could get them running on Plan9 without too much difficulty even :lol:

For graphics the standard is PCX format traditionally, though newer dev tools can also include PNGs to my understanding. The PCE's PPU(s!) are actually pretty powerful and complicated so I'll be vague about the details, but the short version is that your tiles will be 8x8, 16x16, 32x32, or 64x64 depending on what you're doing. I think you can even mix and match like a 32x16 or a 64x32. Aseprite is suitable on Linux but if you can't use binary drawing programs your best bet is probably GrafX2, a clone of DPaint2:http://grafx2.chez.com/ . Unfortunately it only supports 256 colors/image so you might eventually hit a bar there since the PCE supports 512 colors, something like 492 simultaneously without trickery?

I think you're kinda screwed for sound outside of mainstream platforms. Deflemask (https://www.deflemask.com/) supports the PC Engine but outside of that I think you're writing your music routines by yourself? There might be a tool somewhere (or I might have to write one...) to try and convert some milkytracker-supported file eventually.

Last bit you'll want: the best emulator for the PCE is Mednafen. It includes a debugger, but there are some QoL problems with it. Get the PCE Dev community fork so you have things like more readable fonts: https://github.com/pce-devel/mednafenPceDev

Next up: an abridged version of my notes once PCEdev Mednafen finishes and I copy my work over from my old Linux install.
Last edited by tekk on Sun Apr 21, 2024 11:21 pm, edited 1 time in total.
User avatar
tekk
Posts: 20
Joined: Fri Apr 19, 2024 5:17 pm

Re: PC Engine Farming Sim: A Dev Diary?

Post by tekk »

Will It Fit?
I floated a couple of initial ideas: a tetris clone (since there isn't one on the platform?!), and a farming sim. I've wanted to make one of those since I was a kid.

One of the things I most enjoy about these old platforms is all the memory math. Ask me about my favorite day at work some time. So the first question was just how viable this could be.

Harvest Moon was on the SNES, which had 128k of memory. Oh dear (and holy shit what a difference a couple of years meant to computing power in the late 80's and early 90's.)

Luckily my favorite classic Harvest Moon is Harvest Moon GB which has...the same amount of RAM the PCE has ;) Did it use a mapper for more memory? I dunno and nobody seems to have recorded it, but at least it told me it might be possible.

So no for the fun part, when I make up numbers with no basis in reality.

Farming Has A Lot Of State
With 8k of ram to put up with, I was comfortable budgeting 1k or so to the farm itself. This'd be the biggest single chunk of memory in the game. A lot of the rest can be done with rom lookups but when any tile can grow things this has to be ram. How many farmable tiles can I fit in that while feeling like a real farming game?

So, a tile. It needs a tile type, I figured 3 crops per season was fine, then weeds, rocks, logs, open, and tilled. 8 values, 3 bits. I need to know if it's watered, but that's just 1 bit. After that I need to know the age for the crops. 16 seems fine. So I can fit a tile per byte. 1024 farmable tiles, I decided to break that into two plots of 16x32 in an L shape. That's probably enough to farm on.

The next biggest memory hog after this would be the inventory. Harvest Moon and Harvest Moon GB don't have a backpack, but they still need somewhere to store tools and need to have an item format for holding something in your hand. I already committed to 9 crops (3 crops/season, with winter field fallow.) I need those crops plus their seed versions, 18. If I want animals I need hay, eggs, and milk. I threw in the ability to pick up weeds as well though once you'll probably prefer to scythe them. That's 22. Then we have the 5 classic tools (hoe, axe, watering can, pick, and scythe) to 27. At 5 bits I have space for 4 food items or forageables, maybe even fish if we get real crazy. 0 being the "empty" marker of course. 6 bits would give tons more options but I was seeing how small I can crunch with verisimilitude. Plus 5 bits lets me pack item amounts in as well, capping at 8 (the item would have no ID in the slot if there were no items, so a count of 0 = 1 in this case).

So that's something else we can pack into a single byte. This is looking kinda possible?

I need a couple of bits for how much water is in the watering can somewhere, okay. A couple bits for fatigue (I went with 2 bits with RNG to determine when it ticks up.)

Some amount of money. I said 24 bits but I'm not married to it.

Is it just me or is it looking like I can fit basically all of this gamestate in 2k? Maybe I should be making NES Moon...

Oh, I cheat a bit with time: I don't keep track of years, just a season identifier (2 bits,) a day identifier (4 bits), and if I cut a day down to 16 hours I can cram that neatly into 10 bits (16 hours, 64 "ticks" per hour.) Player just falls asleep when it hits 10. I could make this way more reasonable, but I'm still worried about memory crunch at this point and I can always expand it.

Villager relationships are small, just a "like" level. Animals require a couple of variables ("like" level, age.) Those two can share a lot of code and can be heavily based on ROM lookups. Shops can be all ROM lookup basically. Whether a tile is farmable is a ROM lookup.

Oh no. NVRam cost a ton in 1988.
Wait, I have to save this. Shit.
Maybe 2k of gamestate is a lot. It's my whole memory "card!" We can't even swap those. :shock:

Alright, well...a lot of player stats we can drop. We need to keep the name and the inventory for sure, but we could lose fatigue and make it full every time, we could always start the watering can empty on load. The real problem is that a byte per tile is looking real wasteful when that alone is half of the system's save data.

So we crunch. And we crunch in ways that a vintage 1987 CPU can do well.
First while saving: go over the farm data and make every tilled but unplanted tile into a bare earth tile. Then we think about the game. For the most part players plant crops in rows, and they tend to plant a lot at once. Plus at any given time the vast majority of the field is going to be empty (we might be able to improve this more by eliminating the "waste" tiles like stones, wood, and weeds by clearing them every night like untilled tiles and regenerating them in the morning.) I'm pretty sure if I just run length encode tiles it should be fine! 10 bit starting offset (for 1024 possible tiles), 6 bits of length for a run of up to 64 (a run of 0 makes no sense after all), even if I waste a whole byte per tile to make the decoder easier that should help a lot.

Level layouts?
After this I got to other concerns, namely the layout of town. Initially I had the idea to make all zones 2 screens by 2 screens, which is easy on the PCE. With 12 "zones" that was gonna eat 12kb of my rom according to my marginalia. So I decided zones would be either 1x1 or 2x2, and I'd just deal with loading them. One bit of signifier would be fine.

I think this is doable.

So it's possible. Probably.
After that my notes go into some of the actual gameplay and ram details Farm tiles, use tools, walk around town. Feed animals. Sell things in the shipping box, all that.

I played with the in-rom (mostly) representation of items. 8 bytes of a name, a pointer to its effect when "swung", the amount, and its price. Only amount needed to use ram.

I decided to arrange the farmable land in an L because then in rom I could store the check as a bounding rect: is the tile farmable? For farmable in farmables: is tile.x > farmable.left_x and tile.y > farmable.top_y and tile.x < farmable.right_x and tile.y < farmable.bottom_y? If so yes. If none no.

Formally describe how all the tools work:
Hand: if the tile in front of the player can be put into your hand/inventory, put it there.
Hoe: if the tile is bare, till it. If the tile is tilled or has a plant, make it bare. Otherwise do nothing.
Axe: If the tile is wood, set it to bare and increased the stored chopped wood. Otherwise do nothing.
Pick: Axe but for stone.
Scythe: If the tile is a weed or a plant, make the tile bare. If it was a weed increase the stored hay by 1. Otherwise do nothing.
Watering can: Set the wet bit if it's a plant or tilled.

How animals work: they have a friendship meter. You can pet them once a day (a special hand action) to increase their friendship. If you don't feed them that day, their friendship increases. If their friendship is high enough they'll produce milk or eggs in the morning.

My first guess at the map format: whether this map is 1x1 or 2x2. Rectangles for all entrances/exits and where they're connected to. A tile is just a tile id, and declare that tile IDs below some n are impassable.
Fun fact: I think all of the major SDKs actually support mappy: https://www.tilemap.co.uk/mappy.php. That doesn't help me on OpenBSD. I probably need to write a tool.
User avatar
headcrash
Site Admin
Posts: 63
Joined: Fri Apr 19, 2024 9:40 am
Location: The sea of meatballs
Gopher: gopher.deadnet.se
IRC: Headcrash @ irc.libera.chat
Jabber: headcrash@og.im
Contact:

Re: PC Engine Farming Sim: A Dev Diary?

Post by headcrash »

Interesting read! Coding is not something I'm particularly good at, but still interesting. I even powered through falling asleep at the mid-point there somewehre! lol.
Nah, very cool project. Looking forward to seeing some updates on how it's going! :D
Everything is a smoke machine if you operate it wrong enough.
StuXNode
Deadnet
Post Reply