flare-engine
flare-engine copied to clipboard
Does Flare support a Karma system?
Hi, would it be possible to integrate a karma system with the current engine version via a mod in Flare? Suppose the character has a karma value and increases or decreases this value based on actions in the game. Later in the game, the karma value influences certain mechanisms such as special items of monster loots or trader exchange rates or even storylines. The karma may increase if you kill certain monsters or solve quests without monster kills, and could decrease if you kill animals/npc's that do not attack the player but give XP.
Hello,
This could be done via a mod by using event.set_status and event.unset_status. But it would be a bit clunky if the goal is to keep track of increasing/decreasing numbers... as far as I can tell, the best way to approach this would be to suggest a small change to the engine. And the best way to do that, I think, is to write a sample of what the code would look like. For a first draft, it doesn't have to be ultra-polished, shipment-ready code. Just make it work somehow, even if it looks horrible, and once you have that, you can then try to refine it and make it more elegant (this last part is actually the hardest, at least for beginners like me)
Edit: by the way, killing NPCs is not possible right now. But it is possible to solve this via mods, by spawning an ally on load and treating it as if it was an NPC.
This could be done via a mod by using event.set_status and event.unset_status. But it would be a bit clunky if the goal is to keep track of increasing/decreasing numbers...
True. I've had the idea of having "counter" statuses that contain an integer value that can be incremented/decremented. This could cover a lot of use cases, including the aforementioned karma system. The mod syntax could look something like this:
# set_counter=<label>:<operation>:<operand>
# so let's say we want a variable with the label "karma"...
# operations are: 'set', 'add', 'sub'
# set the value to 0
set_counter=karma:set:0
# increase by 2
set_counter=karma:add:2
# decrease by 1
set_counter=karma:sub:1
# and to check the values...
# requires_counter=<label>:<operation>:<operand>
# requires_not_counter=<label>:<operation>:<operand>
# operations: 'eq', 'gt', 'gte', 'lt', 'lte'
# true if karma >= 5
requires_counter=karma:gte:5
# true if karma is not equal to 10
requires_not_counter=karma:eq:10
# And counters would be stored in the save files like so:
# karma = 5, my_counter = 10
counters=karma:5,my_counter:10
Looks good (awesome, actually). A counter could be useful for a lot of situations. I imagine that the C++ part would involve modifying MapSaver.h, MapSaver.cpp, EventManager.h, and EventManager.cpp. Something like this:
in MapSaver.h
SET_COUNTER = 59,
in MapSaver.cpp
EVENT_COMPONENT_NAME[EC::SET_COUNTER] = "set_counter";
else if (e.type == EC::SET_COUNTER) {
map_file << e.s;
// code here, maybe a while loop?
map_file << std::endl;
}
in EventManager.h
SET_COUNTER = 59,
in EventManager.cpp
else if (key == "set_counter") {
// @ATTR description of this property
e->type = EventComponent::SET_COUNTER;
// more code, etc.
I'm not sure what other details the OP has for the karma system, but it kind of reminds me of the way that Planescape: Torment handled alignments. You start out as a true neutral, but if you do chaotic stuff, your alignment changes to chaotic netural, etc. So a counter could indeed be useful for a lot of things.
This looks very good.
Such a karma system could be used in a more complex game. Imagine, you have a few different trader factions (to keep it simple, dark and light magic). Depending on your karma level, you can only trade with one type of trader or you can only get special items from one of them.
Another concept might be how NPCs interact with you. If you have negative karma, you will receive special quests from dark NPCs that would normally have no quest for you.
It could also be affected complete gameplay. For example, you can not enter certain maps or, based on the Karma value, you enter a different map when you leave a map. In other words, you can have different endings.
Ok, if there are no objections, I'd like to take a shot at this. Been trying to level up on C++ for the past weeks, I think I can do this.
Just one question, would it be better to make a Counter.h and a Counter.cpp? Or should I just modify the relevant files? (There's a lot of them)
@m7600 I would try to keep it in CampaignManager.cpp
, as this is where campaign statuses are handled.
Ok, I have the general outline for the counter, in the form of a small console program. Obviously I wont use namespace std, or cout or cin for the FLARE version.
Should the set
operation always set the counter to 0? or to some number specified by the game/mod?
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int x = 0;
int y = 0;
string label;
string opr;
while (label != "exit")
{
cout << "Enter a label: ";
cin >> label;
cout << "Enter an operation: ";
cin >> opr;
cout << "Enter a number: ";
cin >> y;
if (opr == "set") {
x = 0;
cout << "The result is: " << label << " " << x << '\n';
}
else if (opr == "add") {
x = x + y;
cout << "The result is: " << label << " " << x << '\n';
}
else if (opr == "sub") {
x = x - y;
cout << "The result is: " << label << " " << x << '\n';
}
}
return 0;
}
@m7600 set
should function as an assignment operator. I used 0 in the example that I gave, but you should just as well be able to do something like set_counter=karma:set:10
, which would assign a value of 10 to the karma counter.