Closed RoiEXLab closed 7 years ago
Well I can see what I can do. I can imagine som simple black ink-like army inspired icons woul look nice. Something that would fit the style of the text. As a backup plan, we could maybe just use text. Either way, do you know if the UI would allow button pictures that changed to another picture when "mouseover", like they become highlighted before the player presses the button? That could maybe look cool :-)
BTW: Is the game window "resizeable"? Like withe the mouse? And would picures then also scale up and down?
The background color of the buttons is currently becoming darker when hovering over it... Of course we can change the image when hovering over the button ;) this can be done using css.
The window is rezizeable,but the image size is currently fixed at 150x150px
What I just noticed, those images are a little bit "old" ^^ The third image is missing the PBF button for example
WOW ! @RoiEXLab
Does JavaFX have any hooks into working easily for Android interfaces? These days we regularly get requests about running the game on Android. If this platform allows a responsive, say tablet, UI that could be a big plus. Otherwise if you're doing a full UI re-write you might want consider a different methodology that would be cross-platform.
WOW ! is right :) Rock on Brother
@RoiEXLab Looks great! :+1:
Instead of "upgrading" the code, I'm now going to rewrite all of the TripleA UI.
Since you believe a rewrite is necessary, may I make a suggestion? Could you approach this with a feature toggle? That is, incrementally add the JavaFX UI while leaving the Swing UI in place. Then you could add a command-line switch (or some other mechanism) to "toggle" between the two UIs (with the Swing UI continuing to be the default until you believe the JavaFX UI is ready). For example, simply having an if-else
on the feature toggle in GameRunner#main()
to kick off the appropriate UI.
One of the bigger problems I've seen in my limited time looking at the TripleA code is the amount of business logic that appears in UI classes (and, vice versa, some UI code that appears in what should be pure UI-independent code). In my idealistic thinking, taking an incremental approach to the rewrite would allow you to focus on a single UI "fixture" (e.g. a dialog, panel, etc.) at a time. You could first extract the business logic out of the existing Swing UI you are focusing upon so you don't have to duplicate it in your JavaFX UI. And then adding the JavaFX UI itself should truly just be wiring it up to the same business logic used by the refactored Swing UI. Obviously, the additional refactoring would probably increase the amount of work you would have to do up front but could possibly save time overall as having such a long-lived feature branch means you could be regularly merging UI-unrelated changes into your Java FX UI code.
Such an approach would also, I believe, allow you to regularly commit changes to master
in smaller batches rather than having a large merge at the end corresponding to your phase 3 (at least that's how I interpreted it in your description). Because the JavaFX UI can only be activated with the feature toggle, there should be minimal risk having it present in the code side-by-side with the Swing UI (other than an increase in code size presumably due to JavaFX-UI-specific images/resources you'd be adding).
You have much more experience with TripleA than I do, so apologies if my idea is just pie-in-the-sky thinking. :smiley:
@ssoloff Can't make any promises regarding a toggle. As you mentioned correctly, much logic code is inside the UI code. Since my goal is to make the code more modular this would probably achieve the complete opposite... @bung I will try to implement the UI using interfaces which will make it replaceable with any other similar framework. This will make an android version "easier" but not easy. Android uses a completely different system...
@bung Thought about it... Although Android supports Java 8 syntax and most of the code should continue working on Android, we'd still need to discuss how to controll the game without using mouse and keyboard.
Thanks for opening the issue. It's good we discuss every so often what really needs to be done. I've a PR work in progress that I need to push up soon that will help fork the user login creds over to a new DB, after some time we'll then be able to drop derby.
That then unlocks some more sophisticated DB usage and we can keep track of player stats, game challenges and tourneys. We will need a UI for those components of the game as well.
A big potential draw for TripleA is to add Conquest of the World (Risk style rules). That rule set is well known and has shorter games. Google analytics shows a lot of search interest in Risk.
We've made a good bit of progress on the TripleA admin side, but there is some more to do. I don't think that the forum consolidation has been really fully completed yet. A general tooling cleanup to remove old components, both in terms of code and websites is useful so we have less stuff to maintain. The release process still has a few manual parts to it, and the documentation could use another pass and some more work (clean up, formatting, editing, consolidation, pruning down)
Save game compatability. It's a topic which does not come up too often, but I think because it does not bite us quite as often as other issues (notably network serialization). For this one we have a deterministic and simply tedious task to use serialization proxy to make it so new engines will be able to load old save games. That'll take care of a major compatability issues we have when modifying the code, and also it turns out would be a nice refactor since the GameData
object is not needed and does not have to passed around all over the place when we do that. The only problem here is that these are not backwards compatible changes, and there are a number of model objects to do this for (basically anything that has a local variable of GameData
). I think though this work could be done in a week or two if someone really went at it. Once we complete this, and make network calls backwards compatible, our release number would likely be just the build number : )
speaking of version compat we could use a XML (map) version embedded in the XML files. This way we can update our XML parser to read the version and be able to work with both old and new. That will allow us to make more updates to the XML without break the game.
Testing - the high level integration tests are a bit evil in some subtle ways and there are not enough of the lowest level tests. Let's say for example that we have three modules that "talk" to each other, A->B->C. In tripleA we often do a test that uses A and verifies something in both B and C. The problem comes up when you want to test all of B and all of C. Since there are dependencies between the two, hitting every code path between them is a combinatoric explosion. Let's say there are 2 ways to call B, and 3 to call C, you have 2*3 test cases to write, and if you add a D behind that with 4 paths, then there are 4 times as many test cases now (this scales poorly). Instead if we can verify that A->B works really well, and then verify that B->C works, then we know A->C will work. For a longer (1hr) deeper look at this strategy, I very much recommend this video: https://www.youtube.com/watch?v=VDfX44fZoMc. So far that methodology of testing is the best I've found. To sum up on this point, TripleA needs a whole lot of classes to be pulled out from the existing structure and then tested as a unit thoroughly. The rest of the structure can then start to have chunks of code get replaced by mocks, and with luck the logic/complexity will become distributed and better handled. While doing this we will naturally pull out the game logic from most of the UI, and the interface between the two will become much cleaner, enforced, and verified.
Sry for the long unedited wall of text there of some items that would be really helpful.
I think when picking what is next, focusing on benefit to code base and users are the biggest considerations. JavaFx might not yet be the right thing to pick IMO for a few reasons:
Another consider is I would try to make sure that whatever is done can be done in iterations. Ideally branches live for as little time as possible. This means merging relatively small changes on a frequent basis. Most to the point, if someone spends a few weeks coding, the changes will be almost impossible to review, and require a lot of testing effort. Ssoloff had a good suggestion on how a longer running UI change could be done so the merges can be frequent and relatively small.
In short, some of the things I would look at / consider:
Sorry for the rant @RoiEXLab , hopefully the above gives you some context and background on the number of things I've been thinking about as priorities and on the list of things to do. Sorry to get off topic from JavaFx quite as much, though in summary I believe there is either a lot of back-end infrastructure work that we woudl probably want to do first to make that more feasible/easy, or alternatively there are a few areas of focus that could use attention (game moderation, game play/features, Conquest of the World, game challenges/tourneys)
Finally, ti woudl be really killer if we did get touch devices working. With logged in accounts, since we are hosting our own server and have a lot of disk, we could provide file saves. That combined with very nice PBEM and match making, we could really get some great mileage on teh offline game playing experience.
No Problem @DanVanAtta Although I will continue working on the new UI, I'd like to tell you a couple things. You're right. There are a lot of things that would have a direct benefit for the users. There's a reason I chose to replace the current UI. I'm currently designing the new UI using fxml documents which are going to be loaded from the java code. This is a completely new system, not compatible with the old UI at all. In other words: Those changes are forcing me to seperate UI code from game logic, which will make future changes to the backend far easier! Regarding the problems with reviewing: This is why I planned the 3 stages: Once the fxml files are ready, I will put them in a PR. They will be useless at this point. After that the controller classes will be created which enable us (the developers) to open the UI and navigate through it, but still not start games etc. The 3rd stage will be the interesting part. This is the part where code starts getting cleaner and more modular. I will be forced to refactor the existing UI classes to have the UI code seperated from the backend code in order for me to use this backend code.
I do not intend to dissuade you @RoiEXLab , I would like to get off of Swing. I do think there is a good bit of risk in this plan:
To be frank I think you may be setting yourself up for the FXML version of the same problems encountered last time we went to javafx.
There are two things I would really encourage:
reverse the order of your plan, start with the backend, then build controllers, then swap out swing for javafx.
Slice the project up a bit. I still strongly recommend starting with the backend first, but beyond that perhaps don't take on the full game engine as your scope. That could mean start by updating the setup screens first, then lobby screens, then the battle screen only, then the game window proper. Swing and JavaFx can live side by side, I suggest we do take advantage of that and migrate parts of the game at a time.
There are a number of risks to consider when a large amount of work diverges from master and then merges back in. Testing could take a very long time as well (weeks), merge conflicts could introduce extra risk, and there could be overruns. It might be way more than a 6 month project to fix up the backend code, you may find you have the Fxmls and controllers, but only a quarter of the backend updated and are out of time.
You have some good Points @DanVanAtta, I'll try to come up with a good way, once I have some time left. My next step will probably be to implement a 'controls' class which in theory enables you to change the buttons you are using to do different things. I won't implement this functionality of being able to change those into swing, but I will remove the hardcoded values from the swing code
Came up with this: https://github.com/triplea-game/triplea/compare/master...RoiEXLab:controlsPrototype What do you think? Are there any potential problems?
^ |
---|
@ssoloff @DanVanAtta
@RoiEXLab I think I understand what that code is attempting to abstract. Please confirm or correct me...
Controls
enumerates different types of view actions.ControlElement
represents an abstraction around an object the user can manipulate to trigger a view action.ControlStore
looks up an object (ControlElement
) that has been manipulated and maps it to the action (Controls
) to be performed.GameScreen
is an abstraction around the logic that actually performs the requested action.Am I close? :smiley:
From just a code perspective, whenever I see an abstraction (ControlElement
) dispatching on an enum (ControlType
) or some other kind of type code, I think it may be a bad smell. (In this case, I'm assuming there is dispatching based on type
going on in the isActive()
method.) Whenever I find myself doing this, I take a step back and ask if I really should have a hierarchy of types that override isActive()
differently and remove the type code completely. That may not be what's going on in ControlElement
; please ignore this comment if I misunderstood its purpose.
Also, in general, would it be preferable to make as many types immutable as possible? For example, does ControlElement
need to be mutable?
I'm not sure if ControlElement
needs to be mutable, probably not.
The purpose of ControlElement
is to wrap a key press, a mouse button or a scrolling action into a unified object.
This way we can allow users to for example place units with their mouse wheel if they wish.
Keys and buttons on a mouse are handled differently.
The ControlType
enum is not needed for that.
It's main purpose is to allow us to render 'button4' and 'VK_ALT' different, indicating one of those is a button and the other is a key.
This probably needs to be changed when moving to JavaFX, since it no longer uses ints but enums for each action instead.
@RoiEXLab Ok, that makes sense.
Then the only other thing I can think of is there possibly a better name for ControlElement
? Maybe there's a meaning associated with "element" in this context that I'm not familiar with, but it confused me when I first reviewed the code.
I used the term "trigger" in my previous comment, but I think the word I was really looking for was "gesture". .NET seems to use this terminology in the way they model input. For example, they have KeyGesture
and MouseGesture
classes. If you look at that link, you can see that *Binding
is used to associate a *Gesture
with a command (action). Those names seem a bit more intention revealing.
So, using this terminology, ControlElement
is a gesture; ControlStore
is a collection of bindings; and the commands are distributed between GameScreen
and the switch/if/else/whatever in ControlStore#handleInput()
. Does that sound right?
Yes. GameScreen is an interface which is supposed to be implemented by the actual UI class (Jframe, jpanel etc.). It makes the UI more or less independent from the backend code.
Closing for the moment, seems like this topic is at rest. I would recommend a new issue to address any additional topics.
Fixes #1260 and #1422 Relates to #611
Backstory
We had this discussion for a while now. I believe we all agree that TripleA UI-Code is pretty messy right now and difficult to work with... I wanted an UI-upgrade for a while now, but my first attempt (#1235) was a never ending compile error hell. For me there was only 1 possible way to change the TripleA UI-Code moving away from Swing. (Terrible Framework to be honest, depends too much on AWT which is even worse.) I had 2 options: LWJGL, which is basically OpenGL for java and JavaFX. Although I like the idea of controlling the rendering code in every detail, I experienced some issues with LWJGL. Those were:
Basically most of the problems are caused by the differences of legacy C code and Java. (Object orientation FTW!) Believe me, using static methods all the time and passing your "instance" as a parameter is a pain!
That's why there was only JavaFX left
Plans
My last attempt was a complete failure. Took way too much time and wasn't practical. Instead of "upgrading" the code, I'm now going to rewrite all of the TripleA UI. This will be a huge project. I planned this rewrite in 3 steps:
Of course step 3 will be the most difficult one.
Benefits
Cleaner and more modular Code overall LANGUAGE SUPPORT - Yes you read right. JavaFX has a built in way to load strings for different locales. Easier UI-Editing Nicer look ^^
Logic Changes
I'm planning to implement a one-screen UI. This means the only popup window will be the error console. Controls-Settings: I want to enable users to change their controls. Perhaps some people want to navigate using IJKL? \:P Of course this will be one of the last things. Map Selection: Map Selection will be done when starting a new game. You press play, choose wether you want to play Local, PBF/PBEM or host a networked game and then you select a map. Downloads will happen in the background, even if the download scene isn't opened. UI is created using FXML documents, language files (basically .properties files e.g.
key=value
) and CSS (special javafx css, not the w3c standards but very similar). This makes it easy to edit using external software like SceneBuilder or similar.Progress
While writing this, I barely started phase 1. This will take a while, But I'll give you a sneak peak of what I achieved so far. The Settings scene: Main Screen with exit overlay: Game Selection Screen:
As you may have noticed, the design in terms of colors is inspired by the look of the triplea-website.
Of course I want to hear your feedback on this. I know this is far from being final, but If I work on this for the next half year or so and you then dislike it, I wasted my free time. That's why I'm opening this issue now!
@FrostionAAA .@prastle told me you were the "graphics guy". When finishing Phase 1 I may need some Icons for the game-selection buttons (Image 3) ^^