boardgameio / boardgame.io

State Management and Multiplayer Networking for Turn-Based Games
https://boardgame.io
MIT License
10.02k stars 708 forks source link

UI toolkit #48

Closed nicolodavis closed 6 years ago

nicolodavis commented 6 years ago

Just tracking some ideas planned for the UI toolkit in https://github.com/google/boardgame.io/projects/5

PR's are welcome for items not yet claimed. I'll try to keep the items bite sized (implementable in an hour or less), but some may be larger, and will get broken down once they start getting worked on:

All components must be have usage examples in the storybook/ directory.

vdfdev commented 6 years ago

Hey @nicolodavis, I started working on chess pieces and board (which might be used by other games like checkers). Would this be welcomed too?

vdfdev commented 6 years ago

I started this because I am porting the code I already had done for turnato to this framework.

vdfdev commented 6 years ago

I am also thinking about adding chess as an example... It is a classic game and can illustrate some features like AI

nicolodavis commented 6 years ago

Hey @Felizardo. Sounds good! Will add it to the list. Let's have just one generic token component (with options to style via props), though.

You can use unicode symbols for chess pieces on this generic token: https://en.wikipedia.org/wiki/Chess_symbols_in_Unicode

vdfdev commented 6 years ago

Ok! I will send a PR soon

jchristman commented 6 years ago

Philosophically, after we get a decent UI toolkit, we will probably want to split out into separate repos/npm modules? Like boardgame.io/ui-base, boardgame.io/ui-chess, and so on. Once this kit becomes full featured I think it would make sense to not include chess pieces in a checkers game, right? Not saying we should do this now, but possibly down the line...

nicolodavis commented 6 years ago

I think so too. I think we should only include generic components that are applicable to a wide variety of games in our distribution:

Token
Placeholder
Card
Deck
Grid
HexGrid
...

These can stay in this repository, but be distributed as boardgame.io/ui (just like we split the NPM already at the moment).

Chess is a good way to bootstrap some examples, so I'm not opposed to getting chess pieces in. However, if there is an easier way to implement chess without adding more components (just use unicode symbols perhaps?), I'd be a fan of that! Alternatively, we could move the chess piece SVG foo into the examples directory and make it clear that it's not intended to be distributed via NPM.

/* Unicode Chess */

<Token>♔</Token>
jchristman commented 6 years ago

I’m thinking of a hierarchy of UI components that looks like this:

This allows for a bit more flexibility for games that might have multiple game boards and such. The generic Token and GameBoard components can have draggable and non-draggable versions based on which the dev wants to use. Does that sound good? We could even at some point add a GameLobby implementation that provides stubs for matchmaking (listing public matches, allowing private matches with game ID, etc).

vdfdev commented 6 years ago

I think we can start by creating a single type of Token, and add more as we develop more features.

WRT not include chess in the common components, this is fine by me, I can include on the examples folder for now, and add rename it to "Examples - Chess" on the storybook until we have a functional example.

On Dec 30, 2017 10:07 AM, "Joshua Christman" notifications@github.com wrote:

I’m thinking of a hierarchy of UI components that looks like this:

This allows for a bit more flexibility for games that might have multiple game boards and such. The generic Token and GameBoard components can have draggable and non-draggable versions based on which the dev wants to use. Does that sound good? We could even at some point add a GameLobby implementation that provides stubs for matchmaking (listing public matches, allowing private matches with game ID, etc).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/boardgame.io/issues/48#issuecomment-354542826, or mute the thread https://github.com/notifications/unsubscribe-auth/AA_Jh0Z0ZK_8jtScEXlaVASYSBszRnMkks5tFieZgaJpZM4RNLEu .

nicolodavis commented 6 years ago

General plan sounds good. I don't think we need a GameTable, though. The returned React component from Client already functions as one. The user can add as many Grids, Tokens or TokenReceptors to that without being restricted to a particular hierarchy.

Yeah, let's start with Token and build up from there. This is shaping up pretty nicely!

nicolodavis commented 6 years ago

Adding @lionng429 to this thread, who wants to work on HexGrid. Just summarizing the discussion so far so that everyone is on the same page (let me know if I've captured something incorrectly and I'll edit this post):

The plan is to have the following generic components to start with:

Token

TokenReceptor

Grid

/* x=1 and y=2 refer to co-ordinates on the Grid, not SVG co-ordinates. The
   implementation may map them to SVG co-ordinates internally. */

<Grid rows={8} cols={8}>
   <Token x={1} y={2}></Token>
</Grid>

HexGrid

/* x=0, y=0, z=0 is the hex at the very center of an infinite hex grid */

<HexGrid>
   <Token x={0} y={0} z={0}></Token>
</HexGrid>

The plan is to implement Grid and HexGrid using SVG (although this is not exposed to the external interface).

@Felizardo is going to start us off with a Token and a simple Grid (with no drag-n-drop). @jchristman is planning to add drag-n-drop support (probably involves implementing TokenReceptor). @lionng429 is planning to work on HexGrid.

Let me know if you guys want a separate room on Gitter to chat internally if that is helpful for co-ordination of this effort.

arakholia commented 6 years ago

One concern I have with implementing Grid and HexGrid with SVG in conjunction with #56 is that I believe the HTML5 Drag and Drop API doesn't work with SVG elements? (See https://stackoverflow.com/questions/5864249/html5-drag-and-drop-on-svg-element). Potential solutions then are to manually implement drag and drop functionality, or if we do want to use HTML5 drag and drop, encapsulate tokens in SVGs and position them in grids as divs with absolute positioning?

nicolodavis commented 6 years ago

There are libraries like react-dragtastic that might help with this. Implementing Grid using a div might work out well, but I'm not sure about HexGrid.

I'll let @Felizardo and @jchristman comment more because they're working on this directly.

Either way, I think we should design this in such a way that we can change the internal implementation (from SVG to divs or vice-versa) at any point without changing the external interface or affecting behavior.

vdfdev commented 6 years ago

The main advantage of using SVG IMHO is that you get for free a bunch of stuff, mainly the ability to draw complex figures and have DOM events attached to it (imagine onClick or mouse over on a country in a map), it works pretty well cross device, the fact that it is easy to zoom by changing the viewport and being very easy to create react components for it.

But yes, I guess there is no perfect solution and we have to decide which trade-off to choose.

On Sun, Dec 31, 2017, 10:33 PM Nicolo John Davis notifications@github.com wrote:

There are libraries like https://www.npmjs.com/package/react-dragtastic that might help with this. Implementing Grid using a div might work out well, but I'm not sure about HexGrid.

I'll let @Felizardo https://github.com/felizardo and @jchristman https://github.com/jchristman comment more because they're working on this directly.

Either way, I think we should design this in such a way that we can change the internal implementation (from SVG to divs or vice-versa) at any point without changing the external interface or affecting behavior.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/boardgame.io/issues/48#issuecomment-354630341, or mute the thread https://github.com/notifications/unsubscribe-auth/AA_JhzJvBpowWyN7HlSftaea9nSgVw7Qks5tGCfVgaJpZM4RNLEu .

vdfdev commented 6 years ago

*ability to draw complex shapes, sorry.

On Mon, Jan 1, 2018, 1:47 AM Vinícius Felizardo felizardow@gmail.com wrote:

The main advantage of using SVG IMHO is that you get for free a bunch of stuff, mainly the ability to draw complex figures and have DOM events attached to it (imagine onClick or mouse over on a country in a map), it works pretty well cross device, the fact that it is easy to zoom by changing the viewport and being very easy to create react components for it.

But yes, I guess there is no perfect solution and we have to decide which trade-off to choose.

On Sun, Dec 31, 2017, 10:33 PM Nicolo John Davis notifications@github.com wrote:

There are libraries like https://www.npmjs.com/package/react-dragtastic that might help with this. Implementing Grid using a div might work out well, but I'm not sure about HexGrid.

I'll let @Felizardo https://github.com/felizardo and @jchristman https://github.com/jchristman comment more because they're working on this directly.

Either way, I think we should design this in such a way that we can change the internal implementation (from SVG to divs or vice-versa) at any point without changing the external interface or affecting behavior.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/boardgame.io/issues/48#issuecomment-354630341, or mute the thread https://github.com/notifications/unsubscribe-auth/AA_JhzJvBpowWyN7HlSftaea9nSgVw7Qks5tGCfVgaJpZM4RNLEu .

nicolodavis commented 6 years ago

Another idea that I think will be quite helpful for prototyping:

An automated rendering component that can interpret G.

The state in G will typically mirror real objects that are rendered (a card, some tokens on the board etc.). We can probably provide a development-mode component that attempts to smartly interpret objects in G and render them.

Here's how it will work:

For example:

{
   hand: [ { type: 'Card', text: '...', header: '...' }, ...]
}

It doesn't have to be perfect (and should be opt-in with a boolean setting). It just provides someone that has coded a bunch of moves with something to play around with. Right now we have a JSON renderer that spits out the entire object as a tree, but we can probably do better!

nicolodavis commented 6 years ago

@lionng429 I'll have more time to work on the UI toolkit in the coming weeks, so if you haven't started work on the hex grid, I'll take over the work if that's ok with you.

lionng429 commented 6 years ago

@nicolodavis Please feel free to take over. I started just a bit, so if you need as reference to kick start, you may take a look at https://github.com/lionng429/boardgame.io/tree/ui-grid-system/src/client/lib

nicolodavis commented 6 years ago

Oh, didn't realize you'd already started. If you have, and would like to continue working on it, that's fine too! Alternatively, I could create a hex-grid branch here and we can both work on it. Let me know what you prefer.

I'm using https://www.redblobgames.com/grids/hexagons/ as a reference. There are lots of features we could add to a hex grid system.

lionng429 commented 6 years ago

@nicolodavis don't worry about it, and please feel free to speed it up as I might not have too much time before next Saturday.

Btw, I actually refer to the same website and I chose Cube coordinates, so if you are interested, my codes from the link above may help :)

nicolodavis commented 6 years ago

@lionng429 I'm committing in the hexgrid branch in case you're curious. Your code was a helpful reference!

EDIT: merged into master

chrisheninger commented 6 years ago

I'd love to help out with any other remaining UI pieces if it's needed. Let me know!

nicolodavis commented 6 years ago

Great to have your help, Chris!

Our general plan for the UI toolkit is noted above: link

@jchristman is working on the drag-n-drop. Apart from that, I think we could definitely use some help in expanding Grid and Token. Some features we might want to add:

Stefan-Hanke commented 6 years ago

@nicolodavis Regarding that automatic rendering: I've not found any code for that - well maybe a thin bit here. I think this would be a good step towards facilitating writing prototypes. What code exactly were you refering to?

I find that issues like this one make it hard to keep track of things. It looks a bit messy. How about splitting sub-topics into own issues and reference them to a coordination issue?

nicolodavis commented 6 years ago

Hey Stefan. The automatic rendering idea hasn't been implemented yet.

I agree, some ideas can get lost in long threads like this. Maybe going forward, I'll keep the first post in an issue edited and up to date with what we have planned.

I also want to create a Roadmap issue with features that I'd like to see before we're ready for a v1 release.

Stefan-Hanke commented 6 years ago

I've thought about the automatic rendering idea. I think it would be best to have some non-trivial board games before starting it to get a grip for what it could look like, what information already is provided, and what's still needed. Somehow, the UI would need to know what moves are currently possible, and what data they need. I've done some research into this and it all points to very formish looking UIs.

Actually, the "what moves are possible" part is not only important for prototyping, but also the game itself. Somehow, the game needs to provide that information to the UI. AFAIR the chess example has bits of this. I do like the idea to abstract over the UI like in MVVM.

In the meantime, I've tinkered with Blender and got a 3D Meeple rendered to SVG. The color is randomly chosen by the plugin. It also has problems with partially-occluded surfaces, which become visible at larger angles and make it look somewhat artistic. meeple2

Some more useful tokens include houses (think Thurn&Taxis or the stables in Agricola)

vdfdev commented 6 years ago

@Stefan-Hanke "what moves are possible" is very important for AI too. Indeed, I started working yesterday on the AI piece (as described here) and I am working right now on making it available to provide this information to the game engine (what are the possible next moves). However, I was envisioning this to be optional.

Anyway, my implementation will make this list of possible moves, if provided, to be available to the UI too.

Stefan-Hanke commented 6 years ago

@Felizardo I think a human player will want to know what he can do given the situation at hand. For me, this is not optional. Well, let's see whether the structure defined for the bots matches the expectations of someone implementing an UI.

nicolodavis commented 6 years ago

@Stefan-Hanke If you'd like to check in the 3D meeple, feel free to send me a PR. It looks great!

nicolodavis commented 6 years ago

About available moves, I think it will be quite difficult to provide a standard interface for the sake of the UI. I'm ok if we have separate paths for AI and UI.

For example, a card game might just interpret all cards in a hand object as playable. Or, the user might associate a boolean with each card object. Adding an extra availableMoves object for the sake of the UI is additional burden that's not required.

Having a single path for both is ideal, of course, and I'll be glad if that indeed happens. Let's see how the AI interface turns out, and let's also learn from a few game implementations to see what makes sense.

alex2wong commented 6 years ago

Hi all, I suppose we can add some more features in HexGrid, such as perspective, game background, and getNearNeighbors(n: number, obstacle: bool) things..

below is what I am doing (just in design, the Sprites is in bg image, Perspective View is easy to implement)... I think it would be great if we provide comprehensive UI and functions for building this kind of Strategy Battle Game.. What do you think about ? @nicolodavis @Felizardo

hexgame_design

nicolodavis commented 6 years ago

Sounds good to me! Feel free to send me a PR.

nicolodavis commented 6 years ago

Also, is anyone implementing drag-and-drop for Token?

jchristman commented 6 years ago

I was gonna to but life took over, so I currently don’t have time. If you’re trying to decouple from react (which I think i saw some posts saying you might want to), then maybe react-dnd isn’t the right choice? There is a plug-in for react-dnd that adds a SVG backend, Id have to find it again... what are your thoughts on best tech for it? Own implementation or use the widely used solution?

nicolodavis commented 6 years ago

We already have two client implementations:

People are adding support for React Native (and maybe Vue / Angular, depending on interest).

The UI components (Token, grids etc.) will need a separate implementation in each library that we support. I think it's ok to use react-dnd for the React components. I don't imagine that React and Vue will share drag-n-drop code.

nicolodavis commented 6 years ago

I'm going to spend some time on UI this weekend. I think I have a satisfactory solution for drag-and-drop that works for both divs and SVG.

shirakaba commented 6 years ago

A heads-up for when we come to implementing drag-and-drop for React Native UI components: From React Native 55, the Animated.Tracking module supports usage of the native drivers for a JS-thread-independent silky-smooth experience.

Expo should be releasing their v27.0.0 SDK sometime this month (which will add support for said version of React Native).

nicolodavis commented 6 years ago

Closing this in favor of #282