A few weeks ago there was a thread about using AI to finish abandoned projects, and a comment from avereveard https://news.ycombinator.com/item?id=47905088 on building their 100x100 grid battleship got my spark. I didn’t build that, but it pushed me to finally finish a combat idea I’ve been wanting to play for ages.

Introducing Naval Strike!

It’s a simultaneous turn-based fleet vs fleet on a grid played in the browser. There’s no account or signups needed. Both players plan their moves, then the turn resolves at once.

There’s three different play styles:

* Solo. Procedural maps and uses guided “AI” opponents (in the same way that 1990s games had “AI” opponents)

* Scenarios. Objective missions on procedural maps like "rescue the downed pilot" or "destroy the convoy"

* Campaigns. Historical battles on real-world maps (Sink the Bismark in the Atlantic, or escort the tankers through the strait of hormuz)

A few things I figured HN would ask:

I designed the architecture and Claude did implementation. While 90% of the decisions are mine 90% of the lines are AI-written. Lots of micro managing short bursts to get it to look/feel right. I think I consumed a week’s worth of tokens just to get the fog working how I wanted. Eventually I learned that having lots of small bursts of code with testing got me to where I wanted much faster than longer sessions. I built preview pages so I could test animations, sequencing etc without affecting the codebase so I didn’t chew through my tokens.

Stack. TypeScript/Canvas 2D, hosted on Cloudflare. The server is a tiny WebSocket relay, it pairs two players by room code and blindly forwards messages, with no game logic. So there’s no accounts and no tracking beyond default Cloudflare insights. Just open the URL and play. Opponent AI is guided scripted tactics with situational decision trees.

Art is a mix of AI/hand. I’m not artistic enough to do everything by hand, but there’s a lot of manual pixel by pixel editing on the assets. Assets are stored as JSON arrays and drawn directly to screen with a colour palette.

I ended up building a small map editor that lets me "trace" Google Maps screenshots to get the campaign maps geographically close to the real engagements. Sounds are from open source libraries - you can mute them with the little speaker button but they are on by default which might upset a few people.

Although this was largely coded by AI, I got heaps of enjoyment being able to focus on the UX, style, gameplay and UI to be just how I wanted. Being able to test (and throw away many!) ideas so quickly was awesome fun.

Feedback welcome. Especially on balance and the campaign design and gameplay, it’s hard to play-test every variable!

Nice job. As someone who spends an inordinate amount of time on pixel art, I immediately noticed that something was off on the logo [1]. When I brought the PNG down, it looks like when you were trying to clean the asset (probably a background removal tool that was too aggressive), you accidentally made part of the hull alpha-transparent.

Also, consider adjusting the sprite assets for the frigate and cruiser. Right now they look very similar, which could be frustrating if a player wanted to do a quick visual scan and identify which ships are which.

[1] - https://navalstrike.app/assets/naval-strike-logo-xIcrDNQX.pn...

Thank you - you're right, it must have been when I removed the background surrounding the logo, I did it on a colour not the area and missed that the hull was the same shade. I'll fix that :)

I'll play with cruiser sprite too, if you're curious this is how I save them:

  frigate: [
    "................",
    "................",
    "................",
    "...kkkkkkkk.....",
    "..kHHHHHHHHkk...",
    ".kHgGGGGGGGgDkk.",
    "kHHgwGttGttwgDkk",
    "kHHgGGGppGGttgDk",
    "kHHgGGGppGGttgDk",
    "kHHgwGttGttwgDkk",
    ".kHgGGGGGGGgDkk.",
    "..kHHHHHHHHkk...",
    "...kkkkkkkk.....",
    "................",
    "................",
    "................",
  ],

Nice~ I used to do something similar back when I made little games in BASIC using blocks of sequential DATA keywords to visually represent on/off pixels for the various sprites.

that brings back painful memories of typing lines and lines of DATA keywords from library books into GW BASIC.....

I'm an embedded engineer, so it's how I would encode a sprite for displaying an LCD character, it seemed natural to do it this way!

ETA: I've fixed the image transparency and the frigate sprite is less fat, thanks!

Very cool. It’s been a while, but years ago I remember using a nice little tool that somebody had made that let you export BMP pictures to an array you could drop into an Arduino C program for displaying on an RGB LED matrix.