User:Renegade/OpenYR
- This entire thing is a list of proposals. All points are up for discussion and direct editing by the people involved.
This page was conceived as a general master plan and brainstorming for the development of what I will refer to as "OpenYR". The goal is to find common ground and to agree on enough base parameters to start developing the project together.
Name
The name would actually be the first issue to discuss; I propose "OpenYR" because the naming scheme mirrors the scheme used by other projects of similar kind, and it's as descriptive as can be, without directly violating any trademarks.
This descriptiveness also makes it easier to search for for others. When somebody searches for an open source Yuri's Revenge clone, he's way more likely to Google "open YR" than something like "VoxelBattle Elite".
License
An open license, obviously - I propose the GPL, not just because I prefer it, but because of compatibility with other free software projects; if we choose a BSD-license, our license will be free-r than GPL - since the GPL requires to share alike, we couldn't just take GPL code and drop it into our BSD code, because then we'd violate the GPL by not sharing alike.
On the other hand, since BSD is so free, we can just take BSD-license'd code and drop it into a GPL'd code base without problem (at least 3-clause-BSD'd code).
I do believe the latter is desirable in order to be able to use the maximum amount of existing code. It'd be unfortunate if there were a FOSS library doing exactly what we need, but we couldn't use it because our code base is too open. See also this post.
The XCC utilities' code is GPL'd, for example.
Development goals
The goal, in my opinion, would be simply emulating YR as much as possible, while going beyond it.
In practice, this means ideally, it should be possible to play YR as before with our binary. Playing OpenYR should feel like playing YR. On a quick glance, the casual observer shouldn't notice there's anything different about it. OpenYR should feel more like an expanded YR than a completely new project.
This does explicitly not mean multiplayer- or savegame-compatibility, though.
Rules should be transferable, assets generated for RA2 and YR should be usable, but it's completely unfeasible to maintain compatibility for data closely tied to the engine's internal structure and feature set.
Also, we should try to improve details where possible - e.g. fix typos in flag names, leaving WW's as aliases but defaulting to and propagating the correct ones.
Development style & methods
Quiet, but marketable development
Meaning: We'll keep a tidy website, good documentation, lots of shiny screenshots, and make the binaries easily accessible - but we don't beg for community participation, don't develop for anyone but us, and while we accept feature request submissions, we decide on our own what to do about them - community demand is secondary.
Basically, we'll be welcoming to everyone, but we won't go out and actively market the project.
We'll keep quiet, we'll keep to ourselves, if somebody finds us and likes what he sees, good, if not, no effort was wasted.
This allows us to code pressure-free and with minimal community-management and promotion work, and, on the other hand, keeps the door open for those who develop interest on their own.
No fixed releases
In the same vein, I propose not having fixed release versions.
Instead, I propose branching for everything, and always keeping the trunk rock solid.
That way, we can simply compile the trunk after every change, and have a permanent link to the trunk binary as the latest stable on the website.
We would essentially do feature-based releases. Every new feature merged into trunk would lead to a new stable binary, linked as the latest stable.
In practice, we'll probably wait and merge several features at once, but the overall point is not having planned releases, and having frequent small releases.
This takes pressure from us, because we aren't stuck with a list of X boring features we have to develop until a certain due date, and it makes things more enjoyable for the players, because they frequently get new features in a stable release.
Positions
We already have de-facto positions in Ares development - I do a lot of the infrastructure and management stuff, D is essentially the Lead YR++ Designer, and Alex practically owns super weapon development these days.
Nevertheless, I do think we should agree on positions or Areas of Authority for OpenYR development.
This serves two purposes:
For one, it clears up ambiguity. If no one officially owns anything, no one is responsible for anything. If it's clear "Alex is Lead Super Weapon Developer", then it's clear any SW-related bug belongs to Alex by default. That doesn't necessarily mean he'd be stuck with it, or that no one else can touch SWs, but there'd be a certain clarity of where to go for SW-related stuff.
Secondly, and this relates to the touching by other people, it also enables us to make decisions when necessary. Sometimes, we may disagree, and if there's an Appointed Leader for a specific Area of Authority, then said leader can go and make a decision on his own, if all else fails.
Consensus is good, and compromise and friendly debate are definitely desirable, but one unpopular decision after a month is worth more than five years of debate.
Minimal Viable Product/Multiplayer
I believe it should be a primary goal to get something playable in multiplayer as soon as humanly possible, for two reasons:
- Debugging. The sooner we can actually "play", especially in multiplayer, the sooner we can properly debug in an actual game scenario, instead of writing unit tests or thinking "theoretically, this should work".
- Promotion. Something playable looks better than theory. It's as simple as that. Think about how many abandoned C&C recodes had fancy screenshots of "look at how we can render terrain" or "we can import voxels, look!". Nobody gives a shit for that. It doesn't matter if the entire thing allows nothing but selecting pre-placed units and letting them shoot at the enemy. As soon as there's something playable, people will notice the project is actually going somewhere, and will be much more inclined to follow and support it.
We can post a hundred screenshots - if we don't have a product, people will quickly lose interest.
On the flip side, if we actually have a multi-playable product, people have a reason not only to actually interact with it, but to tell their friends about it, too.
In my opinion, the MVP should at least include the following:
- The ability to select units and have units fight against each other
- Multiplayer capability
- Communication capability
So in the most minimal case, people could load up the "game" and play small MP-matches on a hardcoded map with pre-placed units while chatting with each other.
Not exciting, far from a finished product, but a good demo to get people interested and show them we're more than the regular "look at my future engine" crew.
Accept our heritage
We should respect YR for what it is, and accept the limitations that brings.
Yes, we are starting from scratch, and yes, we can code whatever we want; but if we start with funny business like trying to port the game to 3D, we'll not only go down the rabbit hole, development-wise, but we'll also lose sight of our original goals, and will end up with a feature-creep'd OpenYR that is very much unlike YR.
While I am in full support of expanding the game's and engine's capabilities, the overall look and feel of game in its standard configuration should be close to YR. If somebody wants to mod it into StarCraft, fine, whatever. But "OpenYR" shouldn't start looking like Dark Reign 2 at some point.
Reject our heritage
Just because we don't want to use our freedom to stray too far away from YR doesn't mean we want to stick too close to it, either.
Alex suggested writing a list of everything we learned from YR and don't want to repeat - like hardcoding the number of weapons to two and not letting them fire at the same time, or having plugins, but having them in such a castrated form that they're practically worthless.
I think writing such a list as a perpetual warning and reference would be a very good idea.
Technologies
- Subversion and Mantis as before, obviously, but pre-planned this time. We should sit down once and talk about the pros and cons of everything we did for RP and Ares, and adjust our systems beforehand. e.g. having the user documentation in the binaries folder and code documentation next to the source has proven to be kind of annoying in day-to-day coding.
- C++ with SDL; we have the opportunity of doing things the right way from the get-go, and I do believe (not just because I'm directly affected, but on principle) cross-platform-compatibility is of the utmost importance - that automatically rules out things like .NET and Java, who may pretend to be the holy grails of cross-platform-capability for marketing, but are actually everything but.
C++, in my opinion, offers the best trade-off between features and ease of use, and the SDL is the go-to library for a variety of projects of the same kind, both making it a proven solution for this type of development, as well as giving us a certain base of support if necessary.
The SDL would already give us graphics, audio, networking, and a shitload of other stuff, on all important platforms, so we could get right into coding what we want, instead of coding what we need, so to speak. - Jabber or IRC (see below)
- Lua (see below)
Code & Features
Extensions
We should offer an extension system, Lua or Python-based. I would prefer Lua, but that's a detail. It will probably be a bitch to code, but it serves three purposes:
- Increased modability, which will drive more ex-YR-modders to us. In the best case, we will get a thriving extension community above the pure modding community.
- Increased community-participation - people may not want to or be able to join in coding C++, but they may be able to grasp Lua and write a small script to implement a feature.
- Based on the above, streamlined development - if we see that feature X already has a widely-used extension, we not only know feature X is much-desired, but can ideally just port the algorithms of the extension into the base code.
I'm imagining this as "simply" us dropping a number of hooks in the code where Lua functions are fired, with a few helper functions, and then letting the community extend the game similar to how we do it with Ares. Simply by giving them the ability to create and read new INI flags and doing simple arithmetic at specific times we'd already have given them an incredible amount of new power. They could generate shields, for example, by creating a Shield= flag and recalculating damage in a PreDamage hook.
As said - probably a bitch to implement, but very attractive to modders, especially the ones coming from restricted stock YR.
Flat class hierarchy
Not no hierarchy, but not half a dozen levels deep, either. One of the primary problems and feature request sources for YR was feature X not being available on class Y. imo, we should only have three layers at max:
- A Meta-Layer
- Holding members for generic information we want to have about all types of objects. (e.g. a unique ID or rendering information or something).
- An Environment-Layer
- Holding all members necessary for this particular kind of object (e.g. "an object anywhere on the map" or "a force of nature").
- A Gameplay-Layer
- Holding everything for the actual functions of the specific area of use of this kind of object, e.g. one class for parts of nature, one class for "active" participants on the map, and so.
Objects would be differentiated by their properties, not by artificial restrictions. A building would be a building because it'd be a CombatObjectClass with MovementType=Building, not because it's BuildingClass. And if somebody wants to create a mod with objects with building properties, but walking like infantry, so be it. It's his mod.
If a certain feature has specific requirements, we'll document that, and catch potential exceptions. If somebody still thinks he should use functionality specifically designed for aircraft on submarines, that's his stupidity.
Yes, it makes sense to have functions only sensible for one kind of object restricted to that kind of object.
But if there's anything C&C modding has told us, it's that developers never see the whole picture, and that a whole lot of features can find a different use, if you only let them.
Just think of parabombs made out of paratroopers, or MakeInfantry minelayers, or DirectRocker EMP tanks.
We may think "feature X was designed for aircraft, it makes no sense having it on infantry", but a modder might disagree - and we shouldn't end up imposing the same stupid restrictions on him that Westwood did.
Types
Alex brought up the question of distinction between Types and normal units, that is, the distinction between values equal for all units of this kind, and those individual to the particular unit at hand.
My proposal is to keep the first instance of each kind, initialized with the default values, around as a "master copy" of that kind, and making future instances copies of it. We could add a (const) back reference to the master copy on each instance, so we could do Unit->Default->Value, while, at the same time, would have full control over all values on the unit.
Getters/Setters
Alex also mentioned having getters and setters instead of accessing fields directly. While I agree with that on principle, I propose writing wrapper classes with overloaded operators to provide "transparent" getters and setters, i.e. allowing us to use the property like a field, while "secretly" having the values piped through getters and setters.
This may be a little bit of extra work up front, but objects' properties will be much more natural to use, and we save us the pain of having numProps + (numProps * 2) members on each class.
Modularity
In addition to that, Alex asked about the logical division of the code, use of modules, etc.
I believe we should decide about that once we're clear about which libraries we'll be using - the SDL is modularized, for example, and if we started planning our modules now, we might end up misaligned with the usage realities of the SDL.
Console
A typical quake-like console for debugging, on the fly option changes, etc.
Will very most likely help development a lot, and be it only to show debug data flying by.
(An SDL-library for this exact thing already exists, emphasizing what a jumpstart SDL would give us)
Game-Independent Communication
Jabber- or IRC-based communication, asap as well. Generic players being able to talk while playing furthers community, coders being able to interact with other coders in general, and specifically with coders not currently ingame or the same game, helps development.
That last part is an important one, imo. This feature will be a lot more useful if we don't restrict communication to "within multiplayer games or lobbies", but simply design the game as a chat client.
Imagine how much easier debugging Ares would be if we could talk to testers like Tesla while he is in the game and doing stuff - he could say "okay, I did X and Y happened", and we could ask him to try Z and K as well straight away.
Similarly, players ingame could invite players doing other stuff to join them for a round, or just chat with them while playing.
Ingame Map Editor
Easier for us, since there's only one codebase to maintain, and easier for the players, since they don't constantly have to switch between applications when crafting a map.
I've used a number of map editors over the years, and the ingame ones were always better than the external ones. They're just closer to the game.
Music and Playlist Support
Even if you don't care about the players' enjoyment, we will spend a lot of time ingame, and will need music while we're "working".
SDL supports playing audio, and I'm certain we'll find support for both MP3 and OGG either OOB or via an SDL-library.
How to Start
imo, we should proceed as follows:
- Agree on a minimum viable product, on the absolute bare minimum necessary to release as "something".
- Agree on the technologies (language, libraries, etc.) to use.
- Agree on Areas of Authority and distribute them among us.
- Code without explicitly mentioning OpenYR to anyone until we have the MVP.
- Create a website showing it off and linking it, thus establishing a basic identity and something to show off when people are interested.
- Happily and pressure-free develop OpenYR as outlined above and below.
Roadmap
While I am in favor of not having fixed releases, lists of features to check off, etc., I do think we should agree on a few generic development priorities at the start. For example, I propose the order of
- MVP, thus establishing general unit-use and multiplayer
- Creating and loading maps, thus bringing variety into multiplayer
- Adding AI and enabling skirmish, thus establishing single-player gaming
- Expanding multiplayer with "fancy" stuff, like special game modes, global highscore lists, etc.
- Adding campaigns
The idea being that we slowly expand playability over time, leaving people with a subset to play with until bigger features are completed.
e.g. if we focus on adding AI first, and then release MP with AI players, that's nice and all, but also means there's nothing playable until we have a working AI.
That's not gonna help.