Red Sky at Night, Sailors' Delight, Red Sky in the Morning, Sailors Take Warning


Finally back with a new log. It’s been much more time than I would have liked since last time, so get ready for a long read.

Where we left off

First, here’s what happened under the hood: sometime after wrapping up the previous log, I was reading about frame rates and battery life, which lead me to question my style of programming. I began contemplating the benefits of more modern code. At the bottom of a rabbit hole of study and benchmarks, I came up with brand new object powered code, relying on higher level SDK librairies… with the counter productive effect of losing 15 fps on average.

Without a doubt mistakes were made. After all, not long ago I didn’t know what a method is. But it remains that the Playdate, like the vintage computers on which I learned code, leaves the heavy lifting to the CPU. And these failed experiments confirmed that this type of architecture favors my initial instinct of a more direct, low level hard coded approach. 

In hindsight, all the experiments gave me a better understanding of the platform. I reverted part of the changes, and in cases went even more bare bones. I also learned useful concepts, cleaned up the messiest parts, and got rid of nasty global variables. On this I need to give a quick shoutout to SquidGod (https://squidgod.itch.io/), whose excellent introduction to Lua prompted me to revise my naming conventions. He also made useful tutorial videos if you’re looking to develop on Playdate.


Squidgod's introduction to Lua

Still. for the most part, I don’t know what I’m doing. The last time I wrote code was 25 years ago. I haven’t come out of the de rusting phase yet. Frankly I don’t even know if it will get any better; I wish I could spring clever terrain generation algorithms on queue, like Oskar Stålberg does. Or write stylistic 1-bit 3D shaders in my sleep like Lucas Pope. But you have to work with what you got. In fact, go check his promising “Mars After Midnight” for the Playdate, which exudes character like every one of his games.
https://dukope.itch.io/mars-after-midnight


Lucas Pope's upcoming Playdate game

At this point I could keep tinkering with sprites and classes, but even I can’t waste more time. My code isn’t the prettiest, but it’s workable, and it will do the job.


A Tiny Computer

I should address something that I was asked about: the apparent dichotomy between the platform and the genre of game I decided to make. The majority of Playdate games are toys which you fidget with for a few minutes. It’s understandable, and falls in line with the console’s design. And for any game to be commercially viable on Playdate, with barely twenty thousand units on the market, one can’t spend more than a few months on development. However, even though money would be nice, it’s not what drove me to make Atlantic ‘41, so I’ll do away with business sense.


The best computer ever

But why the Playdate then? Well to me it’s a 16 bit computer. I’m used to making games on simple, closed platforms, without any interference from the hardware developer. Back then, Commodore didn’t review C64 games, and all C64s were the same. That combination is rare nowadays, which makes the Playdate unique. I also love working within constraints. For me there’s a joy in working around hardware limitations. And it imposes a focus that I would otherwise struggle to find on a powerful open ended system. That, and the fact that limited hardware tends to level the playing field, which means that you don’t compete against large teams of talented individuals. 

Silent Service 2

Seeing the Playdate as a computer, it’s logical to make a fitting project. I guess the elevator pitch would be: a pseudo realistic U-boat simulation that you can play on the toilet. My idea is a game of larger scope than Silent Service 2, historically researched, and deep enough to remain challenging and fun on the long run. I know how this sounds, but that’s the goal. And it’s not scope creep; I set out early on to make a “big” game by Playdate standards, for better or for worse.


An Unexpected Opportunity

Now back to the current state of affairs. If you remember, I had left both the periscope and the conning tower views in unfinished state. First, making the conning tower more believable.


"Uboat" shows how large the conning tower really is

The excellent game “Uboat” offered perfect reference, as it allows you to freely walk around the conning tower. I was able to judge perspective from that viewpoint. Two main conclusions emerged: first, you can’t see both the stern and the bow from the same spot. The tower is divided into two main sections: the observation bridge, and the AA gun platform. It's large enough that you have to walk several steps to get a clear view out the ocean forward or aft. Second, the railing enters the field of view only if you stand far enough from it, around the center of the platform.

Evidently there’s not much sense in opening a can of 3D worms to let the player move around the tower. Atlantic ’41 is a strategy game first, which revolves around tactical decisions and resource management. But this type of simulation needs to immerse the player, and the exterior views are an opportunity to break from the austere schematic views and static screens that will comprise a large part of the game. 

My solution was to keep the camera fixed in place with only the bow or stern entering the field of view as you rotate around, a bit like if you placed it somewhere between the AA gun platform and the lookout area, a few meters above ground. I feel like this is an acceptable approximation of reality. It’s simple enough yet offers context and visual interest. 


This bow sprite looks too much top view and is hard to read

Even with the reference it took me a few disastrous attempts to get the perspective of the bow; not enough foreshortening and it looks like top view. Too much and the boat feels stretched. Regardless, a major problem arose as soon as the first sprite came into view; the scale was off. Which is great, because it made me realize that my waves were too large for this view. It looked silly.


This bow works but the waves are too large

It should merely be a matter of replacing the waves with much smaller ones. Except not. A few waves fill the space when they’re large enough, but replace them with tiny ones and you get what’s close to nothing at all. Spawn more waves, then. Many more. It looked quite nice with around 100 of them. The only hiccup: That many animated sprites bring the frame rate to a crawl. 

At this point I was getting worried, even considering dropping the whole idea of showing the boat at all. But you can’t unsee things, and that new conning tower view checked all the boxes. If only I could make it run at a decent frame rate. 

I didn’t believe that any amount of optimization would get me there, short of switching to Assembly, and even that was not a guarantee. The only way I could think of was to group waves into large sprites, display them in bulk. It’s often the case that drawing large amounts of pixels in one go is faster than multiple little groups. A few tests confirmed that theory on the Playdate. I structured the waves into 8 long strips, 400 pixels wide and 35 pixels high, that I could move at different speeds, for a parallax effect similar to the clouds. However I couldn’t imagine animating dozens of little waves by hand in Aseprite.


The colored areas show the pre rendered sections

Coding a system to pre render tiling, cycling groups of waves at runtime turned out easier than I thought, and it solved my performance issue beautifully. Now the frame rate isn’t affected by the quantity of waves, whether there’s two or two hundred. Playing with the waves frequency, density, and motion, I realized that there was a potential for suggesting various sea conditions. From quiet to more active. I love the idea that the only way to assess weather is to surface and have a peek.

This system isn't perfect, since it's built around a cycle, instead of constant random generation. The most acute observer will be able to spot the loop, but for most people I doubt that it's noticeable.


Take it to the Skies

Weather was a constant preoccupation of U-boat Captains, as their logs attest. It’s also an ubiquitous topic in the official Kriegsmarine Submarine Commander’s Handbook. And so early on I knew that weather would play a large part in the game, but until now I had assumed that most of it would be conveyed through UI. However, that customizable ocean activity seemed like a good starting point for a visual weather system. Adding variable cloud cover would give me enough combinations to convey changing weather patterns. That would mean more immersion and less pesky UI boxes.

The official handbook given to U-boat captains

I altered the code to customize the number of clouds spawned. Unlike waves though, you can’t just pile them on. Large numbers yield less than pleasing jigsaw patterns and decreased performance. Isolated clusters of distant clouds work best for clear skies. Medium coverage looks good too. Beyond that I needed something else; a new, dedicated system for overcast.

So back to references, the starting point of any new idea. Two main observations emerged: first, overcast skies are often low contrast, with few hard shapes and clearly defined silhouettes. Second, it’s full of clouds. Beyond the evidence, what it means is that there’s less visible sky than there are clouds. However positive and negative space aren’t intrinsically different in 2D. Both appear as shapes. And if you reason further, then instead of building the image by adding clouds, you could flip things around: you punch holes into the cloud cover to reveal the sky. Instead of killing cycles by overdrawing clouds all over the sky, you draw small areas of sky on a cloudy background.

My main reference for overcast skies

I tried different approaches but the simplest ended up the best: a large mass of dark clouds hanging above the horizon, with sparse, distant clouds underneath. And then elongated shaped to simulate breaks in the storm clouds. A few low contrast shapes added motion and nuance to the stormy ceiling. I needed to leave a clear section of sky above the horizon, for ships and (later on) coastline to read. Plus I like the idea that you get a glimpse of friendly white clouds in the far background, suggesting hope for better weather. 


Clear skies and calm winds

8x8 dither patterns proved to be a challenge in this situation. The value of the storm clouds may feel too low, but I couldn’t find the appropriate pattern. It’s one of these “lesser of evils” situations; I prefer too dark to too light in that case, because it gives bad weather a strong, recognizable identity.

Combining the various cloud shapes and values, I was able to break down the sky into four cloud coverage levels:

1/ High pressure system. Clear skies, with few isolated distant white clouds.

2/ Fair weather. A bit more covered, with larger, closer clouds.

3/ Depression builds up. Dark distant clouds suggest the approach of a low pressure system.

4/ Storm. What sailors don’t want.


Moderate cloud cover and high winds

The combination of variable cloud cover and sea activity forms a wide array of atmospheric conditions. I still have to iron out the details of weather implementation and its effect on gameplay, but here’s a few examples:

1/ Cloud coverage affected navigation which was calculated by stars, at a time where gps was yet to be invented.

2/ Bad weather can render life onboard miserable, and affect morale.

3/ Choppy seas obscure the attack periscope, which sits low over the surface. The downside is that it makes targeting more difficult. But it also makes the periscope harder to spot for surface vessels.


Moderate winds, but dark clouds suggest that a storm front is coming

Weather offers many more great opportunities for gameplay, and I’ll come back to this in detail when the time comes. For now, I’m glad to have enough building blocks ready to go.

Full overcast


Back on Track

Now before going on this long tangent, I was mentioning the bow and stern sprites. With the scale fixed, all that was left was getting the bow to rotate around the bottom of the screen, as the camera pans around. This turned into another challenge, as 1-bit is not rotation friendly. 

For anything to retain visual integrity through rotation you need either high resolution or anti aliasing, and preferably both. Anti aliasing is by nature impossible in 1-bit. And the Playdate resolution is less than that of a 40 year old Macintosh. Real time rotation mangled the sprite and proved too taxing for the little M7 processor.


Real time rotated sprite vs touched up pre rotated

Again, I resorted to the old trick of pre rotating the sprites. The Playdate doesn’t lack RAM, but I was concerned, since I needed a full 16 degrees arc of animated sprites (to get an uninterrupted cycle of water motion around the bow), in 1 degree increments. That’s 17 animated sprites (including the center position), for a combined 204 frames, times 2, since there’s both stern and bow. That’s 408 frames total. Which again you must double for alpha, for a massive 816 images. The upside of working in 1-bit though is that graphics take very little space. Nevertheless it amounts to a sizable chunk of memory allocated for these mere two sprites. For now, the game peaks at around 3 Mb of memory usage, out of 16 Mb available, which remains comfortable. I’m weary of over optimization, so better to leave it as is, and wait for potential memory issues later on. 


Complete conning tower view

I’m now happy with the conning tower view. There comes a time where you need to realize that this is as good as it’s gonna get, and I think I’m at that point. I’m sure that this could be improved, but I wouldn’t know how, short of building it all in  3D, which is beyond my capacity. Plus, I begin to lose passion for this particular aspect of the game, which is a sign that it’s time to move on.


Leveling the Periscope

But before that, I had to wrap up the periscope view, which had been left in promising but unfinished state. It was a matter of transferring the customizable waves system implemented for the conning tower, this time with larger waves, to simulate the lower vantage point. I recycled the code and built large clusters of waves, again divided into four strips, based on distance to camera. It all came out smoothly, which is a nice change. 


Former periscope circle overlay vs new one

That last bit was to fix the periscope lens circle. Originally I had a dithered pattern to render the soft edges. But this pattern became problematic when overlaid on the ocean. I considered going with a sharp circle, but it felt too modern. Eventually I came up with a simple and rather affective solution: concentric circles, one pixel thick; not perfect but still preferable to a sharp outline, and it works in almost every situation. 

I’m aware of the ungodly amount of time I spent on the first mock-ups and on implementing these views. But beginnings always suffer these setbacks, when the assets haven’t coalesced into a coherent art direction. Add to this my lack of experience with the language and the SDK, and what should take days turn into weeks and even months.

But these exterior views, as the backbone of the experience, deserved the greatest care. A sizable portion of the gameplay will be viewed through the periscope, and the representation of the outside world is the primary vector of immersion. At this point the game looks close to what I had envisioned, and we’re hopefully in a good place, once sound and user interface will be added.


Complete periscope view

There’s many challenges ahead. From the targeting computer to the map, to the U-boat schematic view, to the radio room, to the listening room, to the captain’s log, to the events screen, to the airplanes attacks, to the time at shore, to the crew management, to the various U-boat types. It’s a daunting task, and the limited time I can put in development doesn’t help. But with experience and the continuous addition of building blocks, I hope to pick up pace as development goes on.

One thing I’d like to improve in priority is more frequent, shorter logs. I’m afraid that this length is barely digestible even for the most avid reader, and long pauses between updates make it harder for people to stay engaged with the project. Events have a tendency to take unexpected turns, but I’ll try to put this into practice with a short log about visible time changes (dusk, dawn, and night), which should come in under a reasonable timeframe.

So as, usual, more soon. Or at least, sooner.

Comments

Log in with itch.io to leave a comment.

(+1)

Seconding what everyone else has said so far - length is not a detriment to these devlogs. The more content, the merrier.

I would say though, if you're looking to optimize these devlog updates for maximum reader enjoyment, the key dimension to prioritize is neither length nor frequency, but rather regularity.

If people can expect a monthly / bi-monthly / quarterly update, the anticipation will go a long way to keeping people around and engaged.

(+1)

I couldn’t agree more. I’m going to aim for one update every 6 weeks, and we’ll go from there. 

Always a pleasure reading your devlogs. Can't wait to read about gameplay mechanics ;)

Do you have a ballpark estimate about the game's release date? Is it going to be less or more than a year?

Thank you so much! I’m also eager to start prototyping gameplay.

I wouldn’t trust my own predictions as to the release window. However, given where I’m at and how much there’s left, a 2023 release seems unrealistic. I realize how unusual it is to work for so long on a Playdate project, but I guess everything is a bit different with Atlantic ‘41.

(+1)

Well, we have been waiting patiently for more than a year for a playdate (mine will hopefully arrive next week), we can be patient for Atlantic '41 too ;)

(+1)

Thanks for the shoutout! Your progress is looking impressive as always - looking forward to the next devlog.

(+1)

You’re very welcome. Your introduction to Lua is a great bird’s eye view of the language. Thank you for the compliments :)

I always thoroughly enjoy these updates; I don't mind the length, though I'd love a higher frequency. The combination of retro tech and 1-bit graphics with modern gameplay sensibilities is fascinating. 

And I agree, SquidGod's tutorials are a great resource. I'd like to try my hand at  a PlayDate game sometime.

(+1)

Thank you! It always makes me happy when someone enjoyed  a log, and even spent the time to write a comment. But you’re right about the frequency. A new post every 4 to 6 weeks would be a decent pace. I think my mistake is to wait to complete a feature before reporting on it, instead of breaking it up into smaller chunks. 

I love that you get this impression of  1-bit with a modern sensibility, because this is what appeals to me in video games, this mix of modern and retro. Games have come a long way, and even if I’m looking to capture some of the charm of the past I don’t want to get stuck into it and let nostalgia drive the project. So I’m glad if that balance comes across when looking at Atlantic ‘41.

Understandably, your primary focus should be working on the game itself. But yes, I always enjoy these updates. I haven't received my PlayDate yet, but I am really looking forward to this title.

Awesome devlog! The weather looks stellar. I'm really enjoying seeing this take shape, and I'm super pumped to see how combat, etc. factor in! Keep up the great work.

Thank you very much for the kind words!

It's looking great! Long or short, I love the posts. Looking forward to seeing the night shots.

Though I'm into submarine films and books, I've not yet played any games. Where would you recommend to begin? (if I find time to play one before Atlantic '41 comes out, that is ;) )

(1 edit)

Thank you for your support! I’m glad that you enjoy the logs. Night will certainly be an interesting challenge. 

As for games, I haven’t played anything seriously since “Silent Service 2”, until I checked “Uboat” recently. I’m not aware of many good games on the subject, except Silent Hunter and Uboat. But these are complex, realistic simulations, which is great if you have a decent PC and quite some time to sink into learning them.

In fact it’s partly why I decided to make Atlantic ’41. I was looking for a well crafted, accessible WW2 submarine game that would revolve less around the technical aspects, and more on the overall tactical and human experience of being a submarine commander. Also something that I could play anywhere, on a small laptop or console. And I couldn’t find any.

I guess you could try Silent Service 2, which is the grandfather of the genre, but even though I have immense respect for its creator Sid Meier, the game feels its old age. It’s a bit simplistic and clunky, and I’m not sure that I would recommend it today. I’ll post links in future logs if I stumble on something good.

A great read! They say you have to there to come back. Nothing is wasted on a journey like this. I see many parallels with my explorations and finding an art direction in Daily Driver. You did it!

I’m really looking forward to this game. I’m a pacifist and don’t play games that involve shooting in but hopefully I’ll find enough to do in this!

(+1)

Thank you again! Yes I think I know what you mean: it’s a process. Sometimes I get this impression that I feel my way in the dark, but at every step, even when I hit a wall, I learn something. And the more I stumble, the more the game comes into focus. It’s as much, if not more, about clearing out the mess, than it is to come up with ideas.

I certainly respect your aversion for violent games, as I share it in part, maybe with less purity. I’m not sure if you’ll find something of value in Atlantic ‘41, but I can say this; I take the subject matter very seriously, and I don’t want to make light of war, quite the contrary.

Other than the focus on the management and strategic aspects of the gameplay, I’m very interested in tackling the moral component. I hate preachy games (anything preachy really), but there’s something unique about war that it puts ordinary people in situations where they have to balance their values and humanity against their survival, or the lives of the people they love. I think there’s a great opportunity there to let the player confront their own moral compass, and really appreciate the consequences of their actions, without the game ever hammering its own message, or cheating them  into “the right way”. It’s something that Lucas Pope achieved with brilliance in “Papers, please” and that I modestly aspire to emulate.

I look forward to it!

Another excellent devlog and glad to see you're still working on it! That new conning tower view looks perfect! Like you say, I'd call that part done and move onto other things. Good job on the clouds too!

(+2)

Thank you! I will work on  time of day next, which is a really important tactical component,  and start implementing surface vessels and a basic gameplay loop where you can play cat and mouse against one ship in a closed sector.