Author Topic: WhoreMaster: Abby's Crossing  (Read 139909 times)

0 Members and 2 Guests are viewing this topic.

Offline DarkTl

  • Hero Member
  • *****
  • Posts: 4737
Re: WhoreMaster: Abby's Crossing
« Reply #120 on: December 11, 2013, 09:38:28 AM »
Well, you said it yourself that clients who can afford lvl5 girls are rare. So if you have too many lvl5 girls, you'll be bankrupt. And if you don't have any control over level ups, eventually you will have too many high-level girls.

Offline E.

  • Jr. Member
  • **
  • Posts: 66
  • Till the end of Eternity.
Re: WhoreMaster: Abby's Crossing
« Reply #121 on: December 11, 2013, 09:44:42 AM »
Or you can let the player choose what kind of customer each girl can serve. It sure is a waste to let bums have their way with high ranking girls, but you gotta get cash in. In short, you choose your target demographics.
Additonaly, increase the occurrence of rare customers based on the average rank of your girls.
...

Offline DocClox

  • Dev Team
  • *****
  • Posts: 1867
  • Messing Around With Python
Re: WhoreMaster: Abby's Crossing
« Reply #122 on: December 11, 2013, 01:26:23 PM »
Well, you said it yourself that clients who can afford lvl5 girls are rare. So if you have too many lvl5 girls, you'll be bankrupt. And if you don't have any control over level ups, eventually you will have too many high-level girls.

Yeah, I didn't get to post all the details. The idea is that you'll not have to operate them at max level. In fact some of them may be happier at the sluttier end of the market, even if they have the skill to entertain nobility. I might also allow you to make them work above their current level (less chance of success, more experience).

Also, a level 0 girl working flat will be almost dead at the end of 24 hours. At level six, the same girl has been wined, dined, pampered and allowed a long lie in before a bout of morning sex. So higher level girls don't get so tired so fast. Which means there's an advantage in rotating them when you can.

There are subtleties here that I hope will lend themselves to different effective strategies. I need to wargame some of this stuff  and see how it scales, but if it doesn't look like it's going to work, I promise I won't use it.

Or you can let the player choose what kind of customer each girl can serve. It sure is a waste to let bums have their way with high ranking girls, but you gotta get cash in. In short, you choose your target demographics.

That too. I might even take a leaf out of the original SimBrothel and make level increases depend on special training, so you would be able to choose who gets promoted and who not.

[edit]

Here's a test plate for the new widget, breaking it down and then building up in code.



Of course, at some point I'll need to re-do most of the main screen to fit. But then I was going to have to do that anyway :)

Maybe a couple of pixels more between the year and month and between the month and the day, perhaps?
« Last Edit: December 11, 2013, 04:49:28 PM by DocClox »

Offline AkiraTepes

  • Newbie
  • *
  • Posts: 26
Re: WhoreMaster: Abby's Crossing
« Reply #123 on: December 11, 2013, 08:05:36 PM »
Looking good DocClox! 8)  Can't wait to give it a play ;)

Offline Marquis

  • Newbie
  • *
  • Posts: 30
Re: WhoreMaster: Abby's Crossing
« Reply #124 on: December 12, 2013, 08:36:09 AM »
I agree that a tiny bit more space between year-month and month-day would be better visually. That said, I think the way SlaveMaster3 handles this could be useful also: day and time is useful most of the time for planning shifts, etc. and should be shown on most planning screens. The date could be on a separate page in a calendar format showing any key events in the future (or past). Calling up the calendar could be used for longer term planning.

Offline DocClox

  • Dev Team
  • *****
  • Posts: 1867
  • Messing Around With Python
Re: WhoreMaster: Abby's Crossing
« Reply #125 on: December 12, 2013, 02:27:39 PM »
Looking good DocClox! 8)  Can't wait to give it a play ;)

Thank you. I'm feeling much the same way about it. (Generally a good sign :))

I agree that a tiny bit more space between year-month and month-day would be better visually. That said, I think the way SlaveMaster3 handles this could be useful also: day and time is useful most of the time for planning shifts, etc. and should be shown on most planning screens. The date could be on a separate page in a calendar format showing any key events in the future (or past). Calling up the calendar could be used for longer term planning.

That's a fair point. We don't really need the date, but day number and time would be useful on some other screens.

I'll have a think on that.

And yeah, we are going to need a calendar :)

Here's a design pic for the turn summary screen

The idea is that the LEDs along the  top are toggles which can filter the events in the sidebar. The shift buttons underneath act as filters as well. The mini-leds on the plates are just there so you can see at a glance what categories an event falls into. All I need now is room for some text and a couple of navigation buttons. Still, getting there...

[edit]

Getting there...



[edit]

removed the earlier WIP - not enough difference to be worth having two pics

[edit]

Coded up the header for the screen. All lights toggle and emit signals. Took a bit more juggling than I was expecting. I think  inkscape is rendering fonts too small. Either that or Qt is making them too big.

Anyway, I got it all to fit in the end.



[edit]

Another test image:



This rather unimpressive little thing is the result of a lot of work today. I wanted to be able to draw the outline of the font, and I knew that  QPainterPath could do that. And I wanted wo work out how to do that.

Still not sure the results are worth it. It looks a little pixelated compared to the inkscape version, even with all the antialiasing hints set.

I'll see what it looks like when it's in place. If it looks a mess, I can always draw the numerals normally.

[edit]

actually, looking at it on the web page, it looks ok. Funny that.

[edit]

Main panel is starting to come together:



[edit]

Another case of "doesn't look much but does cool stuff under the hood".



For this little beast, I've used QLinearGradient to generate the brass effect grad rather than exporting images from inkscape. That's going to cut down a lot on the number of images I need in the resource section, and will help me get a consistent look to the brass panels in the game. I feel quite proud of myself!
« Last Edit: December 15, 2013, 05:14:50 AM by DocClox »

Offline malandor

  • Newbie
  • *
  • Posts: 1
Re: WhoreMaster: Abby's Crossing
« Reply #126 on: December 20, 2013, 01:46:11 AM »
interesting game will be extreamly interested to see the finished product

Offline DocClox

  • Dev Team
  • *****
  • Posts: 1867
  • Messing Around With Python
Re: WhoreMaster: Abby's Crossing
« Reply #127 on: December 20, 2013, 01:28:38 PM »
interesting game will be extreamly interested to see the finished product

Me too :)

Not a lot to look at this week. Been all sorts of busy and stressful, both at work and home, so I've not had much energy to work on the screens. That said, I do have a bit of a treat for those of you who like stats and game balancing and who aren't afraid of a little Python.

I did some googling for Python and Simulation and encountered SimPy[1] - a really neat simulation package in Python. So I had a bit play with it. All of the Slavemaker/WM/SimBrothel type games are, at heart, simulations, and getting the sim part of it balanced is very difficult. So being able to separate out the sim from the boobies and test that it works is potentially very valuable.

Code: [Select]

# horrible coding here. will refactor if I get a chance
#
import simpy    # if we combine this with Ren'Py, do we get Ren and Simpy?
import random
import math

SHIFT=60.0*6.0

L0=0.65
L1=0.30
L2=0.05

#
# class representing the ladies providing the service
#
class Server:
    def __init__(self, env, name, charm, skill):
        self.env = env
        self.name = name
#
#        affect demand and satisfaction
#
        self.charm = charm
        self.skill = skill
#
#        the resouce lets customers queue to gain access
#
#        actually I think I want a queue outside and 1:1 access inside
#
        self.res = simpy.Resource(env, 1)
#
#        earings and other accountancy
#
        self.cash = 0
        self.hap_count = 0
        self.sad_count = 0
        self.ccount = 0
        self.skill_check = False

#
#    end of shift report for this valued employee
#
    def report(self):
        print "{0:12s} {1:3d} {2:3d} {3:3d} {4:3d} {5:3d} {6:5d} ".format(
            self.name,
            int(self.charm),
            int(self.skill),
            int(self.ccount),
            int(self.hap_count),
            int(self.sad_count),
            int(self.cash)
        )

#
#    should return true if able to service
#
    def free(self):
        return self.res.count == 0

    def earned(self, inc):
        #print self.name, ": earned ", inc
        self.cash += inc

    def satisf(self, clev):
        self.ccount += 1
        roll = random.uniform(0, 100)
        diff = self.skill - roll
        if diff > 0:    # pass
            self.hap_count += 1
            return 1
        if -1*diff > 25:
            self.sad_count += 1
            return -1
        return 0

class House:
    def __init__(self, env):
        self.servers = [ ]
        for i in range(3):
            server = Server(env,
                name = "server_{}".format(i),
                charm    = random.randint(1,50),
                skill    = random.randint(1,50)
            )
            self.servers.append(server)
#
#        sort them by looks and skill, in that order
#        we can get more creative with the selection process later
#
        self.servers = sorted(self.servers, key = lambda g: g.charm * 100 + g.skill, reverse=True)
#
#        rep draws in the customers. rep 10 gives us a mean of 10 cusomers per shift
#        which would normally be adjusted for the time of day.
#
#        actual numbers can vary a fair amount
#
#        plan is to make rep go up and down with customer satisfaction.
#        so if a lot of them go away unhappy, the number of punters will slowly
#        decrease over time
#
#        Actually, I'd like to base this one fame and reputation
#        where 100 rep gives a nice bonus to the number of customers
#        and -100 rep means that everyone knows your house a den of
#        slavers and murderers and the only visitors you'll get will be
#        adventurers and guardsmen.
#
#        but for now, we keep it simple
#
        self.rep = 20.0
#
#        mean time between arrivals - we'll pass this on to random.expovariant
#        to get a realistic scattering of times
#
        self.mean_tba = SHIFT/self.rep
        self.n_bored = 0
        self.n_custs = 0
#
#        the door: we allow N people inside at a time
#        (where N == number of servers)
#
#        if the house is full, you queue to get in the door
#
        self.door = simpy.Resource(env, 3)
    def top(self):
        for s in self.servers:
            flag = s.free()
            if flag:
                return s
        return None

    def report(self):
        print ""
        print "Shift Report"
        print "{} customers in total ({} bored)".format(self.n_custs, self.n_bored)
        print "Servers:"
        tot_g = tot_h = tot_s = 0
        print "Name         Bty Skl NCu Hap Sad  Cash"
       
        try:
            for s in self.servers:
                s.report()
                tot_g += s.cash
                tot_h += s.hap_count
                tot_s += s.sad_count
        except Exception as e:
            print e
        print "earnings: {}".format(tot_g)
#
#        bored customers count as unhappy.
#        this will have the effect of bringing your house to an
#        equillibrium level over time - if you can't cope, rep will drop
#        until you can. There is not corresponding force tending to raise
#        rep to equilibrium point though, so you need to watch it
#
        print "overal satisfaction: {}".format(tot_h - tot_s - self.n_bored)

env = simpy.Environment()
h = House(env)

def hhmmss(tim):
    mins = math.floor(tim)
    ss = math.floor((tim - mins) * 60)
    hh = mins // 60
    mm = mins % 60
    return "{0:02.0f}:{1:02.0f}:{2:02.0f}".format( hh, mm, ss)

def stamp(env, seq):
    return "{0:s}: {1:3d}: ".format(hhmmss(env.now), seq)

class Customer:
    next = 1
    levels = [
        { "chance" : 65, "level" : 0, "duration" : 10, "income" : 5 },
        { "chance" : 30, "level" : 1, "duration" : 30, "income" : 25 },
        { "chance" :  5, "level" : 2, "duration" : 60, "income" : 75 },
    ];

    def get_lvl():
        l0 = levels[0]["chance"]
        l1 = levels[1]["chance"]

        r = random.random()
        if r < l0:
            return levels[0]
        if r < l0 + l1:
            return levels[1]
        return levels[2]

    def __init__(self, env):
        self.env = env
        lvl = random.choice(self.levels)
        self.__dict__.update(lvl)
        self.seq = Customer.next
        Customer.next += 1
        self.name = "Customer S{}L{}".format(
            self.seq, self.level
        )
        self.process = env.process(self.go())
        self.paitence = env.timeout(random.uniform(20,100))

    def message(self, s):
        print "{}: {}: {}".format(
            hhmmss(self.env.now), self.name, s
        )
    def go(self):
        self.message("Arrival")
        self.arrive = env.now

        with h.door.request() as qq:
#
#            do the actual queue-to-get-through-the-door bit
#
            res = yield qq | self.paitence

#
#            HOW long?
#
            self.wait_time = env.now - self.arrive


            made_it = (qq in res)
            if not made_it:
                self.message("Got bored, went home")
                h.n_bored += 1
                return
               
#
#            otherwise, pick a "server"
#
#            if the door capacity == number of servers
#            there should always be one free
#
            h.n_custs += 1
            w = h.top()
            if w == None:
                raise Exception("No free servers!")
       
            with w.res.request() as ww:

                txt = ""
                if self.wait_time < 0.01:
                    txt = "service from {}".format(w.name)
                else:
                    txt = "service from {} - waited: {}".format(w.name, hhmmss(self.wait_time))
                self.message(txt)

#
#                let some time pass for the customer to conclude his business
#
                yield env.timeout(random.expovariate(1.0/self.duration))
#
#                was it good for you?
#
                sat = w.satisf(self.level)
                tip = 0

            if sat > 0:
                tip = int(math.ceil(random.uniform(0.1, 0.3) * self.income))
                self.message("cust happy - tip = {0:0.0f}".format(tip))
            elif sat < 0:
                self.message("cust unhappy - leaves muttering darkly")
            else:
                self.message("customer satisfied")
            self.message("earned: {}".format(self.income + tip))
            w.earned(self.income + tip)
            self.message("Done")

def source(env):
    seq = 0
    while True:
        t = random.expovariate(1/h.mean_tba)
        yield env.timeout(t)
        #seq += 1
        #if seq > 4: break
        c = Customer(env)



env.process(source(env))
env.run(until = SHIFT)

h.report()

Which runs to give us something like this:

Code: [Select]
00:07:57: Customer S1L0: Arrival
00:07:57: Customer S1L0: service from server_0
00:08:07: Customer S1L0: cust unhappy - leaves muttering darkly
00:08:07: Customer S1L0: earned: 5
00:08:07: Customer S1L0: Done
00:08:19: Customer S2L1: Arrival
00:08:19: Customer S2L1: service from server_0
00:12:04: Customer S3L2: Arrival
00:12:04: Customer S3L2: service from server_1
00:26:40: Customer S4L2: Arrival
00:26:40: Customer S4L2: service from server_2
00:31:58: Customer S3L2: customer satisfied
00:31:58: Customer S3L2: earned: 75
00:31:58: Customer S3L2: Done
00:35:08: Customer S4L2: cust unhappy - leaves muttering darkly
00:35:08: Customer S4L2: earned: 75
00:35:08: Customer S4L2: Done
00:50:27: Customer S5L1: Arrival
00:50:27: Customer S5L1: service from server_1
01:04:26: Customer S6L0: Arrival
01:04:26: Customer S6L0: service from server_2
01:17:12: Customer S2L1: customer satisfied
01:17:12: Customer S2L1: earned: 25
01:17:12: Customer S2L1: Done
01:24:48: Customer S6L0: cust unhappy - leaves muttering darkly
01:24:48: Customer S6L0: earned: 5
01:24:48: Customer S6L0: Done
01:50:34: Customer S7L0: Arrival
01:50:34: Customer S7L0: service from server_0
01:59:07: Customer S5L1: cust unhappy - leaves muttering darkly
01:59:07: Customer S5L1: earned: 25
01:59:07: Customer S5L1: Done
02:10:01: Customer S8L2: Arrival
02:10:01: Customer S8L2: service from server_1
02:14:15: Customer S7L0: cust happy - tip = 1
02:14:15: Customer S7L0: earned: 6
02:14:15: Customer S7L0: Done
02:45:11: Customer S9L1: Arrival
02:45:11: Customer S9L1: service from server_0
02:48:00: Customer S8L2: cust unhappy - leaves muttering darkly
02:48:00: Customer S8L2: earned: 75
02:48:00: Customer S8L2: Done
02:57:50: Customer S9L1: cust unhappy - leaves muttering darkly
02:57:50: Customer S9L1: earned: 25
02:57:50: Customer S9L1: Done
02:59:09: Customer S10L0: Arrival
02:59:09: Customer S10L0: service from server_0
03:00:58: Customer S11L0: Arrival
03:00:58: Customer S11L0: service from server_1
03:11:22: Customer S12L1: Arrival
03:11:22: Customer S12L1: service from server_2
03:13:50: Customer S11L0: customer satisfied
03:13:50: Customer S11L0: earned: 5
03:13:50: Customer S11L0: Done
03:20:56: Customer S10L0: customer satisfied
03:20:56: Customer S10L0: earned: 5
03:20:56: Customer S10L0: Done
03:23:13: Customer S13L2: Arrival
03:23:13: Customer S13L2: service from server_0
03:28:05: Customer S12L1: customer satisfied
03:28:05: Customer S12L1: earned: 25
03:28:05: Customer S12L1: Done
03:53:38: Customer S14L1: Arrival
03:53:38: Customer S14L1: service from server_1
03:54:33: Customer S13L2: cust happy - tip = 15
03:54:33: Customer S13L2: earned: 90
03:54:33: Customer S13L2: Done
04:04:17: Customer S15L2: Arrival
04:04:17: Customer S15L2: service from server_0
04:08:20: Customer S16L1: Arrival
04:08:20: Customer S16L1: service from server_2
04:11:43: Customer S17L1: Arrival
04:46:42: Customer S16L1: cust unhappy - leaves muttering darkly
04:46:42: Customer S16L1: earned: 25
04:46:42: Customer S16L1: Done
04:46:42: Customer S17L1: service from server_2 - waited: 00:34:58
05:01:01: Customer S17L1: cust unhappy - leaves muttering darkly
05:01:01: Customer S17L1: earned: 25
05:01:01: Customer S17L1: Done
05:01:48: Customer S18L0: Arrival
05:01:48: Customer S18L0: service from server_2
05:05:56: Customer S19L1: Arrival
05:16:08: Customer S14L1: customer satisfied
05:16:08: Customer S14L1: earned: 25
05:16:08: Customer S14L1: Done
05:16:08: Customer S19L1: service from server_1 - waited: 00:10:11
05:27:51: Customer S18L0: cust happy - tip = 1
05:27:51: Customer S18L0: earned: 6
05:27:51: Customer S18L0: Done
05:30:18: Customer S19L1: cust unhappy - leaves muttering darkly
05:30:18: Customer S19L1: earned: 25
05:30:18: Customer S19L1: Done
05:31:00: Customer S20L0: Arrival
05:31:00: Customer S20L0: service from server_1
05:42:10: Customer S21L0: Arrival
05:42:10: Customer S21L0: service from server_2
05:48:47: Customer S20L0: customer satisfied
05:48:47: Customer S20L0: earned: 5
05:48:47: Customer S20L0: Done
05:49:40: Customer S22L1: Arrival
05:49:40: Customer S22L1: service from server_1
05:49:42: Customer S23L1: Arrival
05:53:46: Customer S24L1: Arrival
05:58:41: Customer S15L2: cust unhappy - leaves muttering darkly
05:58:41: Customer S15L2: earned: 75
05:58:41: Customer S15L2: Done
05:58:41: Customer S23L1: service from server_0 - waited: 00:08:58

Shift Report
23 customers in total (0 bored)
Servers:
Name         Bty Skl NCu Hap Sad  Cash
server_0      40  45   7   2   3   231
server_1      17   8   7   0   3   235
server_2      13  25   6   1   4   161
earnings: 627
overal satisfaction: -7

As it stands, the code simulates a brothel with a reputation of 20 (which means roughly an average of 20 customers a shift), and which has three whores working flat out. There's a lot of detail missing yet, but I think this could be the basis of a game. it also, has the potential of stepping through the sim event by event - which means we can potentially offer a level of control ranging from micromanaging each customer, through to processing a day or a week at a time, once the management structures are in place.

Anyway, those of you so inclined are encouraged to have a play with the code and try changing some of the assumptions and the weightings and see how that affects the model. We could not only create a robust mathematical model here, but also the basis for a whole family of girl training sims :)

[1] Which sound like it's begging to be combined with Ren'Py so we can get Ren and SimPy.

Offline slate

  • Donator
  • *****
  • Posts: 25
Re: WhoreMaster: Abby's Crossing
« Reply #128 on: December 21, 2013, 07:24:47 AM »
Hello Doclox!

I have looked at the code. This solves working in paralell time.


My main concerns are:
  • There is so much code, it seems to be an overkill.
  • house.top function returns a service(a girl). Customer's demand is not reflected in it.We implicitly suppose, that no customer will deny the service.
  • We implicitly suppose, that if someone gets through the door, then he is guarantied to get a service, otherwise it is an unhandled exception.. I think the "door" is better a lobby, and we should implement waiting in the lobby, or we can also make house.top return a guarantied always accepted service (e.g: G.W.Bush reads up his memoirs...) for no income, too.
  • The functionality of doing a job involves the house, the girl, and the customer. We cannot simply put it into the customer.
  • I strongly recommend to have only one module importing simpy.

slate

Offline DocClox

  • Dev Team
  • *****
  • Posts: 1867
  • Messing Around With Python
Re: WhoreMaster: Abby's Crossing
« Reply #129 on: December 21, 2013, 04:46:38 PM »
    Hello Doclox!

    Heya Slate!

    My main concerns are:
    • There is so much code, it seems to be an overkill.

    You're probably right. It's very much a first attempt at a simulator with me still trying to get the hang of the package. There's a lot in there that could be written much more concisely.

    That said, I think I'd quite like to expand the scope of the simulation to address some of your other points. We could  almost write the entire game as a simpy app and then the GUI as a bolt on. Which is pretty much the right way to go about it, really.

    • house.top function returns a service(a girl). Customer's demand is not reflected in it.We implicitly suppose, that no customer will deny the service.

    Yeah. What I was mainly trying to do was get the customer supply right. The rule where a brothel with reputation X will get a mean of X customers per shift and using an exponential distribution seems to work very well. There's a lot in the way of game mechanics that I didn't get time to address.  Customer refusal is one. Girl's refusing is another.

    I use the term service because I needed some SFW nomenclature ;) 


    • We implicitly suppose, that if someone gets through the door, then he is guarantied to get a service, otherwise it is an unhandled exception.. I think the "door" is better a lobby, and we should implement waiting in the lobby, or we can also make house.top return a guarantied always accepted service (e.g: G.W.Bush reads up his memoirs...) for no income, too.

    I was thinking just that. I've got an updated version that implements a queue outside the building, with the interior having a capacity equal to the no. of girls. That guarantees the match (or should). I was going to leave a reception area as one of the early upgrade options. Buy seating for three customers and you can have the first three wait inside and maybe get an extension to the customer paitence time.

       
    • The functionality of doing a job involves the house, the girl, and the customer. We cannot simply put it into the customer.

    Mmmm... I tend to agree. Mainly I adapted the banking example from the SimPy website, so that's why it's a bit customer-entric.

       
    • I strongly recommend to have only one module importing simpy.


    One module per simulation, certainly. I'm thinking of  modelling auctions using SimPy which would be another module. But we can import simpy into one module and then pass the environment reference into others.

    [edit]

    Updated version of same script. Code cleaned up a lot.

    What I'd like to do with it is add a command loop so it could run shift by shift. Then add adjustments for the time of the shift, and start to adjust girls stats and house reputation according to performance.

    The biggest problem with the current model is that it puts reputation into a nose dive. it needs a way to compensate for that, whether by lowering prices or by adding facilities. Anyway this is what I have so far:

    http://pastebin.com/Vh4wn1sQ[/list][/list]
    « Last Edit: December 22, 2013, 08:29:50 AM by DocClox »

    Offline DocClox

    • Dev Team
    • *****
    • Posts: 1867
    • Messing Around With Python
    Re: WhoreMaster: Abby's Crossing
    « Reply #130 on: December 24, 2013, 11:02:12 AM »
    Hi All!

    Still not much in the way of widgetry to show for my efforts. I've been getting quite fascinated with Simpy and various models for brothels and how they operate. I spent a chunk of today getting Simpy to talk to PyQt without either of them locking the other out, so I might try and do a rough front end to the sim, wrap it in an exe and let you guys have a play with it.

    Some of the ideas I've been kicking around as a result of this:

    Each Brothel has a property called "draw" which is an abstraction of its ability to draw in customers. I'm thinking taking the value. dividing by two and calling that the mean time between arrivals, and then dropping that into random.expovariate to scatter the arrival times a little realistically.

    Currently draw is basically the brothel's reputation, which goes up by 0.1 with each happy customer and down by 0.1 for each unhappy customer, happiness being determined by the girl's skill. The trouble is that with the sort of girls a player is likely to have at the start, there's no real way to get that reputation up.

    So I'm thinking to add some hefty bonuses for a girl's happiness, health and endurance. Maybe spirit too. What I'd like is so that a girl with really quite low skill can satisfy her customers, just so long as she's cheerful and energetic and healthy. That gives a bonus to the whoremaster who looks after his girls. It'll still be possible to do my old preferred tactic of keeping them all in kennels and using drugs to ensure obedience, but it's arguably going to be more efficient to treat them well.

    The other side of the coin is that as customer level rises, the bonus from those stats drops. As the quality of the patrons rises, their expectations rise as well.   So looks and health and attitude will give less of a bonus and, at lower levels start to bring a penalty.

    I'm also getting quite in the the possibility of an ultra low level mode where the player could micromanage customer-by-customer if so inclined.

    OK, sorry about the random blather. Later all.

    Offline DocClox

    • Dev Team
    • *****
    • Posts: 1867
    • Messing Around With Python
    Re: WhoreMaster: Abby's Crossing
    « Reply #131 on: December 24, 2013, 07:28:51 PM »
    Merry Christmas, all!

    Offline DocClox

    • Dev Team
    • *****
    • Posts: 1867
    • Messing Around With Python
    Re: WhoreMaster: Abby's Crossing
    « Reply #132 on: December 30, 2013, 08:23:07 AM »
    Bit of an update:

    I got a working PyQt front end to my sim code, and did a bit more work towards getting the underlying model right.

    Then I hit the point where I needed to pull in data objects from the game proper. Well, that flagged up all sorts of bugs and places where I fudged things to keep the momentum going. So now I'm biting the bullet and writing some unit tests. It's a pain but the code will be all the better for doing so.

    I'm also implementing status effects. These are going to be used to represent things like potions and spell effects, as well as those traits which have an active effect, hunger, addiction - anything that modifies one or more stat really. They're going to let me streamline a lot of code when it comes to things like obedience checks and the like, since the near fractal complexity of WM decision trees can be reduced to looping over the status list and summing any relevant modifiers. But there's no such thing as a free lunch, and the SEs themselves are proving to be surprisingly complicated.

    So: still no pictures worth uploading, but work is continuing.

    Offline Hazure

    • Jr. Member
    • **
    • Posts: 92
    • I'll get there eventualy.
    Re: WhoreMaster: Abby's Crossing
    « Reply #133 on: December 31, 2013, 08:30:26 AM »
    It may be simplified if the rooms had levels as well as the girls.....so that no matter what level the girl is if she is in a lower level room, that's the level she preforms at.

    Offline DocClox

    • Dev Team
    • *****
    • Posts: 1867
    • Messing Around With Python
    Re: WhoreMaster: Abby's Crossing
    « Reply #134 on: December 31, 2013, 12:36:46 PM »
    It may be simplified if the rooms had levels as well as the girls.....so that no matter what level the girl is if she is in a lower level room, that's the level she preforms at.

    mmm... I was thinking along those lines. if you don't have a bed, all you can do is level 0. If you have a bed you can charge at level one. A bed and a bedroom to put it in for level 2. Level three needs nice furnishings and some refreshments, four and up and we're talking about a private suite. 

    Interesting the same logic carries over to other activities. Streetwalking is generally level 0 unless there's a room the girl can use. So would sly handjobs for strippers and serving girls in the bar, although you might be able to charge a grade or two higher if the place was well appointed and the clientèle select.

    All fun stuff, if I can master the complexity of it all.