androminion
androminion copied to clipboard
New Game Engine
As the complexity of Dominion has grown, the weight of the more complex mechanics and underlying design assumptions of the VDom engine have been stretched to their limits. This has made it hard to implement new features and maintain existing ones. As such, I believe it is time to create a new game engine. In case you don't know what a game engine is: it's basically the code that simulates the rules of the game, as opposed the code that displays the game or takes input from the user.
Some issues with the existing engine
- Hard to implement a new or adaptable AI agent
- Hard to update existing AI code for new mechanics or cards
- Can't save state of the game and restore later (e.g. app switching / device reset)
- Network code is hard to use and unnecessarily coupled in the engine
- High coupling of UI labels to engine code - There appear to have been 2 different UI layers in VDom before the Androminion UI was pasted on top, neither of which was originally built for localisation. This has led to many strange issues in localisation efforts.
- Many rule interactions between certain cards are hard-coded and are hard to maintain (or even make functional at all). This includes things like the "lose track" rule, Duration effect tracking and ability ordering, to name a few.
- Common functionality is duplicated across many of the card implementations, leading to less maintainability, bugs, and bloated app sizes.
Proposed features for new engine
-
Cards defined via configuration files (instead of code) which will allow for:
- focusing on mechanic implementation in the engine, making the code overall simpler and more manageable
- making AI players more adaptable to new situations by responding to mechanics rather than specific cards
- easy injection of fan-made cards (as long as they obey existing mechanics), or play-testing card tweaks
- decoupling engine/app from card configurations (if this is ever needed)
- adding new cards in minutes rather than days/weeks
- well-defined errata for cards (so you can disallow Possession token taking or allow Masquerade pins)
- Game Undo
- State saving/restoring (which undo will facilitate) - which means the game won't quit on you when you switch away from it ever, or even restart your phone
- Card descriptions that can be automatically generated from the rules configurations (would allow for automatic localisation of fan cards, or even official cards)
- Localisation friendly engine - no text strings built into the core of the engine
- Abstract game logging layer built into the engine (makes it possible to show the log in different ways and from different points of view)
- State Cloning and what-if scenario execution (making it easier to implement more advanced AIs as well as executing test scenarios)
- Crash reporting hooks
- Little to no hard-coding of parameters (allow for tweaking game rules more freely - e.g. number of cards in a kingdom pile)
Status
This engine is still in the design phase. I've done an analysis on all existing cards (and some well-designed fan cards) to find commonalities and am currently working through putting these into a design structure that makes sense in code given the aforementioned features. (In case you've been wondering what I've been up to for the last while). Note that if this engine isn't ready in time for the release of Nocturne, then Nocturne will most likely be implemented in the old engine as well, depending on the complexity.
Feedback
I'd like to hear your input as to what features you'd like to see included. Note that this is just a game engine rewrite - the core of the Androminion UI will most likely stay intact (at least for this change). Feel free to also relate features you'd like to see in the UI that might influence how the engine is built. This way the engine can be designed with these features in mind.
Features that i'd like to see :
- show kimdom cards before playing with the possibility to say "No i don't want to play with that card" or "I like those cards. I keep them and regenerate the others.
- save up to x last games so we can replay those cards later.
- add the possibility to set as favorite a game do we can replay it later.
More technicaly, if there's a rewrite, why not migrate to graddle ?
Globaly i like the UI. But I think we can modify things. For sample when you click (instead of long click) on a card it shows the dialogs with the infos of the card. On that dialog we could show a button Buy if we are in the buy phase.
@stcoquelin Sounds like an additional feature of the engine should having the logic for selecting cards be separate from the core engine itself. This should probably be a separate feature to allow for a saved kingdom repository and a kingdom generator. This should allow for saving kingdoms and replaying them as you have requested. The current engine does this to a degree, but not entirely.
The other UI feature you have mentioned about a buy button on the card info shouldn't have any bearing on the core engine.
Overall, great feedback - keep it coming.
For me, there should be 2 engines
- the game engine itself that kows how to play. It should contain a communication feature that send and receive informations with players
- the kingdom generator engine
Then there is features :
- the network (or blue tooth, ...) features that makes a bridges between players and the communication feature of the game engine. It is a another application for the server.
- tools (log things, get localized cards, ...)
The UI interacts with all of those things. For me, saving favorites or games played is for the UI (eventualy via the tools features for having a standart).
@stcoquelin Until I try this interface out (single tap to show text), I'd like to have the old interface available (long press to open text). This sounds similar to Ascension, although it's double tap to enlarge the card. Dragging cards to the appropriate area lets you play, discard them, etc.
-
In a previous submitted issue, the "Last Played Game" option was (for the most part) locked down to strictly being the last game. I'd like to be able to fine tune tweaking various options: -with or w/o Platinum/Colony -with or w/o Shelters -Swap in/out Landmarks -Swap int/out Events -Have a different Bane and/or Obelisk card -Set Different # of players/AI types
-
text log updates --be able to search the text log for specific words --colored fonts Don't know what schema to use. Perhaps matching card colors (so for example, Province would appear in green, Witch would be in red)
-
Whenever a card is discarded (like resolving Sea Hag), it'd be nice to see what that card was without going through the text log. Don't know if this could be "flashed", as IIRC that was only for "reveals".
Thank you for doing this. It has been long overdue. I will try to help out, but don't have much time at the moment. From October on I will have time again to help out.
The biggest challenge I see are having the cards completely in configuration files. Some cards interacting with each other are already difficult to get to work correctly in Java code, and are probably even more difficult to get to work with generic configuration files. It's all the edge cases I'm worried about.
Might be we cannot get around allowing some scripting for cards. Maybe have hooks in the engine to write Lua scripts to add mechanics. New mechanics from official and fan expansions could be added this way without changing the Engine and releasing a new APK. But I haven't thought about this very much so it might be not feasible.
One important thing for me is the logging that you already mentioned. The full log should allow you to completely reconstruct a game. This would also allow the option to replay a game starting on a specific turn. Which is interesting if someone wants to try different strategies.
Something I wish for, but don't know if it's in the scope of the engine rewrite would be to redesign the Client-Server interface. A clearly defined and documented API for clients to communicate with the server is essential if ever want to get multiplayer to work out of the box in the App.
@stcoquelin I agree with the point on splitting the main game engine from the kingdom generator. I was definitely planning on doing that anyway. The part of the game engine that requests player input will be completely uncoupled from the networking layer, but a networking layer will be built as a potential player input mechanism. Possibly a network stack layer could be added on top of this to facilitate playing over different network stacks (TCP/IP vs Bluetooth). Having a saved kingdoms feature would probably be a separate feature that wouldn't necessarily be attached to the main engine. I'm not exactly sure what you mean by "tools", but the engine should have means to be attached to a logger for debugging/error reporting purposes. I was mostly asking about core features you'd like to see in the game overall that might influence how the underlying engine is built (an "undo" feature is a good example of this).
@ayao44
- Tweaking last played options: Having the engine be able to take whatever game configuration is given to it to play should allow for this. The current engine can mostly do this, but the UI isn't currently up to snuff there.
- Game log searchable and coloured: Having the engine generate log updates and logs in general in an abstract format should allow for this. The current engine sort of does this, but the UI doesn't track the log abstractly - it generates the text for a log entry from an incoming event and leaves it at that. Colouring the log in some way might be an interesting feature, but the colour contrast would have to be really good. I think a neat log feature would be to show a turn summary in the log. (most of the time you care about the gained cards in another player's turn) Sometime I'll have to flesh that out as a different feature (UI).
- Visually showing card discards: This shouldn't have any bearing on the game engine as a feature, fortunately.
@schoeggu Once I can get the main core of the engine in place, it should be easier to collaborate here on it.
Viability of configuration files vs scripting: I think it will actually be easier to get the edge cases to work out since the rules of the mechanics are what is in the engine, which, by nature handles what were edge cases in the old engine. Think of the configuration file as a way for the card's rules to be read by the engine. Here's an example of a card, Artisan, in JSON format (don't get too hung up on the syntax yet - and, yes, it's missing name localisations):
{
"name": "Artisan",
"cost": 6,
"type": "Action",
"play": [{"do":"gain","to":"hand","maxCost":5},{"do":"deck","num":1,"from":"hand"}]
}
This syntax looks a bit like coding in JSON, but that's a side effect, since you're expressing structured card instructions. I had thought about allowing scripting for cards, via Lua, Javascript, Python, or something, but I thought it would be better to stick to defining a more rigid schema (at least for the time being). This has at least two interesting properties (there are many others): 1) you can't misconfigure a card - it will always obey the core rules of the game or it won't be processed, and 2) you can generate the text of the card rules based on the configuration. Obviously, this has the downside of not being able to add new mechanics on the fly, but it also helps prevent silly things in cards like if (player.name == bob) player.points += 42
.
Resuming prior games: It would be interesting to allow the game to start from a certain point (as opposed to just undo). I'll keep that in mind. This would probably require the ability to save a replay of a game and later load it up and skip back and forth through it, then take over playing at the point you desire. Definitely a good thing to keep in mind. Good feedback.
Concerning the network protocol: The Client-Server (network) protocol will most likely get an overhaul as part of this. It remains to be seen as to whether this happens when first hooking up the new engine or if we'll end up writing an adapter to the current network protocol. I'm not sure the current network interface is expressive enough to transfer over the needed information, so the former is most likely. Getting the framework in place to later allow multiplayer to work "out of the box" is one of the goals here.
I'm all for it, especially if it means the network errors stop. Feature suggestions:
- Toggle for "select cards to discard" vs. "select cards to keep" with militia, for example. Optional for those who really like the current setting
- Tab support. It would make a huge difference on smaller screens (but require some UI rework). Example would be the play logs but also the big stacks next to your hand like Islands, Trash, Tavern, Distant Lands, etc. I think Blackmarket should stay somewhere close since sometimes you might want to see the descriptions of cards, but the other stuff can just be separated by tabs at the top and when you switch tabs the kingdom cards go away and you can just see that pile.
I'll try to think of more while I'm playing and jot them down.
Suggestions: Can we migrate from Ant to Gradle so that we can easily use Android Studio to compile the apk? Integrate multiplayer into the releases without having to separately compile vdom?
dominionator thanks for all your hard work on this amazing game!
My only "wishlist" is to support more than 2 players in multiplayer :)
thanks!
@powercat The plan is to make the engine able to support any mix of players: AI, local, or remote. It will be a later feature to enhance the UI to facilitate local multiplayer, but it will be designed to work much easier than it is now (possibly using a Wi-Fi Direct connection if needed).
A repository exits so we can help ?
@Kokyett The new engine is currently on hold for a bit while I finish up Menagerie on the old engine. I'm still working out the basic structure of the engine (though not as actively as I could be), as that needs to be done first to be able to accomplish its goals. Once that is in place, it will be much easier to collaborate on it.
If you have any ideas for the new engine, feel free to post them. It also might be a good idea to get familiar with the existing engine so you can learn about its deficiencies if you're looking to help.