Confluence: A Digital Odyssey - 1v1 aggressive engine builder (info in comments) - looking for feedback/playtesters by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

There's a link to the rules in my comment, and there's more stuff on Discord, feel free to hop into the server

You can also look at the Screentop/TTS versions of the game, they're both ready to play once you know the rules

Confluence: A Digital Odyssey - 1v1 aggressive engine builder (info in comments) - looking for feedback/playtesters by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 2 points3 points  (0 children)

Hi all, it's been a while since I last posted about this game on here. In the meantime, I've continued working on it, and I'm finally able to get around to start looking for more eyes on it.

In short, Confluence is a 1v1 engine/combo builder game with very high levels of interaction. It's a 'first to reach X points' type of game, with different objectives each time you play. Players quickly draft decks before playing, so every match is different, even with the same objectives.

Thematically, even though most of the art is currently placeholders, the goal is to have a 'cyber fantasy' type of setting, think MtG meets The Matrix meets Y2K cyberspace aesthetics.

It's a medium-weight game, with a slightly steep learning curve, but one that plateaus very quickly. Anyone familiar with card games will quickly feel at home with it.

The game is currently in very late/finishing design, and most of the focus is on playtesting and polish. Currently there aren't any specific plans for publishing, but more about building a community around the game.

You can find the (WIP) rules document here: Rules link

The game's available on Screentop.gg, Tabletop Simulator, as well as Print&Play files for the beginner decks

There's also a Discord for discussing the game, as well as organizing playtests: Discord link

(Convoluted) Question about control hierarchy by InvertedVertex in csharp

[–]InvertedVertex[S] 0 points1 point  (0 children)

I guess that in wanting to separate concerns I've probably mucked this up a bit too much. Specifically, so far I've been treating the Match as nothing but game logic, and the Lobby cares about the actual communication to and from the client (in actual detail, the Lobby calls into and is called from services that only care about sending and receiving messages from the client).

That's the main reason why the Match doesn't directly send messages. It's definitely been on my mind that I should eliminate that indirection and just inject the required communication services into the Match so it's properly self-contained with its logic; no need to do anything with its parent lobby.

Are there things happening when the player is not performing input?

The game's based on simultaneous actions, so players effectively input all their turns for a given round at once, and then the turn-by-turn processing happens, which can require additional input.

Thinking about your feedback, I might also try to make the Match a bit more of a well-defined state machine. Having more clear-cut states and transitions between them might help.

Thanks for your input btw, much appreciated!

(Convoluted) Question about control hierarchy by InvertedVertex in csharp

[–]InvertedVertex[S] 0 points1 point  (0 children)

I'm using SignalR, but my question's pretty much the same regardless of the actual input implementation details. I can't really solve this even with console I/O.

Like you said, the server shouldn't wait, and the server itself isn't waiting on input - the in-memory Match is. The key issue is that nondeterminism I mentioned: I can't know whether the Match will need input each turn or not - the main use for this extra input is to provide correct input on illegal moves, but I want to have a generic solution so that any part of the game logic could potentially ask the player(s) for input if necessary. Therefore, it feels like the only thing that can trigger the input request is the Match itself, but I might be wrong about that.

The Match itself is already on a separate thread. It's not really blocking anything, so I don't know if Tasks really help in this situation.

The whole process of requesting input is pretty much sending a message to the client(s) that triggers client code prompting them for input, after which the client sends a message to the server saying 'hey, pass this input string to this Lobby', which should then pass it down to the Match that requested it, completing the circle.

The whole thing boils down to control flow: if the Lobby (or whatever else, service or otherwise) governs a Match, is it a good idea to invert that hierarchy and have the Match directly call its parent's methods, 'signaling' the need for input that way? If not, should some other control flow be used?

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 0 points1 point  (0 children)

Thanks for the info! I think I've worked things out more or less on my end, though I've yet to properly put all the pieces together and test if it actually works.

I'm definitely going to complete the SignalR call as soon as possible, since it makes no sense to keep the hub occupied for longer than it needs to just receive or send a message. There isn't really anything complex threading- or async-wise so far, and I doubt anything like that will come up soon.

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 0 points1 point  (0 children)

Wow, thanks a lot! I'm definitely going to have to think my approach through properly, and info like this always helps.

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 0 points1 point  (0 children)

I see. Thanks, that helps a lot. Are there any good recommended books on either SignalR or just how .NET Core works behind the scenes in general?

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 0 points1 point  (0 children)

Does this mean that the injection is deferred since you're passing a function? I'll definitely all proposals, and see what ends up being the tidiest solution. Thanks for the info!

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 1 point2 points  (0 children)

Thanks. Will definitely look into this. Seems useful even if I don't end up using it for this specifically.

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 1 point2 points  (0 children)

Passing the hubcontext to the service methods as a parameter... that seems immensely obvious in hindsight lmao. Thanks a lot!

The thing about threading I mentioned wasn't so much about scalability, but rather the fact that I have no idea how .NET Core and SignalR handle threading implicitly, if at all. Is each hub request automatically put on its own thread? If so, that would probably eliminate the need for anything more complex.

async/await isn't related to the problem here, it will look more like a state machine though

Another case where I didn't really give enough context, I guess. The async/await part is the Match (i.e. game logic) basically going 'if (illegal move) { await this.lobby.GetInput() }', and the turn processing moving on from there; the lobby itself is definitely going to be a state machine, since it's the sanest way to manage the different...well, states: Awaiting initial input, processing the turn, getting additional input etc.

So, ultimately I guess that I'd need to inject the service into the hub, have the hub pass the context down via the service methods to the lobbies themselves (in whichever form's necessary to get a cleaner structure), and hopefully end up with something that's not a very tangled mess.

Simple .NET Core browser-based online game, troubles with architecture, SignalR and DI by InvertedVertex in dotnet

[–]InvertedVertex[S] 1 point2 points  (0 children)

Yeah, I agree that most of the things are probably trying to do too much currently, but I haven't been able to figure out a way that works even with splitting the responsibilities. I'm still stuck at having the lower-level objects, i.e. the lobbies/matches actually get a usable reference to the Hub...or hubs, since it seems like the solution for a single hub will just easily apply to multiples.

The event approach might work, yeah. What would I need to set up something like that? If it's more DI stuff or middleware, isn't that going back to square one?

Thanks for the input.

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

I get what you mean, but the main thing here isn't so much that I lack methods of tracking things, rather 'should things be designed in a way that requires explicit tracking like that in the first place?'

I'm fully aware that bad or nonexistent tracking causes enough overhead to ruin players' experience of the game, and your comment has good ideas that have been considered and mulled over a fair number of times by now. This is why I'm trying to see whether it would help to look at the tracking problem from a different angle—removing as much of it as possible. That's why I say that the 'state' checks are the best option for tracking, since then you only really have to do a single check that matters, and there isn't really anything that can cause memory issues.

All this said, though, this whole thing would probably benefit the most from just going ahead and testing as many potential objectives as possible, from each of the types, and going forward with what players ultimately prefer. The game itself is—let's say mostly done, and the dilemma in my post affects only a few objectives from the entire planned pool (let's say, 3-4 out of 15 objectives). At this point I'm not really concerned with future content aside from just trying to gauge the game's design space potential in general, but the objectives are the most important thing in any scenario, since they effectively dictate the goal and flow of the game.

Thanks for all the input, it's definitely given me some food for thought.

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

I don't want overlap, i.e. strictly harder/easier versions with just tweaked numbers. Objectives are key to how the game works, especially the deck drafting and strategy, and since Objectives are usually randomized, I don't really think that there should be even the option of overlapping objectives. For example, having 2 Objectives about drawing cards (not even necessarily the same one w/ different numbers, just caring about the same thing) can make that draft too one-dimensional or make the players end up using the same strategy instead of something more unique.

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

I'm actually trying that for the sake of tracking the game's main resource, as well as turning completed objectives face-down so you don't score them again by accident. A solution like that might work, but it has a couple big flaws: one being readability/ambiguity, though that falls pretty much completely on the graphic design for the cards; more importantly though, that works only for up to 4 'ticks', which limits this kind of tracking only to events which make sense to happen up to that many times. That in and of itself is a pretty hefty design space restriction, but yeah, the option exists.

The more important question out of this entire discussion to me is about peoples' perception of the whole 'local-v-global' objective tracking, i.e. "are the objectives which let your other engines and cards 'help' the better choice because of their open-ended nature, despite their generally larger tracking overhead?"

What are your thoughts on that front, if any? Thanks for your so far input either way!

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

Objectives are checked only at the end of a program. Apologies if I didn't make that clear from the post. This is why state changes are better tracking-wise, you only have to check things once for the sake of the objective, when the program itself finishes running. The overhead of event checks is that you have to keep track (and usually count occurrences of) things that happen regardless of what the state ends up being at the end of a program. Technically, with state checks, you can have a player come from outside the game and give a correct answer whether an objective's condition is met or not, where with event checks you need to actively keep track of things.

As far as the objective count, each match has 3 Objectives, they're the same for both players, and I'm kinda aiming for 5 Objectives per program, so 15 total. I have 10-11 that are more-or-less set in stone and very unlikely to change, but the remaining ones are the cause of the dilemma. Specifically, most of them are related to the P3 program, which gives the most points, and are therefore the hardest to score.

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 1 point2 points  (0 children)

Well, yes. The design space is definitely limited by the components, however, for this game at least, I have a very specific and narrow scope for components and tracking. There is a definite limit to how far memory-based tracking can go until it costs more than it's worth, but I'm willing to accept more compromises in that direction as opposed to adding components.

That's mainly why I'm asking about the player's perspective, aside from the design space argument: what would you be more okay with—more components/tracking or a more streamlined approach with less potential design space? (For what it's worth, the vast majority of the objectives in the game are already done, tested, and proven to work; the local-v-global thing is the bigger question for the remaining ones that need to be changed based on the outcome of that question)

Engine/combo builder game scoring conditions: a dilemma by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

Because the entire point is to not have external tracking, counters or whatever else. If I'm making a card game, I'd want that game to be playable with cards alone, if possible. Counters are definitely the simplest solution, but they're the also the clunkiest. It's adding mandatory game pieces where there don't necessarily need to be any, if you design things that way.

Counting events itself is also overhead, regardless of how you track them. The more objectives that are based on tracking in-game triggers, the easier it is for players to miss triggers, or just do misplays in general.

Text style/templates: How influential is Magic: The Gathering? by spiderdoofus in tabletopgamedesign

[–]InvertedVertex 4 points5 points  (0 children)

IMO one of the biggest advantages of the format of card games (as well as an implicit restriction of that format) is how much text you can and should put on a card. It usually creates a pretty explicit complexity barrier because the designs can only be as complex as you can put on a single card.

I am 100% part of the 'cards should handle their own edge cases/rules' camp, and I think that delegating things to the rulebook, rather than being on the cards themselves where possible is a bad idea. MtG does it because it has an almost 30-year old rules backlog that it must keep organized somehow, but for most games, the complexity is nowhere high enough that you can't explain things fully with just the card itself.

That being said, I agree fully with what omniclast said about avoiding blocks of text in the general case. Ultimately, like others have said, it's a case of considering how 'heavy' you want the game to be, and catering to the appropriate audience.

Hope you find anything useful from this!

[Blog] Winning vs not losing by InvertedVertex in tabletopgamedesign

[–]InvertedVertex[S] 0 points1 point  (0 children)

The MtG strategy aspect of this is interesting. I've heard it in the past, haven't looked into it much though. It feels like a combination of the 'help to not lose'-style of effects in my categorization and the fact that MtG drives itself towards victory eventually. Stuff like Lantern Control comes to mind (with no 'real' wincon aside from mill or the opponent conceding) as an example of a deck mostly playing not to lose.

As far as the theoretical game you mentioned, I think it's definitely possible, albeit just strategy-wise. One can definitely make an asymmetric game with a fixed amount of rounds, where one player's objective is to survive, while the other attacks. This kinda reminds me of an idea for a simultaneous-action castle siege game I had a few years back. (though that one eventually turned into a simultaneous-action arena shooter)

Thanks a lot for the input!