Robot Fishing Village

Here's a game I started quite a while back! It's been a really weird year so development's been very much on and off, but I thought it'd be nice to get a devlog going here.

20200522_robotFishing_world_optimized
Quick Summary
There is a remote coastal fishing village inhabited by tiny robots. A typhoon has swept away all the villagers save for one. That's you. Now it's your job to fish your friends out of the sea, one-by-one.

You will need to collect tackle to open new possibilities while fishing. Maybe one lets you cast farther, one speeds past the fish you don't need, one spins to catch the eye of a big catch, one drills through rock into underwater caves. The Twist: Each additional feature adds a minigame to the fishing process. By the end of the game, fishing has become a series of quick, wacky little challenges you've mastered.

What's new
So yeah, I've been diving back into this thing. I rolled my own tiling system because I wanted more flexibility than was provided in the sdk. Loading and drawing all those little world tiles turned out to be pretty rough for performance on the device, especially when moving between screens, but with some optimization and a nice transition effect, it feels a lot better!

I'll share some GIFs of the world editor and minigames later.

17 Likes

That looks great Dave (as usual)

For you own tiling system do you plan to have scrolling for it or do you focus on single screen only?

Single screens for simplicity's sake. Going for a bit of a Link's Awakening aesthetic.

3 Likes

woah! This is really snazzy. I'd love to hear more about your tiling system. I have no experience with sprites or tilemaps or anything so some insight would be much appreciated! The transition effect is really impressive, can you go into that a little more and what's going on under the hood?

Really promising, I can't wait to see where this goes. I hope you use the crank to reel in catches :playdate_wink:

20200524_robotFishing_editor2_optimized

Here's a look at my in-game map editor, which runs in the simulator thanks to the keyPressed callbacks which let me use input from a bunch of keyboard keys. This lets me switch between editing and playing really quickly so I can check to see how things feel as I work. I just added a little UI preview of all the tiles in a set to make it easier to find the right one.

A map is basically just a table full of numbers and names of tilesets. I wanted the flexibility of pulling from multiple image tables because although it would probably be better for performance to use one big image table, I was worried about how that would complicate things during development if I wanted to add, remove, or rearrange parts of the table. That was the main reason I didn't go with the SDK's tilemap feature, which I believe is designed around using a single image table. Also, I wasn't sure if it supported animated tiles, which I'm using for things like the water. And I wanted finer control around collision shapes.

A tile's properties are pulled from a reference JSON that defines what its collision is like, whether it's animated, whether it's fishable, etc. Animated tiles can have a speed, and they can even have randomized delays applied for stuff like the waves in the water.

Each screen's layout is from a separate JSON file that gets loaded in when you go there. I tried out loading the whole world at once when the game started, but it took a surprisingly long time, and I decided it was better to load things on the fly. Edited JSON files get saved in the simulator's Disk folder, and then I just copy the ones I want to keep into the project folder manually.

As for the transition effect, it's super simple! I just draw a big black rectangle over the screen and use the playdate.easingFunctions to smoothly change its size.

3 Likes

20200524_robotFishing_reeling

Oh, and here's what the reeling minigame looks like! It's all about reeling at the correct speed. For more difficult fish, the speed window could get narrower or move around more unpredictably.

6 Likes

Oh wow, the built-in map editor is amazing!

And here I've only just started deliberately adding global functions intended to be called from the console in the simulator for debug and dev.

A map editor is just a whole other level.

3 Likes

Holy cow! That mini-game has me hyped. The map editor is such a brilliant idea too, are you using the simulator to edit maps purely for design? By that I mean, are you designing in the simulator at run time in order to save the map to later bake into the binary? I had a thought about doing something similar for making assets using the console itself by being able to create sprites or sprite sheets and save them out to be used in games and your map editor really brings that concept to life! Amazing work. I find my self baffled by how simple your explanations are and my own understanding of how to setup these systems. I can't even comprehend what your update function looks like for a game of this scope.

1 Like

Basically, yeah! The editor saves a JSON that's basically a table full of numbers, and then if I like it, I copy that file into the project. I personally work in Aseprite for assets because I imagine it'd be kind of a pain to do it in-engine, and I'm trying not to go too overboard with dev tools, haha. Although, Loren Schmidt is doing some really inspiring stuff with editing sprites in her game.

Anyway, my update function isn't too bad! Things are broken down into objects, and an object called game manages pretty much everything. I wrote a little about my state machine elsewhere, but I might as well repeat it here. Basically, this goes in the init:

-- game states
self.states = {
	world = self.worldState,
	edit = self.editState,
	transitionToMinigame = self.transitionToMinigameState,
	minigame = self.minigameState
}
-- starting state
self.state = self.states.world

This will expand as the game gets more complex, I'm sure. And then the game object's update looks like:

function Game:update()
	-- Perform State
	self.state(self)
end

and then I make a function for each state like function Game:worldState() etc. Even then, those functions aren't holding much because the individual objects (the player, the world, the editor) are off doing their own thing with their own state machines. The game object sort of loosely makes sure everybody's doing what they're supposed to be doing, haha. When I want the game state to change, I just do something like self.state = self.states.edit and that changes what the update will be next frame.

1 Like

looking great!

Super inspiring work on your map maker and Loren’s pixel editor.

I didn’t know about keyboard keys working in simulator until today.

2 Likes

Very informative thank you! I'm excited to see more progress :playdate_happy:

1 Like