Inspiration
Back when I was a kid and Club Penguin was all the rage, I ended up grinding all of the Card Jitsu Snow battle mode. I cried when it went away because I couldn't match with friends in the normal modes and take on Tusk solo and win as a non-member anymore. And then came Slay The Spire. An absolutely phenomenal deck building roguelike. So what if they met?
And thus this idea - and this project team - was born
-- MV
The story is of legendary animals: The Teumessian Fox who terrorized a village, Laelaps, the dog that chased him away, Chelona, who insulted Zeus and Hera on their wedding day, and Gale, Hecate's involuntary familiar cat. In a twist of the tale, these animals are merely misunderstood, and seek to ascend to Arcadia - Pan's haven for all creatures of the wild.
What it does
You see, Card Jitsu Snow at its core feels quite boring. Every turn, you can make one move and one Action. Slay the Spire tends to get repetitive, with some deck archetypes winning out and the game being more about creating a deck than playing with it. Now Card Jitsu Snow, as in the name, also has cards. But they MUST be played in place of your Action, and always have the same effect (granted, different Ninjas specialize in different aspects, so you technically could pick one of the three). However, what if we mashed the two genres up:
Randomize your move set like Slay the Spire by drawing a small hand of random cards, then add a small, but significant "movement" cost, letting you and enemies move around the battlefield. Finally, (though not implemented yet), add and remove additional cards to and from your deck to modify your move set to better suit your play style.
Not just this, but planned are four whole class archetypes, procedural map generation, and interactable inanimate and neutral obstacles and traps! The fox is JUST THE BEGINNING!
How we built it
To make this game as accessible as possible, the frontend runs on a simple NextJS website, with Three.JS running in the form of threejs-fiber in order to allow for TSX. This allows for the server to handle nothing but the game. The game server itself is built out of the Netty Java Socket.IO API, to allow for all of the benefits that Java has in terms of concurrency, object orientation, deployability, and scalability (try finding a machine this WON'T run on! I dare you! I bet it runs on your Microwave!)
All of the NextJS pieces are organized into their own components and rendered dynamically using map() aside from very few static components.
The Java side was designed specifically with adding new cards and monsters in mind. The Java side handles all of the game logic, meaning that in order to implement a card or creature, you would simply have to modify the play() or nextMove() function in a new class that extends their respective base, and you've instantly added a whole card!
Challenges we ran into
First: Isometric views and transforms are hard. In order to render everything on a single canvas with a single camera, we had to fool the camera by rotating any objects to be perfectly normal with it. This, however, royally messes up the local axes of the object, meaning that in order to animate it next, you must constantly convert between rotation spaces. We solved this by transforming into and out of quaternions with the correct rotation axis order instead of computing rotation matrices ourselves, and saved ourselves a lot of hassle.
Second: Communication between programming languages, while incredibly nice for a stylistic choice (separate frontend from game logic and use the language that lends itself best to both), leads to double the setup overhead in a very short time. This was solved by efficient use of documentation and thorough intermittent testing. The end result is completely robust - meaning that a page without a server will simply connect to the server when it is present, and a server without a page will continue to exist and serve connections until killed.
Third: We had to use Solana without Rust (because three languages is far too many). While the Solana Rust API is very well documented, the Javascript one is third party and does not have as much support. By looking at a lot of example code and painstaking testing, we managed to get it working through RPC - on our terms!
Accomplishments that we're proud of
This was an incredibly ambitious project, and it took a lot of dedication to pour care and attention into every part of this. However, what we have ended up with is a completely maintainable, extensible, and understandable product (albeit, not enough comments due to rapid prototyping). There was so much that we had not dealt with before - such as rendering 3D on a webpage, Socket.IO (you would think one who has a website would have done this before, but nope!), and Solana, and we were able to pull through and create what is more than a simple minimally viable product.
What we learned
- Quaternions are the superior form of rotation
- Flat (non-square) isometric grids suck, and calculating distances inside them suck more.
- NextJS is not built for Frame-based object animation, but the way you do it is oddly clean
- Socket.IO feels jank, but is quite stable
- The blockchain is a cool way to document events!
What's next for Ascent to Arcadia
- More Fox cards
- More monster variety and AI
- Procedurally generated rooms
- Roguelike mapping and scaling (endless!)
- 3 more playable characters
- Storyline
- Possible Steam release?
Built With
- blockchain
- java
- netty
- nextjs
- socket.io
- solana
- three.js
- typescript
Log in or sign up for Devpost to join the conversation.