Open GrimPixel opened 1 year ago
I could see this being done as an extension of the snap system.
It is also noticeable that after playing a game, pieces or tiles may be everywhere and it requires some mouse clicks to clean up the table. So it would be better to also have the ability to detect and use existing objects on the table, instead of spawning a new set.
That's a good idea - it would provide a good way to reset a game that doesn't leave any clutter.
I'd like to add that there could be vertical positions, so mahjong tiles can be arranged the same as in real life and Mahjong Solitaire can be played.
About the question of how to define positions of objects, there is one thing to be noticed: the sizes of an object differ from one asset set to another (e.g. mahjong tiles in related games by GNOME and KDE). If positions of objects are defined by coordinates, then after a change of asset set, the “Vector3” values are changed, and the objects may collide with each other and fly out of their original positions like an explosion. As a result, relative positions may be considered: define the x, y, z distances of an object to the centre of the table, with the ability of reading “Vector3” values of an object and setting the distance correspondingly. For example, a 4x3 Shisen-Shō game can be defined like
(-3x/2, y/2, z), (-x/2, y/2, z), (x/2, y/2, z), (3x/2, y/2, z),
(-3x/2, y/2, 0), (-x/2, y/2, 0), (x/2, y/2, 0), (3x/2, y/2, 0),
(-3x/2, y/2, -z), (-x/2, y/2, -z), (x/2, y/2, -z), (3x/2, y/2, -z),
I'd like to add that there could be vertical positions, so mahjong tiles can be arranged the same as in real life and Mahjong Solitaire can be played.
I was thinking about this when it comes to, for example, Knights in a Chess game. The knights need to be able to be facing either forwards or backwards. So it stands to reason that they could also be pointing "up" or "down" so that Mahjong pieces can be oriented in the intended way. Maybe this can be done in-game by having the piece snap to the nearest axis when it is put on the board? But this would not account for the "setup" that this issue describes, the starting orientation would have to be in the config.cfg
file somewhere.
On your point about absolute vs relative positions for the snap points, I can see where you are coming from, but I feel like it might introduce a lot more room for error when it comes to the implementation in order to avoid an issue that I think will very rarely be come across. I imagine that in the vast majority of cases, the pieces that are intended to be put on a specific board will come in the same asset pack as the board itself - and if they are indeed in differing asset packs, then one pack is then in a way "dependent" on the other, and thus it falls to the owner of the "parent" pack to let the other creator know that there has been a change that may be relevant to them.
I guess my main concern is that there may be a number of edge-cases that arise from having a system relative to the sizes of the pieces, given that each of those pieces can potentially be various sizes. For me, it also makes more sense to have co-ordinates relative to the center of the board itself, since most boards are tile-based anyway, a lot of the time the pieces will want to end up in the center of each tile (which is where I imagine the snap point would be defined in the config.cfg
file). Then, the size of the piece that is being snapped to that position can have it's bounding box analyzed to make sure it is centered on that tile, regardless of the size of the piece itself.
Would like to hear your thoughts on this - I may very well be tunnel-visioning on what I imagined the implementation would look like.
That orientation problem was what I neglected. Yes, the orientations of pieces and other objects need to be defined in the board's config.cfg
file, or a new
cfg
file dedicated to that.
In the game of “Quilt”, cards are arranged in varying orientations. So I guess the simplest solution is a Vector6 for an object.
https://commons.wikimedia.org/wiki/File:Carpet_patience_1.jpg
About that relative-position problem, here is the background: there are different sets of images, for example, 43 sets of French-suited playing card images. If they all appear on the menu dropdown list, they will occupy too much room. So I created subdirectories in /cards
, picked one of them as the default one, moved it and itsconfig.cfg
, stack.cfg
files into /cards
, and placed an empty file default
in that subdirectory. If the player wants to use another set of images, he/she can move the default images and the config.cfg
, stack.cfg
files into the subdirectory of the default asset set, and then move another image set and its config.cfg
, stack.cfg
files out.
That means that after such a change, Vector2 values in cards/config.cfg
may be changed as well. This means that cards spawned on the board will have different distances to each other. For mahjong, where tiles have even more significant size differences, as the Chinese tiles are 1.5 times in length of the Japanese tiles, relative distances to the board centre and that bounding box solution are not enough, as tiles need to be densely packed.
If each set of images of cards or tiles needs to have a corresponding board/config.cfg
, that could mean a lot of work when there are many sets of card or tile images of different sizes.
So I guess the simplest solution is a Vector6 for an object.
It would have to be one Vector3
for the position, and one Vector3
for the rotation in degrees, but yeah.
About that relative-position problem, here is the background: there are different sets of images, for example, 43 sets of French-suited playing card images. If they all appear on the menu dropdown list, they will occupy too much room.
Which menu drop-down are you referring to here? What I was imagining for this issue is that there's just one sub-menu added to the context menu for boards, which lists a set of pre-defined starting states for the board as defined in the config.cfg
file (not in separate folders). For example, the Chess board could have starting states for both "Chess" and "Draughts", among other games that use an 8x8 board. The drop-down menu should not be that big unless the creator makes a ton of starting states for the board.
Oh, that dropdown menu was the asset selection menu, where there is only a “TabletopClub” by default. In PySolFC, such an image set is called a “cardset” and can be selected in “Options → Cardset”. That solution doesn't fully fit this situation, where assets are loaded at the initialisation and the restart take some time. Or maybe new image sets can be loaded ingame. I also neglected that considering the case of spawning chess and draughts on the same board. So there are two situations: objects are placed at specific locations on the board; objects are densly packed on the board. The first requires absolute positions on the board; the second requires relative positions to the centre of the board with consideration on object sizes. To play games with gravity, the finaisation like rotating the objects and then locking the board is required. The board in this case is not a mere cuboid, but with a guard at its bottom, and the tiles need to be aligned with the guard. https://www.youtube.com/watch?v=RRwuswkk9GI
Oh, that dropdown menu was the asset selection menu, where there is only a “TabletopClub” by default.
Ah right, I think I understand your query now. However, I think it strays quite a bit from this issue specifically, hence the confusion I was having. If you want to discuss having multiple "card sets" in an asset pack, I would happily do so in another issue.
I also neglected that considering the case of spawning chess and draughts on the same board. So there are two situations: objects are placed at specific locations on the board; objects are densly packed on the board. The first requires absolute positions on the board; the second requires relative positions to the centre of the board with consideration on object sizes.
Considering the fact that in the vast majority of cases, we want the pieces to be centered in the middle of each of the tiles of the board, I think it makes sense to use absolute positions. I'm not quite sure how the pieces would be centered if relative positions were used, and they would potentially change depending on the size of the pieces themselves.
Maybe both could be implemented, but that would be very confusing from a usability standpoint I think.
Another way: use absolute positions only, with collision avoidance that places the tile to the nearest possible position without collision. So it can be defined like (0, 0, 0), (-0.1, 0, 0), (0.1, 0, 0), (-0.2, 0, 0), (0.2, 0, 0)
, which means tiles are bound to be colliding originally and with the collision avoidance, they are aligned next to each other without problem.
I'm confused... I think we've got two totally different ideas in our minds as to how this would work. I'm not sure why the system would need to take the piece's bounding boxes into account when placing them on the board.
Would it be possible for you to describe in detail what you imagine this system would look like, both from the asset creator's perspective (i.e. what data is in the config file), and from the player's perspective in how they interact with the system?
The “collision avoidance” is something imagined: it prevents collisions of objects on defined spawning positions, by means of detecting the nearest possible position that doesn't collide with existing ones for the new object. To define a compact layout, the creator can simply write small distances without worrying about collisions.
I found that collision avoidance solution not ideal: it is impossible to create layouts where gaps exist or half a tile shifted, when the size of tiles undetermined is: https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Online_Solitaire_Mahjong_Spiel_von_ratehase.de.png/620px-Online_Solitaire_Mahjong_Spiel_von_ratehase.de.png
The solution for the corresponding positions.cfg
file may be like
[Chess]
positions = {
{black rook, black knight, black bishop, black queen, black king, black bishop, black knight, black rook},
{black pawn, black pawn, black pawn, black pawn, black pawn, black pawn, black pawn},
{, , , , , , },
{, , , , , , },
{, , , , , , },
{, , , , , , },
{white pawn, white pawn, white pawn, white pawn, white pawn, white pawn, white pawn},
{white rook, white knight, white bishop, white queen, white king, white bishop, white knight, white rook},
}
In the corresponding config.cfg
file for the board without any border like https://upload.wikimedia.org/wikipedia/commons/5/5b/Chessboard480.png:
[Board.png]
yaw_angle = 0
grid_shape = square
grid_endpoints = {
(1/16, 1/16), (15/16, 15/16)
}
Defining endpoints is like drawing a rectangle with mouse. Grids are generated by dividing the space evenly for “square” ones. For a different board like https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Brett_Schach_Schwarz-Wei%C3%9F.png/477px-Brett_Schach_Schwarz-Wei%C3%9F.png, where there are borders, the grid_endpoints
values will be different.
Other grid shapes like that for “Chinese chequers” https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Chinese_checkers_start.svg/431px-Chinese_checkers_start.svg.png can be defined in grid_shapes.cfg
like
[Standard]
points = {
(12/24, 0/16),
(11/24, 1/16), (13/24, 1/16),
(10/24, 2/16), (12/24, 2/16), (14/24, 2/16),
...
}
endpoints = {
(0/24, 4/16), (24/24, 12/16)
}
Hmm... I'm not sure about having all of the data in separate files, but having a "shortcut" for defining grids instead of listing each co-ordinate would be very helpful for a lot of boards. And there would still be a way to define points for non-grid boards as well like the one you mentioned.
If they are integrated into fewer files, I think each cfg
file needs to be brief.
To make it clear, I prefer to use the word “mesh” instead of “grid” now, to describe the shape of the collection of all available positions on a board.
There is no stacks.cfg
for a board game, but could be a layouts.cfg
, where two things are defined:
In layout.cfg
[Chess]
endpoints = {(0, 0), (1, 1)}
positions = {
(0/7, 0/7), (1/7, 0/7), (2/7, 0/7), ...
}
spawn_points = {
'standard chess' = {
'black rook' = {(0/7, 0/7), (7/7, 0/7)},
...
}
}
There could also be connections
to connect positions with connection_type
, making the “mesh” real meshes. This will be useful for AI models, I think. The mesh can also be visualised on the board.
In config.cfg
[chess board.webp]
mesh = Chess
mesh_endpoints = {(1/16, 1/16), (15/16, 15/16)}
Is your feature request related to a problem? Please describe. Currently, a game requires a tc file, which is not easy to set up.
Describe the solution you'd like Pieces can be spawned on boards at predefined positions through the right-click menu of a board. Positions can be defined like the snaps mentioned in https://github.com/drwhut/tabletop-club/issues/180. A board may have different predefined setups, e.g. different draughts, chess, reversi on the same 8x8 board. It could also be defined vertically, so games like Mahjong Solitaire can be played as well.
In addition, there could be an option of randomness, for the board to spawn games like Klondike, FreeCell, different Mahjong, etc.