The perk system will have to consist of a set of perks and some logic to enact their function.
Where this logic resides should be up for design. Two ways I see it:
We can do it like Fallout 2 and intersperse perk logic in relevant game logic. This has the benefit of being easy to do, more obvious, and immediately powerful, but has the big downside of hardcoding perk logic and having it distributed amongst unrelated code. This is obviously very undesirable.
The other way would be to have the perk system intercept and override calculations similar to (and possibly using) an event system, e.g.:
// Calculating perception range (as an example)
let range = 10;
// ...
range = Event.emit("rangeCheck", { obj, range });
Event then dispatches the event and somehow combines return values from its event handlers, and passes it back to this check. In the perk system, we could have, for eample:
Perk.define("Sharp Eye", { rangeCheck: ({ range }) => range*2 });
Which effectively doubles the range.
The benefit of this approach is perk logic being localized in one place; the downside, of course, is requiring events to be emitted for each place a perk should be checked, and having the event system properly combine event handler results.
In addition, with a more distributed and modular approach, perks can be added in a data-driven manner (such as via mods), rather than having to edit the engine code.
However, to anticipate such new perks, more events for checks would need to be added in more of the codebase.
The perk system will have to consist of a set of perks and some logic to enact their function.
Where this logic resides should be up for design. Two ways I see it:
We can do it like Fallout 2 and intersperse perk logic in relevant game logic. This has the benefit of being easy to do, more obvious, and immediately powerful, but has the big downside of hardcoding perk logic and having it distributed amongst unrelated code. This is obviously very undesirable.
The other way would be to have the perk system intercept and override calculations similar to (and possibly using) an event system, e.g.:
Event then dispatches the event and somehow combines return values from its event handlers, and passes it back to this check. In the perk system, we could have, for eample:
Which effectively doubles the range.
The benefit of this approach is perk logic being localized in one place; the downside, of course, is requiring events to be emitted for each place a perk should be checked, and having the event system properly combine event handler results.
In addition, with a more distributed and modular approach, perks can be added in a data-driven manner (such as via mods), rather than having to edit the engine code. However, to anticipate such new perks, more events for checks would need to be added in more of the codebase.