Main Loop part 2: Home
The player character's home location has to implement a number of
labels expected by the main loop.
This is the second part of the main loop section.
Note: The Per
suffix relates to this being
the date/period version in my project.
Arrival
The first label is the .arrival
one that is called when
the player character returns home.
All this has to do is describe the player character letting themselves
into their home, and then set pcLoc
.
# # Player's home. # Date/Period style. # label homePer: # ------------------------------------------------------------------------- # Interface labels # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Player arrives home from somewhere else. # label .arrive: $ dbgLabel('homePer', 'arrive') "Fishing out your key you let yourself into your home." $ pcLoc = 'homePer' return
Choice
The label that will likely be used most often is the .choice
one.
This is called by the main loop when the player should be offered a choice
of what to do next.
In this simple example I've just added some basic choices:
- Three meals, conditional on the time of day.
- Watch TV, which is really just a rest/wait option.
-
Two travel options: town is always available, work only on work days.
These involve using the
travelTo
routine. - Sleep, which advances to the next day.
# Offer player a choice of what to do. # label .choice: $ dbgLabel('homePer', 'choice') menu: "{alt}Menu. {/alt}What to do?" "Breakfast" if period == 0: call .breakfast from home_per_choice_bfast "Lunch" if period == 2: call .lunch from ome_per_choice_lunch "Dinner" if period == 4: call .dinner from home_per_choice_dinner "Watch TV": call .tv from home_per_choice_tv "Go into town": call .goTown from home_per_choice_town "Go to work" if isWorkDayPer(): call .goWork from home_per_choice_work "Sleep": call .sleep from home_per_choice_sleep return
Travel To
The travelTo(destLoc
label implements travelling from
the player character's home to other places.
For the purposes of this example the only travel option the player
character has from their home is to take a bus into the town centre.
-
If the player character wants to go to work, then the bus trip
is described and their location is set to
townPer
. ThetownPer.travelTo()
will then be used by the main travel code to finish the journey. -
If the player character wants to go to town, then the bus trip
is described and their location is set to
townPer
. -
As a fallback if the destination isn't known, for example when
a new location is added in development, a vague travel message
is given and the
pcLoc
is set todestLoc
.
# Have the player travel to a new location. # label .travelTo(destLoc): $ dbgLabel('homePer', 'travelTo', 'destLoc={}', destLoc) if destLoc == 'workPer': if period == 1: "The bus is packed as you and the other commuters head into town." else: "The bus isn't nearly as busy as it is in the morning. It's almost pleasant. Almost." $ pcLoc = 'townPer' elif destLoc == 'townPer': "You get the bus into town." $ pcLoc = destLoc else: # Fall back if there's no specific travel message. "You let yourself out of the house and head to your destination." $ pcLoc = destLoc return
This code can be expanded upon as needed. Perhaps the player character obtains their own vehicle, or they get a lift with an NPC they like and chat along the way.
Wake
The final label needed is the .wake
one.
This just describes the player character waking up.
In this example code the player character can only wake in their
home, but this is left as part of the location "interface" in case
the player wakes somewhere else in a future development.
# Have the player wake up. # label .wake: $ dbgLabel('homePer', 'wake') "You wake up rested in your own bed." return
Activities
The remainder of the code for this location implements the choices the player can make. These are kept as subroutines so the choice menu can be implemented differently if desired, for example a travel option that brings up a clickable map.
Going to town
All the go to town routine has to do is to call
mainPer.travelTo('townPer')
.
This then makes the required calls to describe the player character's
travel and their arrival at the destination.
# ------------------------------------------------------------------------- # Local activities # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Player character wants to into town. # label .goTown: $ dbgLabel('homePer', 'goTown') call mainPer.travelTo('townPer') from home_per_go_town_travel return
The sequence of calls is:
- The main loop calls
homePer.choice
. -
The player chooses "Go into town" which calls the above
townPer.goTown
. - The
.goTown
callsmainPer.travelTo('townPer')
. -
The
mainPer.travelTo('townPer')
callshomePer.travelTo('townPer')
which describes the journey and setspcLoc
totownPer
and returns. -
As the player character is now in the desired location the
mainPer.travelTo('townPer')
callstownPer.arrive()
to describe arrival in the town and returns. -
The
mainPer.travelTo('townPer')
returns as its task is complete. - The
townPer.goTown
routine returns. - The
homePer.choice
returns. - The main loop executes once more and calls
townPer.choice
.
Going to work
The go to work routine has is very similar, calling
mainPer.travelTo('workPer')
.
# Player character wants to to work. # label .goWork: $ dbgLabel('homePer', 'goWork') call mainPer.travelTo('workPer') from home_per_go_work_travel return
The sequence of calls is a little different:
- The main loop calls
homePer.choice
. -
The player chooses "Go to work" which calls the above
homePer.goWork
. - The
homePer.goWork
callsmainPer.travelTo('workPer')
. -
The
mainPer.travelTo('workPer')
callshomePer.travelTo('workPer')
which describes the journey into town and setspcLoc
totownPer
and returns. -
As the player character isn't at work yet
the
mainPer.travelTo('workPer')
callstownPer.travelTo('workPer')
which describes the next step of the journey. It setspcLoc
toworkPer
and returns. -
As the player character is now in the desired location the
mainPer.travelTo('workPer')
callsworkPer.arrive()
to describe arrival at work and returns. -
The
mainPer.travelTo('workPer')
returns as its task is complete. - The
homePer.goWork
routine returns. - The
homePer.choice
returns. - The main loop executes once more and calls
workPer.choice
.
Sleep
The sleep routine first checks that the player character is tired enough
to sleep, and rejects the request with a message if they aren't tired
and it's not at least evening.
If they do sleep then newDay
is set to True
so the main loop can do the new day processing and wake the player
character.
If it's evening or later it advances to the next day.
If the player character is so tired they can sleep during the day
it uses two periods instead.
# Player wants to sleep. # Allow if energy is zero, and not too early. # label .sleep: $ dbgLabel('homePer', 'sleep') if energy > 0 and period < 3: "You get into bed and toss and turn for a while, but it's too early to fall asleep." return "You get into bed and fall asleep." $ newDay = True if period >= 4: $ nextDayPer() else: $ addPeriod(2) return
And the rest...
The remaining routines are simple. They just produce narration and advance the period as needed.
loc/homePer.rpy (cont)# Player character has breakfast. # label .breakfast: $ dbgLabel('homePer', 'breakfast') "A simple bowl of cereal and a cup of life-giving coffee should keep you going until lunchtime." $ nextDayPer() return # Player character makes dinner. # label .dinner: $ dbgLabel('homePer', 'dinner') "A microwaved frozen meal and a beer sorts out your evening meal." $ nextDayPer() return # Player character makes lunch. # label .lunch: $ dbgLabel('homePer', 'lunch') "You fix yourself a sandwich for lunch, and have another coffee." $ nextDayPer() return # Player character wants to pass time watching TV. # label .tv: $ dbgLabel('homePer', 'tv') "You flop down on the couch and start channel surfing, but nothing really grabs you attention." $ nextDayPer() return
Summary
Hopefully the brief nature of each of these routines shows the benefit of breaking the tasks down into very small parts. Each of them can of course become more complex as needed to tell your story.
Other parts of the main loop example
- Main Loop
- The main loop.
- Town centre
- The town centre and hub.
- Workplace
- The player character's place of work.