The Legend of Syro is a strategy RPG based on Sega’s “Shining Force” series. This project originally started out as nothing more than a way to pass time and to better improve my programming skills. Since this project was first started in 2014, its popularity has grown amongst the Shining Force fan base, and inspired several other programmers to begin making games of their own.
I never imagined that a small passion project would have such an impact on so many people, and the enthusiasm, and feedback I receive fuels me to make this game the best it can possibly be.
After a cataclysmic disaster than nearly destroyed the continent, rendering it un-livable, our heroes must search for a new land in which they can call home. Enemies and allies are made as the group arrives on the continent to the east.
This story has been quite fun, and sometimes stressful, to craft over the years. Overall, I try to keep every location, and character unique. Each character has their own distinct personality, and their own reasons for going on this adventure. Their contrasting views and ideologies cause them to clash often, and in some cases, gets them into trouble.
Every town, and city you visit has its own unique culture. Whether it be the city of thieves, a busy port city, the home of the birdfolk high above the badlands, or reptar village in the northern swamps, I always try to ensure that each location is fun to explore, and very different from other places on the map.
I want the world to feel alive, and to reward the player for choosing to explore and learn more about the world where their adventure takes place. Something I try to keep in mind when writing this story, and especially NPC dialogue, is that the player and their party aren’t the only adventurers in existence! There are many other heros, villains, and adventurers in the world, each looking to achieve their own goals. Your paths may cross, or they may not. All in all, I try to keep in mind that events are transpiring all over the world, whether or not the player is a part of them. The player isn’t the hero of every story.
It’s been a while since I really had time to sit back and reflect on the journey this project has taken me on. I originally started this project during my sophomore year of college, having taken CS1 and 2 (your basic programming courses) and intro to game design. At that point, I wasn’t aware of proper design, object oriented programming, and how important it is to plan things out and re-use code wherever possible.
When I started this project, I did so because I wanted to make something truly special and not just another simple prototype. I wanted to work on a much larger project and really spend the time to sit down and make it as good as it could be. Don’t get me wrong, some of our class projects were super fun, but when you’re still learning proper coding techniques, and you only have a small amount of time to work on each project, you tend to end up with 10 basic prototypes as opposed to one fully functional game.
I often tell people that starting this project was both the best and worst decision I could have made at that point. Out of all of the possible games I could have made, I chose to make a strategy RPG inspired by the game that originally got me into game development when I was 6 years old, Shining Force. What I didn’t realize at the time, was that this particular genre of game was the most involved, and it required a lot of knowledge that I didn’t have yet. Things like object oriented programming, code re-use, pathfinding, and AI. Knowledge that I would only obtain in my later years of college. That said, I dove head first into an uphill battle that I definitely wasn’t ready for, and in doing so, I learned way more than any class I have ever taken.
As stated previously, I hardly knew what I was doing when I started this project, yet over the course of sophomore year, I had a working prototype for the game’s battle system. However, with the start of junior year, I had to postpone the project as I was now taking more difficult courses, such as AI, and they required a lot more time than previous courses. As the year came and went, summer break finally rolled around and I was once again ready to work on this project.
Upon re-opening the project file, and glossing over the codebase, I began to realize how bad the code actually was. It worked, sure. But it was not at all user friendly, and most of it was spaghetti code. As such, I decided to take my newfound knowledge and completely start from scratch, and this time, I was going to do things right.
What previously took over a year, took only a few months. Systems and functions were now scalable, and self-contained. I was using proper parenting techniques, and re-using as much code as possible. I cut my original line count by 70% and the game was able to do twice as much. This was when I released my pre-alpha demo.
I had previously released demos before, but they were all just tech demos. A single battle that would just loop infinitely when you won, assuming one of the many bugs didn’t crash the game. This new demo however, was a short, mostly bug free, and complete game. It was a huge milestone in development as I now had enough of the battle code done to start working on towns and cutscenes. A few months later, I released the alpha demo, the first part of the main game. For the first time in the history of this project, the game had finally started to look professional and at long last, it was bug free. (Seriously though, that floating point error was a pain to fix!)
When I first started this project, many Shining fans were skeptical and kept their expectations low. For around 10 years before I came along, the community has had many members attempt to create a Shining style game but for one reason or another, they never came to fruition. As such, while many people were excited about my project, others simply wished me luck but also mentioned that no fan has ever completed a standalone game that didn’t rely on rom-hacking, and they wouldn’t be holding their breath.
Many of the older community members had been let down over the years seeing so many projects come and go. Of course they would be skeptical of a young college kid who was promising not only a feat that no one had successfully came close to completing in 10 years, but also promising full access to the source code, and an easy to use system for others to make their own Shining games.
While many people would get discouraged from such responses, it fueled me even more to see this project through to the end. In time, as my project became more and more complete, many former skeptics began to take notice and realize how serious I was taking this project.
I can’t justify talking about this project’s story without bringing up AI. As I talked with the community, it became apparent that AI was the thing that everyone wanted to be as flexible and as easy to work with as possible. I don’t remember exactly, but it took me around 3-4 re-writes to finally get AI to the level of flexibility and usability that I wanted. And man is it glorious!
Before I can explain how AI works, let me talk about Battle States and Triggers. Each map is split into several regions. The player typically starts in region 1, and as they move further into the map, this number increases. Battle State is determined by what region you are standing in, and if your army is split between multiple regions, the highest number is used. This is useful for having the enemies behave differently depending on where you are at on the map.
Triggers are a bit different. Each character has a set of triggers that can be flipped due to many different events. Let’s say you are up against a group of 5 enemies. A leader and 4 soldiers. If the leader is killed before his soldiers, the remaining troops might have a trigger set which causes their AI to change from making smart decisions, to running away in fear.
Now we can talk more about how the AI works. To start, I created a list of possible actions that the AI can perform. These are things like attack target, cast spell, use item, follow target, end turn, etc. Each action has what I call ‘fail cases.’ For example, if you tell the AI to cast a spell, but they don’t have enough magic to do so, the script will fail. These fail cases can be fine-tuned as well, but I’ll explain that later.
Each character is given a list of actions to try to perform in the order you want them to attempt to do so. If any action successfully runs, all other actions listed after it do not. For example, a basic melee AI would be as follows.
Attack Target
Move Towards Nearest Target
End Turn
First the character will try to attack a nearby enemy. If the character does not have any possible targets, it will try and move towards the nearest target that it can attack. This way it could hopefully hit something next turn. If that fails, then the nearest enemy is so far away, it’s not worth chasing them down and we should just end our turn.
As I mentioned earlier, each action can be fine-tuned to better control how the AI behaves. For example, you might want to change the heuristic used to choose which target to attack, or cast a spell on, or change when such an event takes place. You might have a fighter who can cast a few weak healing spells, but they’ll only cast them if A. Their allies are in critical condition, or B. if all other enemies are already defeated, as they prefer to fight rather than heal.
This is just the surface as far as AI is concerned. I can talk for hours about the different possibilities you have access to using all sorts of different triggers. That said, this should at least give you a general idea as to how the AI works.
Sometimes you don’t know what your game is capable of doing until you do. There have been many cases where I’d add a feature and through testing, or player feedback, I realize that I can use this new feature for way more than I originally thought without needing to change the code. Those are fun moments.
A while back, I added an enemy death event, and its main purpose was to tell the next wave of enemies to reveal themselves once the previous boss was defeated. The enemies weren’t spawned in dynamically, they were simply placed on the map and toggled ‘off’ until the bosses death event triggered them to reveal themselves. It was a very specific thing that I needed for my Christmas challenge battle. The first thing I was asked when I mentioned this new event was if it could be used to spawn in 4 smaller slimes around where the first, larger one was killed. The answer was yes, and I now had a new idea for the sewer battle in chapter 2!
Overall though, my favorite accident was the summon spell. Someone asked me to add a summon spell to the game a few years back and I said sure, thinking nothing of it. I mean the concept wasn’t too hard, you just target an empty tile with the spell’s target selector, and poof a new character into existence. Yeah, it wasn’t so simple.
When I sat down and actually thought about the spell, there were so many different possibilities. Does the summoned creature last for X turns? Do they last forever but drain the caster’s magic each turn? If the caster dies, does the creature do so as well? I had a lot to think about! So I did the only thing I could have done at that point and added the ability to utilize every single scenario.
That in itself is very useful, but then I realized… this was a spell… As a spell, it had access to all of the spell variables including AoE. As it turns out, despite being a totally new spell, my spell system didn’t have any problem summoning 15 wolves at once! Wait… I’m creating a character which means I have access to all of the character variables and event overrides… Oh this is going to be fun! Long story short, this spell can do almost anything. For example, I summoned a creature who was able to summon itself, which would then lead to an infinite chain of summoned creatures. Once the original caster died, each summon died one by one triggering the next in line to disappear. The game didn’t break during any of these extreme cases, and left me feeling accomplished, and gave me so many ideas on what I could do in the future with this spell.
Chapter 1 Trailer
Chris Putnam's "Let's Play" of a super early demo (Alpha 1.3)
Latest Version (Beta 1.1): Download