HentHighSchool Development Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

collapse
* Recent Posts
Re: Test version for 0.2 by Jman
[Today at 12:26:46 pm]


Re: Test version for 0.2 by bibense
[Today at 12:05:35 pm]


Re: Girl packs by Leortha
[Today at 06:43:14 am]


Re: Off-topic, and Fun! by DougTheC
[Today at 05:54:25 am]


Re: Test version for 0.2 by DougTheC
[Today at 05:36:54 am]


Pages: [1]   Go Down

Author Topic: AAR Modding help  (Read 1634 times)

dreamchaser

  • Full Member
  • ***
  • Offline Offline
  • Posts: 160
    • View Profile
AAR Modding help
« on: March 14, 2021, 10:34:08 am »

This thread is intended for budding modders to ask me questions, so that everybody can benefit from the answers.
If I improve the modding documentation, I'll post this here, so that you don't have to wait for the next game release to profit from it.

To make your life easier, you can set yourself up a Ren'Py development environment.
https://www.renpy.org/release/7.3.5
This will give you (amongst other things) a proper editor that is linked to from game errors, and a button to delete all .rpyc files.
(Just moving the AshfordAcademyRedux-0.x.y-pc folder into the renpy-7.3.5 folder is enough)
« Last Edit: March 14, 2021, 10:48:42 am by dreamchaser »
Logged

dreamchaser

  • Full Member
  • ***
  • Offline Offline
  • Posts: 160
    • View Profile
Re: AAR Modding help
« Reply #1 on: March 14, 2021, 10:35:06 am »

I've added startup help to the example mod readme.txt, so copying that here.

====Howtos for changes====
==Debug Menu==
To enable the debug menu (everything following will assume you have it) in game/script/game_data.rpy, change
config.developer = "auto"
to
config.developer = True

==Renaming Mod and Club==
To rename the event and club to sth. else (taking 'swimming' as the 'example' new name for the club and mymod for the mod):
Tip: before you start, make a copy of the folder game/images/example, just in case.

- rename the folder game/images/example to game/images/mymod
#(this is the mod folder itself)
- in game/images/mymod/main.rpy change
Mod("example",50,desc="an example mod as starting point for modders")
to
Mod("mymod",50,desc="Your new mod description goes here")
#(this renames the mod)

- in game/images/mymod/data/clubs.rpy change the lines
current_mod="example"
Club("fightclub","Fight Club",False,
unlockable=False)
to:
current_mod="mymod"
Club("swimming","Swimmers Club",False,
unlockable=True)
#(this is the club renaming itself; we set unlockable=True so that we can test the club)

- in game/images/mymod/images/clubs, rename club_fightclub.jpg to club_swimming.jpg
#(this is the expected path for the picture shown for the club in the game menu)

- in game/images/mymod/events, rename fightclub.rpy to swimming.rpy
- in game/images/mymod/events/swimming.rpy change the lines
img_prefix("clubs","fightclub_example","e:club_fightclub")
label clubs_fightclub_example1
to
img_prefix("clubs","swimming_mymod","e:club_swimming")
label clubs_swimming_mymod1
#(this changes the names of the events we define, so that they belong to the swimming club in mymod)

- in game/images/mymod/class.rpy change the lines
img_prefix("class","example")
label class_example1:
to
img_prefix("class","mymod")
label class_mymod1:
#changes the mod name of the class event

- in game/images/mymod/data/image_tags.rpy change the lines
img_prefix("class","example")
img_prefix("clubs","fightclub_example")
to:
img_prefix("class","mymod")
img_prefix("clubs","swimming_mymod")
#(this changes the naming scheme for the event pictures we define here, so that the swimming events (and the class event) find them)

- in game/images/example/images rename folder 'fightclub' to 'swimming'
- in that swimming folder, rename clubs_fightclub_example1-1.jpg to clubs_swimming_mymod1-1.jpg
#(these are the expected locations for the pictures of the swimming event)

- in game/images/example/images/class rename class_example1-1.jpg to class_mymod1-1.jpg
#(this is the expected name for that image due to activity, modname and eventnumber)

- Important!
delete the file game/images/mymod/events/fightclub.rpyc
OR
in the Ren'Py launcher (if you use it) press the "Force Recompile" button
->If you do neither, you'll get extremely weird errors which contradict what you see in the .rpy files!

To test whether everything worked:
- Start a new game
- In Unlocks, check that "Swimmers Club" is there. Click it, and check that the policy picture is shown
  (game/images/mymod/images/clubs/club_swimming.jpg)
- In Seen Events, check that Mod "Mymod" is listed, click it
- in the top right, click "Show all", check that "Class" and "Clubs" are now listed on the right side, click "Clubs"
- On the left, check that "nice name of event" is listed, click it
- Check that the picture is shown
- Click "Replay Event!", check that it plays out properly
« Last Edit: March 14, 2021, 10:49:11 am by dreamchaser »
Logged

dreamchaser

  • Full Member
  • ***
  • Offline Offline
  • Posts: 160
    • View Profile
Re: AAR Modding help
« Reply #2 on: March 14, 2021, 10:39:53 am »

A bit of discussion about mod renaming can also be found here:
https://f95zone.to/threads/ashford-academy-redux-v0-4-1-dream-chaser.43399/post-4912021
->There the big problem turned out to be stale .rpyc files.
Logged

Dante

  • Sr. Member
  • ****
  • Offline Offline
  • Posts: 339
    • View Profile
Re: AAR Modding help
« Reply #3 on: March 15, 2021, 04:19:00 am »

Alright the message system is very buggy(still can't see my previous message) so I'm gonna post it here for now.)


I've set the club up and now I'm gonna start making events for it. The Python coding is very complicated(to me at least) but the readme is helpful and I've been looking through the current game events to make sense of it too. For now my questions are:

-Where are locations/timeperiods set up and where should the swimming club events go?
The 3 options I can think of would be "Pool" on the afternoon slot, "Clubs" on the evening slot, or alternatively separate "clubs" into "cheerleading club" and "swim club". I'm more partial to leave them together under "Clubs" since otherwise I think the mod would need to replace OG game files, and I don't think keeping them together would be a problem until we have too many clubs to handle under one location.

-As far as I can tell the events are separated into two parts, the upper part(image selection and event definition which i sorta understood) and the lower part( actual event content and further coding.)

I'm using the first 3 library events as an example:

Upper part:
(click to show/hide)

In this case i assume the format is:
img_e([first number of the image goes here variations are described with a -another number defined in the img definitions file], "[conditions for the event to trigger]",Reg("[event name]","[event description]"))
So far so good, in the case of event 3 i assume the rest is the option names that will appear as player choices and the conditions for the choices to appear, tho I"m not sure what the pre_img="black" means.

Lower part:
(click to show/hide)
First one is very straight forward. Event description, stat changes, return.

(click to show/hide)

The second one is more or less the same. Only difference is that the event description is separated into click lines and it calls a random number/subject for event flavor. The only question I have is where is it calling that from.


(click to show/hide)
This is where it gets complicated, i understand some of it but if you can give me a general rundown of how this event works i think i will more or less know everything i need to start making my  simple events.

Also the only common question i have between all three is how does the upper part "connects" to the lower one? Is it because the label shares the same number as the image prefix call?

I never coded anything so these questions may be dumb, but i figured it might be somewhat helpful at least if another complete newbie ever tries to make a mod too  ;D
Logged

dreamchaser

  • Full Member
  • ***
  • Offline Offline
  • Posts: 160
    • View Profile
Re: AAR Modding help
« Reply #4 on: March 15, 2021, 12:40:17 pm »

Nice to see that you are working yourself into the code. As I always said, I'll gladly answer any questions, so let's get to it!  :)

-Where are locations/timeperiods set up and where should the swimming club events go?
The 3 options I can think of would be "Pool" on the afternoon slot, "Clubs" on the evening slot, or alternatively separate "clubs" into "cheerleading club" and "swim club". I'm more partial to leave them together under "Clubs" since otherwise I think the mod would need to replace OG game files, and I don't think keeping them together would be a problem until we have too many clubs to handle under one location.
The club events are intended to be all in the same activity slot in "Clubs", so that you can enable and disable multiple ones and get a mix. That has the big advantage that even with only a few events the location won't feel too empty. Currently the Cheerleading Club does not have enough events yet, so that would be very welcome.
(Also, I'll implement a way to choose to visit a specific club in 0.5, so no need to worry about that.)

-As far as I can tell the events are separated into two parts, the upper part(image selection and event definition which i sorta understood) and the lower part( actual event content and further coding.)

I'm using the first 3 library events as an example:
Actually they are split into 3 parts, so I hope you didn't miss the third part, defining the images in canon/data/image_tags.rpy
For the 3 events you picked as examples, the relevant part is:
(click to show/hide)
This lets the game know which images exist, for which dresscodes (=school uniforms) they apply (u:...), and may set tags (and other things, but only tags are used here). Flavor tags are the f:... part (so e.g. image library2-1.jpg is tagged with 'two').

Upper part:
(click to show/hide)

In this case i assume the format is:
img_e([first number of the image goes here variations are described with a -another number defined in the img definitions file], "[conditions for the event to trigger]",Reg("[event name]","[event description]"))
So far so good, in the case of event 3 i assume the rest is the option names that will appear as player choices and the conditions for the choices to appear, tho I"m not sure what the pre_img="black" means.
All correct so far.  :)
From the readme.txt: "pre_img: if True, keeps the chosen image from being displayed. If an image name, that image will be shown instead. Use '$ set_img()' to switch to the chosen image later in the event."

"black" is the name of an image (which is pure black). So pre_img="black" means that at the start of the event the screen is black (instead of showing the chosen image, which is the default behavior).

Lower part:
(click to show/hide)
First one is very straight forward. Event description, stat changes, return.

(click to show/hide)

The second one is more or less the same. Only difference is that the event description is separated into click lines and it calls a random number/subject for event flavor. The only question I have is where is it calling that from.
The topic is set by the function random_topic(), which is defined in base/functions.rpy. It gives you back a random string based on the academics stat (the higher, the more advanced the topic). It is currently only implemented for the academics stat, as I never had a need for another one.

...
This is where it gets complicated, i understand some of it but if you can give me a general rundown of how this event works i think i will more or less know everything i need to start making my  simple events.
Sure, lets do that.   :D

label library3:
    if (renpy.random.randint(1,2)==1 and variant_id==-1) or variant_id in [3,4,5]:
Without the event gallery, this condition would simply read "if (renpy.random.randint(1,2)==1", which in human words means: randomly, 50% of the time.
However, for the event gallery, randomness is bad, so we are looking at variant_id to see whether we are in an event replay.
-1: no, we are not, lets throw the dice
3,4,5: in those event gallery variants we want to enter this code block
any other number: other event gallery variants where we don't want to enter this code block

        "As you walk around in the library you suddenly hear a faint snore."
        $ set_img()
As hinted by the readme, we use $set_img() to activate the image chosen for this event run, since we started it with a black screen (pre_img="black").

        "You see a student who fell asleep in the middle of study and decide to wake her up."
        girl "Mhmm? Oh!"
Everything so far has been narration, the lines which go: "..."
This one puts the speaker that says the line in front of it, in this case 'girl'.
Other possible speakers are 'pov' (the principal/player), the ones defined in base/data/characters.rpy (generic speakers) and the ones defined in canon/data/characters.rpy (specific characters introduced by canon content).

        $ set_img_letter("b")
from the readme:
For pictures named with a letter, there is a function set_img_letter("<letter>") to choose which picture from the set to show.
If you registered bath1-1a and that picture got chosen for the event, set_img_letter("b") would switch to bath1-1b.

->This switches to image library3-1b.

        girl "[povTitle] [povLastName]! I'm sorry, I just have this important test coming up and I must have fallen asleep..."
This line is a bit interesting: In text strings, you can do "[<var>]" to have Ren'Py insert the current value of <var> (a variable or a class property). This is frequently used to have a character address the principal, like here.
Aside: in 0.5, you'll be able to write "[pov.polite]" instead of "[povTitle] [povLastName]". The old way will of course still work, though.

        "She looks really worried so you decide to tell her:"
        menu:
            "Don't worry, just keep up your studies." if variant_id in [-1,3]:
                $ unlock(3) #studies
                girl "I promise I will, [povTitle] [povLastName]!"
                $ academics_o.inc(0.5)

            "This time it's ok, but from now on make sure to get enough sleep at home." if variant_id in [-1,4]:
                $ unlock(4) #enough sleep
                girl "Of course, [povTitle] [povLastName]."
                $ behavior_o.inc(0.5)

            "It's alright, but don't forget to take some time to just relax." if variant_id in [-1,5]:
                $ unlock(5) #relax
                girl "Thank you, [povTitle] [povLastName], I will remember to."
                $ morale_o.inc(0.5)
Here we have a menu with choices. the "if variant_id in [...]" part is a condition for the choice to be available. We use it to restrict the event replay to a single path.
Every list of allowed variant ids contains -1, so that we never constrain what you can do in normal gameplay (outside of a replay).

Once a choice has been made, we use "$ unlock(<n>)" to unlock the corrent event replay variant.

    else:
        $ set_img()
        "While passing through the library, you suddenly come across a young girl who apparently fell asleep in the middle of studying."
        menu:
            "She must be exhausted." if variant_id in [-1,99]:
                pov "I don't have the heart to wake her up."
                $ morale_o.inc(0.5)
                $ academics_o.dec(0.5)

            "This is no place for napping!" if variant_id<1:
                $ unlock(0) #wrong place
                pov "What's this?"
                $ set_img_letter("b")
                girl "Uh... oh... I must have dozed off."
                pov "As long as you are on school premises, you follow our code young lady."
                girl "I - I'm sorry [povTitle] [povLastName]... I was just so tired."
                pov "From now on I expect you to go to bed early on weekdays. Less fooling around after school is the right medicine."
                girl "Y - yes sir."
                $ deviance_o.dec(1)
                $ behavior_o.inc(0.5)

            "Hey, sleepy head, it's time to wake up." if variant_id in [-1,1,2]:
                girl "U...uhm..."
                $ set_img_letter("b")
                pov "Wow, you were really out of it."
                if inhibition < 90:
                    $ unlock(1) #what dream?
                    girl "Oh [povTitle] [povLastName]... I'm so sorry. I had the strangest dream."
                    pov "Now now, that's alright. We all get tired, don't we?"
                    girl "I - I guess... But, you're so kind. I really shouldn't be sleeping while in school."
                    pov "Nothing to worry about. What kind of dream was it?"
                    girl "Oh... Umm..."
                    pov "Ha - ha, I think I can guess..."
                    girl "*giggle*"
                    $ morale_o.inc(0.5)
                    $ inhibition_o.dec(1,50)
                else:
                    $ unlock(2) #wake up!
                    girl "Oh [povTitle] [povLastName]... I'm so sorry."
                    pov "Now now, that's alright. We all get tired, don't we?"
                    girl "I - I guess... But, you're so kind. I really shouldn't be sleeping while in school."
                    pov "Nothing to worry about."
                    $ morale_o.inc(0.3)
Nothing new here, just the same techniques repeated.

Also the only common question i have between all three is how does the upper part "connects" to the lower one? Is it because the label shares the same number as the image prefix call?
The event definition you did above sets up the label the game looks for. And the game will complain at start up if the label has not been defined.
The schema for the label name is: <string1>_<string2><ending> (where string1 and string2 are from img_prefix, and <ending> comes from the img_e call). However, you have canon events here, <string2> has the special value "canon", which is ommited from label and image names.
So:
img_prefix("library","canon") + img_e(1,...
constructs the label name library1.

However, your mod will do something like:
img_prefix("swimming","dante") + img_e(1,...
and construct the label name swimming_dante1 from that (since "dante" isn't the special value "canon", it does not get removed).
Read through the readme.txt explanation of img_prefix again if you need more details, that gives a more in depth explanation.

I never coded anything so these questions may be dumb, but i figured it might be somewhat helpful at least if another complete newbie ever tries to make a mod too  ;D
Best of luck, and feel free to ask questions if you don't understand something.
Remember to search for the string in the readme.txt first. It will often turn up something if you want to know what a method does or a variable means.

And yeah, I think it's better to have these questions and answers here in the thread, just in case anybody else wants to know the same thing.  :)
Logged

Dante

  • Sr. Member
  • ****
  • Offline Offline
  • Posts: 339
    • View Profile
Re: AAR Modding help
« Reply #5 on: March 31, 2021, 03:15:30 am »

Nice to see that you are working yourself into the code. As I always said, I'll gladly answer any questions, so let's get to it!  :)

-Where are locations/timeperiods set up and where should the swimming club events go?
The 3 options I can think of would be "Pool" on the afternoon slot, "Clubs" on the evening slot, or alternatively separate "clubs" into "cheerleading club" and "swim club". I'm more partial to leave them together under "Clubs" since otherwise I think the mod would need to replace OG game files, and I don't think keeping them together would be a problem until we have too many clubs to handle under one location.
The club events are intended to be all in the same activity slot in "Clubs", so that you can enable and disable multiple ones and get a mix. That has the big advantage that even with only a few events the location won't feel too empty. Currently the Cheerleading Club does not have enough events yet, so that would be very welcome.
(Also, I'll implement a way to choose to visit a specific club in 0.5, so no need to worry about that.)

But where in the event it defines where they will trigger?

I haven't had time to work on the mod lately but i did finish the picture collection for the events.
Logged

dreamchaser

  • Full Member
  • ***
  • Offline Offline
  • Posts: 160
    • View Profile
Re: AAR Modding help
« Reply #6 on: March 31, 2021, 02:39:26 pm »

Nice to see that you are working yourself into the code. As I always said, I'll gladly answer any questions, so let's get to it!  :)

-Where are locations/timeperiods set up and where should the swimming club events go?
The 3 options I can think of would be "Pool" on the afternoon slot, "Clubs" on the evening slot, or alternatively separate "clubs" into "cheerleading club" and "swim club". I'm more partial to leave them together under "Clubs" since otherwise I think the mod would need to replace OG game files, and I don't think keeping them together would be a problem until we have too many clubs to handle under one location.
The club events are intended to be all in the same activity slot in "Clubs", so that you can enable and disable multiple ones and get a mix. That has the big advantage that even with only a few events the location won't feel too empty. Currently the Cheerleading Club does not have enough events yet, so that would be very welcome.
(Also, I'll implement a way to choose to visit a specific club in 0.5, so no need to worry about that.)

But where in the event it defines where they will trigger?

I haven't had time to work on the mod lately but i did finish the picture collection for the events.

Well, since you started with the example mod, there should be a line like this in the top part of the file where you define the events:
Code: [Select]
img_prefix("clubs","fightclub_example","e:club_fightclub")(You will probably have renamed 'fightclub' to 'swimming' or something, and 'example' to the name you have given your mod.)
This img_prefix line tells the game that the following events belong to the activity 'clubs', and that they should be available if the club 'fightclub' is enabled.

If you are talking about conditions for single events, you can give those in the img_e definitions. Look into the documentation how to do this, or look at the example event in example/events/class.rpy.
Logged
Pages: [1]   Go Up
 


SimplePortal 2.3.3 © 2008-2010, SimplePortal