vaendryl / Sunrider

source code of the visual novel 'Sunrider'
http://sunrider-vn.com/
41 stars 21 forks source link

rewrite modifier backend #59

Open vaendryl opened 9 years ago

vaendryl commented 9 years ago
BlueOrange commented 9 years ago

This seemed like a good idea the first 10 times I read it, although the nightmarish qualities of implementation and testing kept making me glad it would be you, and not me. Then I thought that I'd do you a favour and make a start on it. Then I looked at the code, and realised I had vastly underestimated the nightmare.

Modifier class is definitely the way to go, but I think there might be an easier way to go about it - if the modifier class makes actual changes to the thing that it modifies (and sets them back when it expires), then the task becomes much simpler. In other words, instead of requiring the ships to understand all of the ways in which they can be modified (knowledge of the future is always problematic), we require the modifiers to understand all about the ships that they modify (which already exists, and is therefore simpler).

So Modifier would be an abstract class that looks something like this:

Class Modifier(store.object): def apply(newtarget):

make the change

def unapply():
    #undo the change
def end_of_turn():
    #reduce duration remaining by 1, unapply if expired.  Can be overridden if the modifier is permanent in nature
duration_remaining = 1
_target = None

If you're modifying a statistic, then you modify the statistic by hacking into the ship and changing it. If you're modifying a dynamic behaviour, then you might fiddle with the method references. (Creating a method reference in a ship is like creating one in the battlemanager - one of the easiest and safest refactorings around.)

You'd need to be careful about mixing absolute modifiers that expire with relative modifiers, given that value + 100 * 1.3 != value* 1.3 + 100. Otherwise, this should be pretty safe.

(Grrr. Stupid github deleted my indentation.)

vaendryl commented 9 years ago

I want to make a modifier system that's as powerful as possible. preferably one that can do more than change stats. I still need to think on how to handle it though. I don't think this will be a thing for beta 7 after all.

BlueOrange commented 9 years ago

It looks like fun. Will get you a proof on concept while you sleep.

BlueOrange commented 9 years ago

On second thoughts, I'm starting to see why your original idea is the way to go, and my time for this project is running out for the day.

So, you have a modifier class that has a set of attributes that it modifies. When you evaluate the value for an attribute, you scan through the modifiers and apply them. It should be possible to rewrite apply_modifier so that it instantiates the class and attaches an instance to the ship as it works through.

In general, I think an end_of_turn() function (similar to the bakery stuff) is quite relevant to modifiers, and to ships as well.

So, that's attribute modifiers. Behaviour modifiers, I reckon you'd handle those by playing with pointers. The trick is to make each modifier responsible for cleaning itself up, and to give each ship a 'scrub_modifiers' method that gets each modifier to clean itself up, and then deletes the modifier.

Memory management starts to look like an issue, although it might be less worse than the current modifier arrays that mostly sit empty.