4 ms·
I'd love to know the 'design patterns' of works like this Knights of San Francisco game. Did the author use a workflow engine, a rules engine, functional event
by Multicomp 5y ago
I'd love to know the 'design patterns' of works like this Knights of San Francisco game. Did the author use a workflow engine, a rules engine, functional event sourcing, a nested pyramid of if-then-else doom?
I have a sense that this space is somewhat unexplored. Text-based game world simulation is a relatively underdocumented (to my eyes) form of the 'game UI overtop a database manipulated with game logic rules' type of games, of which Simulation games are at the complex end of.
There are things like Twine and Inky that offer variables and conditionals to prewritten bodies of text, but doing composable texts worlds that change their state based on the accumulated choices of players over the course of their time seems to be a complex feature to build and extend, whether in Twine or another tool. Dialog simulation systems that remember what options you've done and give you additional options or changes over the course of the game are sold as products online. Heck, someone recently patented a 'grudge' system that a popular game (League of Legends?) used.
Or maybe I've just been looking too closely at it. I've been working slowly for about the past 2 years on an automation system for a tabletop RPG (non D-20 system) to speed up battle generation & resolution, trying to incorporate all of the various rules that say 'in X scenario, if Y conditions are met, gather this information from the user, then apply its Z effect like so, but also let the DM / user change any of the above or ignore the entire thing before you do so', so while I've ordered Designing Data Intensive Applications in hopes of gaining more insights, this problem certainly seems like a big thing to chew on from my self-taught programmer's POV right now.
- filiph 5y agoAuthor here. The game has several levels (explored more in my 2017 "fractal stories article"[1]) - from top to bottom it can be something like > you're in a room > you're talking to this person > you're in this branch of the conversation OR > you're in another location > you're in a fight with these two monsters > monster A is swinging at you with an axe > you've deflected that swing and have an opportunity to counter-attack It's basically a stack of situations. To answer your question, the design patterns differ according to the situation. The roaming between the locations is relatively simple node-navigation (except we need to track from which node we come to each location, for example, and we can skip through visited nodes that haven't changed). The dialogue can be something very similar to ink [2]. The combat is similar to roguelikes, where it's turnbased, but as a player, you only "see" your own moves, and the other moves happen in between. I do track of time on the level of milliseconds, and I have moves that take more or less time, also depending on who makes them (an agile goblin readies a sword much quicker than an old man stands up from the ground). I like your idea of a TRPG helper. I was thinking of something similar. Like, have an app for combat only, where you set up the combatants, and then let the DM simulate effects of different actions done to those combatants. As you say, in TTRPG it's important for the DM to be able to bypass the system, make an exception, etc. But I'd say that 80% of the time, the DM can just report the effect back to the players. And it takes them much less time and mental effort. (Especially if we're talking about one of the more simulationist TRPGs like Blade of the Iron Throne [3].) [1]: https://filiph.medium.com/skyrim-rendered-in-text-1899548ab2c4 https://filiph.medium.com/skyrim-rendered-in-text-1899548ab2... [2]: https://www.inklestudios.com/ink/ https://www.inklestudios.com/ink/ [3]: http://ironthronepub.com/ http://ironthronepub.com/ (Edit: format)
- Multicomp 5y ago> I like your idea of a TRPG helper. I was thinking of something similar. Like, have an app for combat only, where you set up the combatants, and then let the DM simulate effects of different actions done to those combatants. As you say, in TTRPG it's important for the DM to be able to bypass the system, make an exception, etc. But I'd say that 80% of the time, the DM can just report the effect back to the players. And it takes them much less time and mental effort. (Especially if we're talking about one of the more simulationist TRPGs like Blade of the Iron Throne [3].) TL;DR: This is exactly what I'm working on, and exactly for the reason you say (input what the player wants, input the dynamically generated questions about what rules to apply here, then just report what happens), and seeing things like your Knights of SF game app give me hope that it is possible to build something like this after all! The goal is to give the GM time to imagine narrative flair, all within a ~10 second cycle time between player input and game output so the players don't lose interest. If you as the DM have gone through all the rules, gathered further player input (you can crit! Do you?), figured out what happened, and report it to the players only to look up and see them all on their phones because it's been 12 minutes and by the way you forgot some rules that the players bought for their characters but neglected to mention, something has gone wrong. As ignoring rules that affect the battle is not a solution (why would they write them in the book if they didn't matter), a battle sim helper would greatly speed up the process of adjudicating character turns in a battle without slowing the action down to an entire session of just battle dice rolling. Right now battles are the slowest thing that happens in our campaigns because while the battle is a closed finite state machine, it has a combinatorial explosion of state that affects subsequent options, actions, and outcomes, which is all manually tracked in the head or on paper of the GM and/or players. So much for the advertised 'narrative first, fast paced' combat system! The particular game system I am modelling is called Genesys[1] and has a fully developed game logic model [2] (in-game characters have fields which themselves have validation rules and invariants which all effect the core mechanic of assembling a dice pool from the saved state, reading the dice results, applying the outcomes to the saved state, which then affects subsequent character turns etc.). I am currently only modelling what happens in a fight AKA a turn-based battle system. Each battle rule will have simple text, but that then has to be parsed in order to determine where and how to apply it. The example rule below is one of the most simple rules in the game. This is before one enables the user to edit this instance of the rule, or ignore it for this particular occurrence, or delete it from existence entirely, etc. etc. Adversary (rule name) 1 (rule rank) [passive] (activation condition) - when targeted by a combat check (trigger condition), upgrade the difficulty of all incoming combat checks (outcome). So we have a name, a rank (or not!), an activation condition, a trigger condition (or multiple), and an outcome. And in theory we want the user to be able to modify any of these fields at runtime for just this once (because of some narrative reason), or on a permanent basis until further notice. Other rules have an active activation condition, so you need to check if the character would be able to trigger the rule at this time (or has some past transaction precluded it), a composite trigger condition (you are attacked, and you are hit, and the attack skill is melee, and you have not yet moved in this turn), and multiple outcomes, each with their own side effects & conditions (you take damage, the attacker gains a boost dice on their next transaction, but only if they don't already have a boost dice from a previous transaction). Algebraic data types can help wrangle some of the game logic, via tools like aggregates of tagged unions, but while I currently have the skill to reason about modelling and writing the vertical code slices for writing and retrieving the data, my still-evolving understanding of the overall game logic system and my relatively clunky choice of tech stack (UI is Giraffe HTML forms, JSON-RPC for API, sqlite for storage) all combine to mean that I make slow progress actually getting all of the rules modelled, written to and from the DB, evaluated to affect the overall state, and updating the UI or returned API responses. In short, I've bitten off way more than I realized at the beginning and while I've not given up yet, I definitely hope that a read through of Designing Data Intensive Applications will help me fix my data structure choices and/or re-architect my entire system to something more manageable, yet still gives me the ability to enable end users to modify the rules at runtime. Right now, because I don't know what architecture would be best in this scenario, I spend time wondering if I should re-architect to cool sounding things I found on the internet like Discrete Event Simulation, Functional Event Sourcing, Akka.Net actors, Rules Based Engine, Expert Systems, Workflow Engine, or instead try to keep it simple with something like a Finite State Machine and (application code level, database is only a data store) Online Transaction Processing would work, but my inexperience in building this system likely results in suboptimal choices like my current FSM top-level aggregate with sub-entities themselves having inconsistently built-out FSMs of their own. [1] https://www.fantasyflightgames.com/en/products/genesys/ https://www.fantasyflightgames.com/en/products/genesys/ [2] https://genesysemporium.com/ https://genesysemporium.com/
- crooked-v 5y agoCheck out Inform 7, which is distantly descended from text games like Zork. http://inform7.com http://inform7.com It has a rules engine intricate enough to literally include basic physics simulations (example from their documentation): A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration. A room has a concentration called current concentration. A room has a concentration called former concentration. To decide what number is the probability inverse between (space - a room) and (second space - a room): let guess be 20; let way be the best route from space to second space; if way is up, let guess be 50; if way is down, let guess be 10; if the guess is less than 10, decide on 10; decide on guess. Every turn: follow the diffusion rules. The diffusion rules are a rulebook. A diffusion rule (this is the gas movement rule): repeat with space running through rooms: let sum be 0.0 ppm; repeat with way running through directions: let second space be the room way from the space; if second space is a room: let incoming be the former concentration of the second space divided by the probability inverse between second space and space; let outgoing be the former concentration of the space divided by the probability inverse between space and second space; let difference be incoming minus outgoing; increase sum by the difference; now current concentration of the space is the former concentration of the space plus the sum. A diffusion rule (this is the resetting concentration rule): repeat with space running through rooms: now the former concentration of the space is the current concentration of the space. The last diffusion rule (this is the lethal dosage rule): if the current concentration of the location is greater than LC50: say "The concentration in the air overpowers you..."; end the story; otherwise: if the current concentration of the location is greater than TLV-STEL: say "You feel extremely uncomfortable in this environment." Instead of doing something when the current concentration of the location is greater than TLV-STEL: if going, continue the action; say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."