game design – What is a factually optimized engine for JRPG development?

Game engines are everywhere. There are hundreds to choose and sift between that I can’t decide. I’m open to all suggestions, coding languages, and platforms. What is a factually optimized engine for JRPG development?

Note: this is not an opinion based question.

domain driven design – Where does a Process Manager live with a Hexagonal/Ports and Adapters Architecture?

Context: I initially asked this question. I lacked some understanding and phrasing to ask the actual question I wanted to ask. The answer though helped me understand the friction points a bit better to ask this question.


I have three separate Bounded Contexts, and have a new feature requirement that states that, based on an Event from the Upstream Context, two different Commands must be sent to the two Downstream Contexts. This is more appropriately described as a Process Manager (not a Saga, where one operation failure rolls back all operations).

In the book Implementing Domain-Driven Design, a number of packages are described.

  • root.package.(application)
  • root.package.(application.subconcept)
  • root.package.(domain.model)
  • root.package.(domain.model.subconcept)
  • root.package.(domain.service)
  • root.package.(infrastructure)
  • root.package.(infrastructure.persistence)

It also describes Hexagonal Architecture/Ports and Adapters with a pretty straightforward flow.

  • Adapters live in the Infrastructure Layer, and are the clients of the Application Layer/Services
  • Application Services are the clients of the Domain Model

So the code in the *.application package calls the code in the *.domain.* package (model or service).
The code in the *.infrastructure package calls the code in the *.application package.

I noticed a pattern, mechanically (not conceptually), between Aggregates, Projections, and Process Managers.

Projections

  • Consume Events to Produce Current State

Aggregates

  • Consume Events to Produce Current State (Event Sourcing), and
  • Consume Commands to Produce Events (modify Event Stream)

Process Managers

  • Consume Events to Produce Current State (Event Sourcing), and
  • Consume Events to Produce Commands (for other Applications/Aggregates/Contexts)

All three consume Events published by the Domain Model. The Aggregate (Command Model), lives inside the Domain Model, and is sourced from Domain Events. The Projections (Query Model), lives next to the Domain Model (*.projections), and is sourced from Domain Events. The Process Manager lives somewhere, and is sourced from Domain Events.


Based on this, where do the Process Managers live? Do they also live next to the Domain Model (in a *.process package)? Does it exist as an output Adapter, which might place it inside the *.infrastructure package? Remember that this particular Process Manager is not required for the Upstream Context to work, nor is it required for the Downstream Context to work; it is entirely an optional integration between the Upstream, and the two Downstream Contexts.

  • Do optional integrations exist in a separate Bounded Context, in a *.process package, as an Adapter in the Infrastructure?
  • Do required integrations that are sourced from Upstream Events belong in the Upstream Domain Model?
  • Do required integrations that are sourced from multiple Upstream Events, but interact only with one Downstream Context, belong in the Downstream Domain Model, maybe as an input Adapter?

design – Where to store the results of a class internal computation?

WI suspect the real problem here is that there exists a point in time when you know the instance vars but you haven’t yet done the expensive calculation to get the data. Which means if you store the data in the object it now has two states: before and after. Bleh.

I think it’s better to have an object that knows the logic and vars used to make the data but that shoves the data into a new object that it hands to whatever asked for it.

This way there isn’t two states. There’s just an object that makes the data object when asked. Done this way it can immutable. It’s ready to make the data when it exists. And the data object is ready to be used when it exists.

What’s really nice is you don’t have to ask things if they’re ready to be used because if they exist, they’re ready.

If the problem is that you need the data in contexts where you don’t remember if it’s already been created you can make things more efficient by caching the data.

But sometimes the best way to solve a problem is to avoid it. If you need the data then let something inject it into you. Don’t go asking for it.

Material Design | Cards – Rich Media – Above Primary Title VS. Below Primary Title for a Card Grid?

I’m designing a website under Material Design guidelines for an online media organization.

I’m designing right now a card grid where each card will include a rich media component.
The page the grid will be in will be dedicated for content: articles, videos and podcasts, and each card will have one of those content types. Each rich media will be a thumbnail image for the content.

Do you see for this use case any advantages or disadvantages for having the rich media above the primary title? What about the other way around?

Below images of the two structures, taken from Material Design’s documentation on card anatomy (ignore the various marks and notes on the cards, they refer to other things in the documentation):

The rich media above the primary title:
material-design-card--rich-media-above-primary-title

The primary title above the rich media above:
material-design-card-primary-title-above-rich-media

design – Visitor pattern applicable ? – Applying rules to a list of registrations

I have a list of Registration‘s, on which I need to apply a set of rules to each individually.

Rules can be a single Rule, or a sequence of rules, representable by a tree. One rule is a ConditionalRule, where the condition itself can be a tree (e.g. and,or,not, isOwnedByAdmin), which checks if a specific condition apply to the given Registration. I have used the composite pattern on both Rule and Conditional, which currently recieves the registration like:

$rule->apply($registration)

or conditionally:

if($condition->check($registration))
{
    $rule->apply($registration)
}

This works, but needs to be more flexible in the future.

Eventually, I will have to apply this method on something which is not a Registration, say a Post object instead. Post should be able to be run through this rule tree similarly, on compatible rules and conditions. For example, both could check the condition isOwnedByAdmin, but only Post is compatible with the rule PublishPost. I’m ok with the fact that I will be able to construct an illegal tree (something not able to run on a Registration because it requires a Post).

I could extend my composit interfaces:

interface Rule
{
    public function applyTo(Registration $registration, Env $environment);
}

interface Condition
{
    public function check(Registration $registration);
}

into:

interface Rule
{
    public function applyToRegistration(Registration $registration, Env $environment);
    public function applyToPost(Post $post, Env $environment);
}

interface Condition
{
    public function checkRegistration(Registration $registration);
    public function checkPost(Post $post);
}

In the end, I will have quite a few (10+) Condition classes, many Rule classes and few types of objects it will need to run over (3-10). I would have to modify all those classes whenever I need a new type to check against.

I’m considering using 2 instances of the visitor pattern. A ConditionVisitor and a RuleVisitor. The RegistrationRuleVisitor would be created with a Registration object and a RegistrationConditionVisitor visit the Rule tree with.

But as my composit trees is “actions”, applied to a resource, I’m not sure the visitor pattern applies at all? As I’m visiting something which cannot be evaluated without input (a registration/post). Or is there another pattern that I have missed which allows me to use the same tree based application of methods upon an object?

architecture – How to properly design a system that provides services based on location

This is more of a high-level architecture question. If there is a better site to post these at please let me know.

To greatly simplify – think of Uber Eats, but for services. You could order services of a local plumber, local roofer, but also nationwide service like Comcast internet, or some statewide service. “How to order” doesn’t matter, assume all you get from backend is the right phone number, and have to make the call yourself. The question centers around the correct way to set up individual services to make sure they can be easily shown to end users based on location.

Here are a few approaches I thought of so far:

  1. Set up a specific address for each service. Show the end user services within X miles of their home address. Problem – that doesn’t let us handle nationwide or statewide services without setting up individual addresses for each single local office. Seems like a lot of unnecessary precision.
  2. Set up separate list of services for each city, for each state, and for the country. Based on end user’s address show them the services of their city, for their state, and for the country, together in one list. I guess for each service I’d need the optional State and City fields – if empty the service is nationwide, if city is empty but not state – it’s statewide, otherwise it’s citywide. Problem – “citywide” might not be precise enough for big cities. A plumber in a huge city is not likely to go across the entire city for work. Might need a 4th level of services, with precise address and a distance they are willing to travel.

So far it looks like I’d need a combination of both options, which seems like a mess.
How would you handle this?

design – What desing pattern / class / interface should I use for encapsulating a program?

I am building a chess – related application, and I want to use a pre-compiled program called Stockfish as my chess engine. I am wondering what is the best practice to encapsulate the usage of the program. There are many design patterns to match – Strategy, as the program is, after all, an algorithm that operate on some context (a.k.a the game position). Adapter, as what I essentially do is to provide an interface for a pre-existing program, Facade, as the engine is, in fact, an entire subsystem of the program, or even just a regular interface, that specifies all engine operations like this example, and more. Of course, every solution requires easy switch to another engine.

What is the best practice in this case?

game design – Mana, Backlash and Slots: how to limit a magic system

Generally, I encountered three big systems for limiting the amount of magic that characters can wield at a given time in my RPG career. Grossly simplified they belong to one of three groups: Mana-Systems, Backlash-systems, and Magic Slot-allotments. Of course these come at different names in other systems, but their ideas are there

Pay the Price-Systems aka “Mana” et al.

Mana systems generally come with a set number of magic points that can be spent on spells. Most spells take several of these points and balance the used amount with the power of the spell: the more powerful, the more points it takes. For example the-dark-eye-4 uses that approach. In call-of-cthulhu your price is sanity, making it almost-mana, and the life or stamina of a character also can step in as mana replacement in many other systems.

I think they offer a huge variety, as you can drain that mana pool with a huge variety of setups, but their main drawback is bookkeeping.

When most spells only cost a single point an that is not linked to a vital statistic, the system becomes pretty much a Magic Slot.

Magic-Slots

Magic-slots usually represent a single cast of a (baseline) spell. This makes tracking easier, no matter if you need to choose your slots first (as a dnd-3.5 wizard needs to) or can spend them willy-nilly as a l5r-4e shugenja. The downside I see is that we don’t get the same balancing fine thread screw as in a Mana-system but at increased usability.

Some variants also allocate levels to slots to try and balance the power of spells to their usage.

Fighting the Backlash

A totally different approach is gone in shadowrun: you can cast as much as you want, but each spell kicks you in your shins and can damage you. The premise here is, that magic has a Price of Power (TV-Tropes warning) – but there is a mechanic that allows you to resist that damage. It is somewhat related to Mana-systems in that you pay for magic with a statistic (typically health, stamina or sanity) but got a chance to resist that loss.

The downside here is clearly increased rolling but at the benefit of occasionally more magic. Or less. Or actually giving magic a proper risk.

The Balancing act

Now, with the basis out of the way, what design maxims should determine the choice between those three systems? Are there inherent factors that make either system fit better to a specific approach to designing a game?

design – Achieving loose coupling

My scenario involves the following classes:

enter image description here

I have three types of Peer that creates a RegistryType instance because its methods are needed. Same for Identity class. Each PeerType need 0 or all the RegistryType methods in order to accomplish their work. Every Peer is then run by creating a Server instance that makes use of one of the methods defined by the Peer by passing a callback.

What I’m trying to achieve is to solve the tight coupling between the PeerType classes and the RegistryType class. My idea is to define a general Peer class from which every type inherits and define the dependency with the RegistryType there.

The target language is Python so either constructing the Peers with a RegistryType or a Registry is ok.

Even after defining a new Peer class to encapsulate the RegistryType I reckon the two classes are still tight coupled so (maybe) a solution would be to pass a RegistryType instance to the Peer class instead of constructing it inside its constructor.

I hope to receive some great suggestions. Thanks.