DLC that is meant to add more content to the "base" game itself (not New Game+)

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
AERenoir
Veteran
Posts: 320
Joined: Fri May 27, 2011 8:23 pm
Contact:

DLC that is meant to add more content to the "base" game itself (not New Game+)

#1 Post by AERenoir »

So... suppose a DLC is meant to add new routes into the existing game. Like, for example if you have the DLC there will be new choices to choose, or new characters will show up, etc. Can the DLC file be just additional content appended, or will I need to provide a new set of game script files altogether that is meant to overhaul the old non-DLC "base game"?

Like, for example, a choice menu might go:

A) Choice A
B) Choice B
C) (only visible if you have DLC)

I can use conditionals, but if someone gets the DLC will it be implemented if the player tries to play from a previous saved file? Not sure how to setup the inits here.

User avatar
Jackkel Dragon
Veteran
Posts: 283
Joined: Mon Mar 31, 2014 7:17 pm
Organization: Nightshade, Team Despair
itch: jackkel-dragon
Location: USA
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#2 Post by Jackkel Dragon »

A lot of this can quickly get complicated, but the short answer is "you can do it, if you code for it in advance".

An example from one of my games: Flowering Nightshade is structured as a list of stories that can be played from the main menu. In the most recent build of the game, I re-wrote the story selection menu to check for story objects (created during the init phase by other files) and make buttons for each story it finds. Because of this, I theoretically can just provide story DLC files that a player can slot into the game folder and immediately access within the game. But in order to do that, I had to:

- Set up a variable to track story objects in an early init phase
- Define story objects as a class and provide a way to create new ones
- In each .rpy file that defines a new story object, run the story creation function during init (after definition)
- In the screen code, iterate through the story variable and make a button from each story it finds

It can be a bit complicated if you're not familiar with Python and Ren'Py coding, but that's a basic way of doing something like what you're talking about. In general, you need to design the game in such a way that the base game doesn't need to be changed at all to allow for additional files to add things, which means you have to do certain things indirectly. As a specific example, for a choice that only appears if you have a DLC installed, one way I can think of is to:

- Create a function that can dynamically create choice menus from a list of (choice_text, label) tuples.
- During the init phase, create a variable for each choice in the game (or a way to dynamically make these variables, like nested lists or dictionaries)
- In a later init phase, run code that fills in the choices available (across multiple files)
- Where the choice appears in the game script, use the special choice function to get the list of choices, which can be modified by other files

Some Pythonic pseudocode:

Code: Select all

def ChoiceMenu(choice_list):
    ## code to make the choice menu from the list
    for (entry in choice_list):
        choice_text = entry[0]
        choice_label = entry[1]
        ## whatever actually can add the choices goes here...

init -3:
    $ choice_1 = []

init -2: ## main game file
    $ choice_1.append("Yes.", "yes_label")
    $ choice_1.append("No.", "no_label")

init -2: ## maybe DLC file
    $ choice_1.append("Maybe", "maybe_label")

label pre-choice1: ## main game file
    "I have to make a choice..."
    $ ChoiceMenu(choice_1)
On the other hand, if you decide to code things in a way that still requires updates to the main game when DLC is released, the main thing to watch out for is to check to make sure content is installed before anything that might need it. For instance, you can check if a label or file can be found as a conditional for anything that uses the new content, thus making sure only people who have the related DLC files on their system will see the choices or whatever.

I don't recall the exact name of the function, but a great example of this would be using [renpy.has_label("maybe_label")] as a condition for a choice that would jump to a DLC label.
Main Website
Includes information about and links to many of my current and past projects.

Major Game Projects
[Nightshade] Eldritch Academy, Eldritch University, Blooming Nightshade, Flowering Nightshade, Life as Designed
[Team Despair] Corpse Party D2 series

User avatar
AERenoir
Veteran
Posts: 320
Joined: Fri May 27, 2011 8:23 pm
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#3 Post by AERenoir »

Huh. That complicated? I was thinking I would do something like this:

Choice
Choice
if have_DLC:
Bonus Choice

And then set up some extra inits in the DLC so that once the file is added to the "base" game's folder, the game can detect that it exist.

User avatar
Jackkel Dragon
Veteran
Posts: 283
Joined: Mon Mar 31, 2014 7:17 pm
Organization: Nightshade, Team Despair
itch: jackkel-dragon
Location: USA
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#4 Post by Jackkel Dragon »

That could potentially work, though that method requires having all of the choices coded into the base game to work, and thus falls under the "may need to update base game" camp if things change between releasing the base game and the DLC release.

Of the top of my head, I see this going like:

Code: Select all

## in base game files
default dlc1_installed = False

## in dlc1 game files
init python:
    dlc1_installed = True

## in game script, at choice
menu:
    "Yes.":
        jump yes_label
    "No.":
        jump no_label
    "Maybe." if dlc1_installed:
        jump maybe_label
This method requires less fancy code compared to the method I suggested, so it's easier to set up, but it requires more planning if you want to avoid requiring an update to the base game when the DLC comes out. So it may come down to deciding which trade-offs you want to work with.
Main Website
Includes information about and links to many of my current and past projects.

Major Game Projects
[Nightshade] Eldritch Academy, Eldritch University, Blooming Nightshade, Flowering Nightshade, Life as Designed
[Team Despair] Corpse Party D2 series

User avatar
AERenoir
Veteran
Posts: 320
Joined: Fri May 27, 2011 8:23 pm
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#5 Post by AERenoir »

Oof, I hope this is not considered necroposting, I didn't see notifs of new replies.
Thanks. I will have to try that soon.
Do you know if this could work from a saved game, if the DLC is installed midway through an ongoing gameplay?

The idea is that the entire game is going to be worked on all at once, but maybe I might need to separate certain character routes as DLCs for various reasons. E.g maybe one of the characters route contain disturbing themes that people will want to avoid, and rather than putting up warnings I might as well separate the content.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2405
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#6 Post by Ocelot »

It would not, since dlc1_installed = False would be stored in save file.
On top of my head there are some possibilities:
1) Overwrite default value by DLC in later init phase:

Code: Select all

# Main game 
init -100:
    $ dlc1_installed = False

# DLC
init -50 python:
    $ dlc1_installed = True
2) Do not provide value at all, set it only in DLC, check for value existance first:

Code: Select all

#DLC
defin dlc1_installed = True

# Main game 
menu:
    "Yes.":
        jump yes_label
    "No.":
        jump no_label
    "Maybe." if getattr(store, "dlc1_installed", False):
        jump maybe_label
< < insert Rick Cook quote here > >

User avatar
Jackkel Dragon
Veteran
Posts: 283
Joined: Mon Mar 31, 2014 7:17 pm
Organization: Nightshade, Team Despair
itch: jackkel-dragon
Location: USA
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#7 Post by Jackkel Dragon »

I'd have to test it myself to be sure, but the sample code I provided should be able to set the variable even for saved games using the combination of default and init. If not, I believe there is a special label for running code as a game loads, and you can set the value from there. (Using my sample as a baseline, I'd have the after_load or whatever it's called check for DLC and set the flags if they're not already set.)
Main Website
Includes information about and links to many of my current and past projects.

Major Game Projects
[Nightshade] Eldritch Academy, Eldritch University, Blooming Nightshade, Flowering Nightshade, Life as Designed
[Team Despair] Corpse Party D2 series

User avatar
AERenoir
Veteran
Posts: 320
Joined: Fri May 27, 2011 8:23 pm
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#8 Post by AERenoir »

Ocelot wrote: Sat Feb 19, 2022 3:13 pm
"Maybe." if getattr(store, "dlc1_installed", False):
jump maybe_label[/code]
So that needs to say "False" and not "True"?
Will I need to declare any additional checks in the "after_load" label to ensure the DLC exist if I continue from a saved game?

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2405
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: DLC that is meant to add more content to the "base" game itself (not New Game+)

#9 Post by Ocelot »

AERenoir wrote: Sun Feb 20, 2022 2:00 pm So that needs to say "False" and not "True"?
Will I need to declare any additional checks in the "after_load" label to ensure the DLC exist if I continue from a saved game?
getattr(store, "dlc1_installed") literally means store.dlc1_installed which returns value of the variable. HOwever, if variable is not set (when DLC is not installed), it will result in an error. To avoid that you can provide a default value to getattr which will be returned if variable is not set. Logically, value you want when DLC is not installed is False.

Main feature of this approach (both, actually) is that dlc existance variable is never saved into your game at all, so there is no need to make sure that saved variable contains correct information.
< < insert Rick Cook quote here > >

Post Reply

Who is online

Users browsing this forum: Google [Bot]