Adding Sprite Objects - Monika-After-Story/MonikaModDev GitHub Wiki

Version 0.9.4 introduced adding sprites via JSON files.

TOC

  1. Installing Sprite/Art Packs
  2. Using Sprite/Art Packs In-Game
  3. Creating Sprite/Art Packs
  4. JSON Formats
  5. File Locations
  6. Prog Points
  7. Gift Reactions
  8. Available Exprops
  9. ACSTemplates
  10. Version History

Installing Sprite Packs

Installing these sprite packs into your mod will be done the same way you installed the mod/manually install updates.

  1. Download the sprite pack zip file from our releases page.
  2. The zip file will contain folders with the sprite pack names, and inside each of those will be a folder named mod_assets. Simply copy the mod_assets folder for the sprite pack you wish to install while MAS is closed and paste it into the game folder that is located in the base directory of your MAS install.
    • For a steam install on any OS, reach the base directory by right-clicking on the game Doki Doki Literature Club in your steam library, click the option Properties, then click on the tab Local Files and then click Browse Local Files.
    • For non-steam Windows, it's the folder from which you launch the game.
    • For non-steam Mac, inside of your MAS install right click on DDLC.app (it may just show as DDLC) and click Show package Contents, then navigate to Contents/Resources/autorun/

Video example of installation here

Troubleshooting Installation

  1. Did you copy the mod_assets folder of the spritepack you wanted to install into game/? Aka, there should not be a folder like author-spritepackname in game/ nor mod_assets/.
    1. YES - delete the author-spritepackname folder in your game/ or mod_assets/ and copy the mod_assets folder from the spritepack into your game/, try to gift again.
    2. NO - continue to step 2.
  2. Does log/spj.log list the sprites you wanted to gift? (See here if you don't know how to check your logs)
    1. YES - continue to step 3.
    2. NO - verify that you have installed the contents of a spritepack into game/ correctly and if you installed a spritepack while MAS was running, say goodbye and reload.
  3. Does log/spj.log contain any lines with ERROR? If you have already done this and the sprites still don't appear in the log, go to step 6.
    1. YES - verify that you have installed the contents of a spritepack into game/ correctly and try again. If you have already done this and errors continue to show, go to step 6.
    2. NO - continue to step 4.
  4. Are you adding a hairstyle spritepack?
    1. YES - Hairstyles are not giftable, they should already be unlocked unless the sprite pack creator is using custom code to unlock them. You can find unlocked hairstyles in Hey, Monika... > Appearance... > Can you change your hairstyle?
    2. NO - continue to step 5.
  5. Did you copy the files in the gifts/ folder to your characters/ folder?
    1. YES - continue to step 6.
    2. NO - copy the files in the gifts/ folder to your characters/ folder.
  6. Make an issue and include the following:
    • name of the spritepack you are trying to install
    • name of the gift you are trying to gift
    • log/spj.log

Using Sprite Packs In Game

Each sprite in a sprite pack has an associated giftname. Files with the appropriate giftnames are in the gifts/ folder in a sprite pack. NOTE: Not every sprite object may be unlocked this way.

Creating Sprite Packs

Creating sprite packs require only 2 things: Art and JSONs to describe the sprite.

Art should be in the appropriate 1280x850 size (except the thumbnail). See File Locations for where to put the art.

JSONs should follow the format below. Again, see File Locations for where to put the JSON.

And don't forget, log/spj.log is your friend.

Submitting a sprite pack:

Requirements for submissions:

  • Includes JSONs for the sprites.
  • Spritepack folder structure is correct.
  • One of the following must apply:
    • the art was created by you
    • the art was commissioned by you
    • the art is owned by you
    • the creator of the art has given you explicit permission for creating a spritepack

Sprite packs submitted to the spritepack issue (#3765) are not eligible for addition to the official spritepacks. To submit something for the official spritepacks, make an issue. Note that we have final say regarding the usage of sprites included in the official spritepacks.

JSON format

ACS (Regular)

{
    "version": 3,
    "type": 0,
    "name": "id-of-sprite",
    "img_sit": "base_filename_without_extension",
    "pose_map": {
        "default": "0",
        "l_default": "5",
        "use_reg_for_l": false,
        "p1": "1",
        "p2": "2",
        "p3": "3",
        "p4": "4",
        "p5": "5",
        "p6": "6",
        "p7": "7"
    },
    "stay_on_start": true,
    "ex_props": {
        "propname": "propvalue"
    },
    "select_info": {
        "display_name": "User Friendly Name",
        "thumb": "thumbnail_filename_without_extension",
        "group": "id-of-selection-group",
        "visible_when_locked": false,
        "select_dlg": [
            "list of dialogue to show when selected"
        ]
    },
    "giftname": "gift_filename_without_extension",
    "dryrun": false,
    "rec_layer": 3,
    "priority": 10,
    "acs_type": "accessory-type",
    "mux_type": [
        "list-of-mutually-exclusive-types"
    ],
    "dlg_desc": "user-friendly accessory name",
    "dlg_plural": false,
    "keep_on_desk": false
}

ACS (Split)

{
    "version": 3,
    "type": 0,
    "name": "id-of-sprite",
    "img_sit": "base_filename_without_extension",
    "pose_map": {
        "default": "0",
        "l_default": "5",
        "use_reg_for_l": false,
        "p1": "1",
        "p2": "2",
        "p3": "3",
        "p4": "4",
        "p5": "5",
        "p6": "6",
        "p7": "7"
    },
    "stay_on_start": true,
    "ex_props": {
        "propname": "propvalue"
    },
    "select_info": {
        "display_name": "User Friendly Name",
        "thumb": "thumbnail_filename_without_extension",
        "group": "id-of-selection-group",
        "visible_when_locked": false,
        "select_dlg": [
            "list of dialogue to show when selected"
        ]
    },
    "giftname": "gift_filename_without_extension",
    "dryrun": false,
    "rec_layer": 3,
    "priority": 10,
    "acs_type": "accessory-type",
    "mux_type": [
        "list-of-mutually-exclusive-types"
    ],
    "arm_split": {
        "default": "0",
        "l_default": "5",
        "use_reg_for_l": true,
        "p1": "0",
        "p2": "",
        "p3": "5",
        "p4": "10",
        "p5": "5^10",
        "p6": "*",
        "p7": "*"
    },
    "dlg_desc": "user-friendly accessory name",
    "dlg_plural": false,
    "keep_on_desk": false
}

Hair

{
    "version": 3,
    "type": 1,
    "name": "id-of-sprite",
    "img_sit": "base_filename_without_extension",
    "pose_map": {
        "mpm_type": 0,
        "default": true,
        "l_default": false,
        "use_reg_for_l": false,
        "p1": true,
        "p2": false,
        "p3": true,
        "p4": false,
        "p5": true,
        "p6": false,
        "p7": false
    },
    "stay_on_start": true,
    "ex_props": {
        "propname": "propvalue"
    },
    "select_info": {
        "display_name": "User Friendly Name",
        "thumb": "thumbnail_filename_without_extension",
        "group": "id-of-selection-group",
        "visible_when_locked": true,
        "select_dlg": [
            "list of dialogue to show when selected"
        ]
    },
    "unlock": true,
    "dryrun": false
}

Clothes

{
    "version": 3,
    "type": 2,
    "name": "id-of-sprite",
    "img_sit": "base_filename_without_extension",
    "pose_map": {
        "mpm_type": 1,
        "default": "steepling",
        "l_default": "def|def",
        "use_reg_for_l": true,
        "p1": "steepling",
        "p2": "crossed",
        "p3": "restleftpointright",
        "p4": "pointright",
        "p5": "steepling",
        "p6": "down"
    },
    "stay_on_start": true,
    "ex_props": {
        "propname": "propvalue"
    },
    "select_info": {
        "display_name": "User Friendly Name",
        "thumb": "thumbnail_filename_without_extension",
        "group": "id-of-selection-group",
        "visible_when_locked": true,
        "hover_dlg": [
            "list of dialogue to show when hovered"
        ],
        "select_dlg": [
            "list of dialogue to show when selected"
        ],
    },
    "giftname": "gift_filename_without_extension",
    "dryrun": false,
    "hair_map": {
        "all": "def",
        "bun": "def"
    },
    "pose_arms": {
        "crossed": {
            "tag": "crossed",
            "layers": "5^10"
        },
        "left-down": {
            "tag": "down",
            "layers": "0"
        },
        "left-rest": {
            "tag": "rest",
            "layers": "10"
        },
        "right-down": {
            "tag": "down",
            "layers": "0"
        },
        "right-point": {
            "tag": "point",
            "layers": "0"
        },
        "right-restpoint": {
            "tag": "restpoint",
            "layers": "10"
        },
        "steepling": {
            "tag": "steepling",
            "layers": "10"
        },
        "def|left-def": {
            "tag": "def",
            "layers": "10"
        },
        "def|right-def": {
            "tag": "def",
            "layers": "5^10"
        }
    },
    "outfit_hair": "hair-sprite-ID",
    "outfit_acs": [
        "acs-ID",
        "another-acs-ID"
    ]
}

Highlights

Highlights are a way to add layers to a sprite that will not be affected by the filtering system. For example, this can be used to add glow to a sprite during night time.

Here is a simplified example to add highlight layers to an ACS at night. (Only relevant properties are shown)

{
    "version": 3,
    "type": 0,
    "name": "glowingacs",
    "img_sit": "glowingacs",
    "pose_map": {
        "default": "0",
        "l_default": "5",
        "p1": "0",
        "p2": "1",
        "p3": "0",
        "p4": "2",
        "p5": "5",
        "p6": "0",
        "p7": "1"
    },
    "highlight": {
        "mapping": {
            "0": {
                "night": "0"
            },
            "1": {
                "night": "1"
            },
            "2": {
                "night": "2"
            },
            "5": {
                "night": "5"
            }
        }
    }
}

This assumes the following:

  • The ACS has images using pose codes 0, 1, 2, and 5.
  • The ACS has highlights for those images.

The resulting files to match with this JSON:

  • acs-glowingacs-0.png
  • acs-glowingacs-0-h0.png - highlight layer to apply for any pose using pose code 0
  • acs-glowingacs-1.png
  • acs-glowingacs-1-h1.png - highlight layer to apply for any pose using pose code 1
  • acs-glowingacs-2.png
  • acs-glowingacs-2-h2.png - highlight layer to apply for any pose using pose code 2
  • acs-glowingacs-5.png
  • acs-glowingacs-5-h5.png - highlight layer to apply for any pose using pose code 5

The highlight code does NOT need to match the pose code. The example uses the same value for ease of organization. In general, highlight layers just need to have an -h# suffix where # is any arbitrary string.

Additionally, Clothes and Hair have different mapping keys than ACS. More explanation is given in the Highlight object section.

For where to put the highlight property, see the Object Explanation section below.

Object Explanation:

Shared name/value pairs:

These properties are for all sprite objects

  • version: (int) version of this sprite
    • required
    • as of 0.11.0, this should be set to 3
  • type: (int) type of this sprite
    • required
    • Must be one of the following values:
      • 0 - ACS
      • 1 - Hair
      • 2 - Clothes
  • name: (string) name of this sprite
    • required
    • must be unique to sprite type
    • This is used as an identifier for this sprite.
  • img_sit: (string) filename for this sprite's sitting position
    • required
    • Do not include filename extension.
    • Do not include file path.
  • pose_map: (object) PoseMap object
    • required
    • usage varies depending on sprite type. See here for more info.
  • stay_on_start: (boolean) determines if Monika should continue wearing the sprite object on a restart
    • optional
    • True allows Monika to continue wearing the sprite upon a restart. False will remove the sprite upon quitting.
    • Default: false
  • ex_props: (object) dictionary of arbitrary properties
    • optional
    • Allows for arbitrary properties to be assigned to this sprite object.
    • This is like giving the sprite object "tags".
    • Keys must be strings.
    • Values must be strings/ints/bools
    • Available ex props
    • Default: empty object
  • select_info: (object) Selectable object
    • optional
    • Allows the sprite object to be selectable via a selector. See here for more info.
    • Default: empty object
  • highlight: (object) Highlight object OR HighlightSplit object if Split ACS
    • optional
    • highlights are layers added to sprites that ignore the filtering system
    • ACS with arm_split set should use HighlightSplit objects
  • dryrun: (any) Meta key that enables dryrun mode
    • optional
    • If provided, the sprite object will not be formally added to the database, but will be checked for errors/warnings. (aka a "dry run")
    • Value does not matter.

ACS specific

These properites are for only ACS sprites

  • rec_layer: (int) desired layer for this ACS
    • optional
    • Must be one of the following values:
      • 0 - before body (PRE_ACS)
      • 1 - between facial expressions and arms (MID_ACS)
      • 2 - after arms (PST_ACS)
      • 3 - between back hair and body (BBH_ACS)
      • 4 - between body and front hair (BFH_ACS)
      • 5 - between front hair and facial expressions (AFH_ACS)
      • 6 - between body and back arms (BBA_ACS)
      • 7 - between middle arms and boobs (MAB_ACS)
      • 8 - between base body and clothes (BSE_ACS)
      • 9 - between base arms and clothes (ASE_ACS)
      • 10 - between base arms and table (BAT_ACS)
      • 11 - between middle arms and table (MAT_ACS)
    • This will force the ACS to only be rendered in this layer.
    • Default: 2 (PST_ACS)
  • priority: (int) render priority
    • optional
    • lower is rendered first
    • Default: 10
  • acs_type: (string) type of this ACS
    • optional
    • This is used with mux_type to automatically determine what ACS to remove when trying to wear this ACS.
    • Generally, this should be used if you anticipate multiple versions of a similar ACS (ribbons, mugs).
    • If you need something akin to "tags", use ex_props instead.
    • This is also used with the ACSTemplate system to default certain properties. See ACSTemplates for more info.
    • Default: None
  • mux_type: (list of strings) list of ACS types that this ACS conflicts with
    • optional
    • This is used with acs_type to automatically determine what ACS to remove when trying to wear this ACS.
    • ACS with types listed here will be removed when trying to wear this ACS.
    • Default: None
  • giftname: (string) filename for the sprite's associated gift
    • optional
    • Providing a giftname enables the sprite to be gifted to Monika.
    • Do not include filename extension.
    • Do not include file path.
    • If not provided, the sprite cannot be unlocked via gifting, and therefore not unlockable via the standard system. Sprites can stil be unlocked programmatically.
    • Default: None
  • arm_split: (object) PoseMap object
    • required if rec_layer is 8 (BSE) or 9 (ASE). ignored otherwise
    • each value should be a string. See PoseMap object for more info.
    • if omitted, then this will make a regular ACS
  • dlg_desc: (string) user-friendly name of the accessory to be used in dialogue
    • optional
    • This is used in dialogue when referring to the accessory.
    • This should be in lowercase.
    • Must be provided with dlg_plural
  • dlg_plural: (boolean) determines if dlg_desc should be used with plural or singular adjectives/adverbs
    • optional
    • This is used in dialogue when referring to the accessory.
    • Must be provided with dlg_desc
  • keep_on_desk: (boolean) determines if this ACS should remain on the desk if Monika is not at the desk.
    • optional
    • Default: false

Hair specific

These properties are only for Hair sprites

  • unlock: (boolean) determines if this sprite should be unlocked automatically or not
    • optional
    • True means the hair sprite is unlocked automatically. False means the hair sprite will not be unlocked automatically.
    • If False, the sprite can only be unlocked programmatically.
    • Default: true

Clothes specific

These properties are only for Clothes sprites

  • hair_map: (object) dictionary mapping hairstyles to other hairstyles
    • optional
    • Allows for overriding hairstyles with other hairstyles when wearing these Clothes.
    • Keys must be strings. Keys should be IDs of hair sprites (Except all)
    • Values must be strings. Values should be IDs of hair sprites.
    • Using key all will establish a default hairstyle override. If this is not explicitly set, this will be set to def (the default ponytail hairstyle)
    • NOTE: Dry running will not catch keys/values that do not exist. Instead, warnings are logged and properties altered to prevent crashes.
  • giftname: (string) Same as giftname in ACS sprites
  • pose_arms: (object) PoseArms object
    • optional
    • If not provided, then we use the internally defined pose_arms that follow the base sprites.
  • outfit_hair: (string) hairstyle that matches these clothes for an outfit
    • optional
    • Must be an ID of a hair sprite.
  • outfit_acs: (list of strings) list of ACS that matches these clothes for an outfit
    • optional
    • Each string must be an ID of an ACS.

PoseMap object

These properties are for PoseMap objects

  • mpm_type: (int) type of this pose map
    • required for pose_map for Hair and Clothes
    • optional for other properties
    • For pose_map in Hair and Clothes, this should be set to one of the following:
      • 0 - if the pose_map should be treated as enable / disable mode
      • 1 - if the pose_map should be treated as fallback mode
    • For ACS and all other properties, this will be overwritten internally with the correct type.
    • Default: Internally-defined
  • default: (boolean | string | object) value to use as default for all non-leaning poses
    • optional
    • Default: None
  • l_default: (boolean | string | object) value to use as default for all leaning poses
    • optional
    • Default: None
  • use_reg_for_l: (boolean) determines of the leaning defaults should use regular defaults instead
    • optional
    • True will use default instead of l_default in the appropriate situations. False will treat the two values separately.
    • Default: False
  • p1: (boolean | string | object) value to use for pose 1
    • optional
    • This is the "steepling" pose.
    • Default: None
  • p2: (boolean | string | object) value to use for pose 2
    • optional
    • This is the "crossed" pose.
    • Default: None
  • p3: (boolean | string | object) value to use for pose 3
    • optional
    • This is the "restleftpointright" pose.
    • Default: None
  • p4: (boolean | string | object) value to use for pose 4
    • optional
    • This is the "pointright" pose.
    • Default: None
  • p5: (boolean | string | object) value to use for pose 5
    • optional
    • This is the "lean|def" pose.
    • Default: None
  • p6: (boolean | string | object) value to use for pose 6
    • optional
    • This is the "down" pose.
    • Default: None
  • p7: (boolean | string | object) vlaue to use for pose 7
    • optional
    • This is the "downleftpointright" pose
    • Default: None

Many of the values (except for use_reg_for_l) are different for each sprite type:

  • ACS:
    • pose_map - each value should be a string denoting an image code to use. For example, if set to "0", then the ACS is assumed to have an image like acs-mug-0.png
    • arm_split - only used if the ACS's rec_layer is ASE or BSE. Each value should be a caret (^) delimeited stirng like: 5^10. Available layer codes:
      • "0" - this ACS has a body-0 or arms-0 (acs-mug-0-0.png) layer for this pose
      • "1" - this ACS has a body-1 (acs-mug-0-1.png) layer for this pose
      • "5" - this ACS has an arms-5 (acs-mug-0-5.png) layer for this pose
      • "10" - this ACS has an arms-10 (acs-mug-0-10.png) layer for this pose
      • "" - this ACS has no layers for this pose (it is not rendered)
      • "*" - this ACS has all layers for this pose
  • Hair:
    • pose_map - each value should be either a boolean or a string, depending on the mpm_type
      • if mpm_type is 0, then each value should be a boolean. True denotes that the pose should be enabled, False means the pose should be disabled.
      • if mpm_type is 1, then each value should be a pose, as a string (see below). This pose is used instead of the actual pose.
  • Clothes:
    • pose_map - Same rules as Hair.

Available Poses:

  • steepling - stock pose from DDLC
  • crossed - crossed arms
  • restleftpointright - steepling, except right hand points right
  • pointright - left arm is down, right arm extends far right and points right
  • down - both arms down
  • downleftpointright - left arm is down, right arm is rest and points right
  • def|def - default leaning with default arms

Selectable object

These properties are for Selectable objects (select_info)

  • display_name: (string) User friendly name of this sprite
    • required
    • This is shown to the user via the selector menus.
  • thumb: (string) filename of thi sprite's thumbnail
    • required
    • This is shown to the user as the thumbnail in selector menus.
  • group: (string) ID of the group this selectable should be associated with
    • required
    • Used to group selectables so related sprites can be selected with the appropriate selector menu.
  • visible_when_locked: (boolean) determins if the sprite should be visible in the selector menu even when locked
    • optional
    • True will allow the sprite to appear in the selector menu when its locked. False will only allow this to appear when it is unlocked.
    • Default: True
  • select_dlg: (list of strings) list of lines Monika should say when this sprite has been selected
    • optional
    • Each string is treated as a separate message, picked randomly.
    • There is support for substitutions (aka using square brackets), but its limited to global variables.
    • Expression is not adjustable per line. In general, 1eua is used.
    • When the sprite has been "selected", Monika changes to wear the sprite.
    • Default: None

PoseArms object

This is a mapping of all available arms. Any ommitted arm means that no layers should be shown for that arm. An empty object means these clothes have no arm layers.

  • crossed: (object) PoseArm object
    • optional
    • pose arm data to use for crossed arms
  • left-down: (object) PoseArm object
    • optional
    • pose arm data to use for the left down arm
  • left-rest: (object) PoseArm object
    • optional
    • pose arm data to use for the left rest arm
  • right-down: (object) PoseArm object
    • optional
    • pose arm data to use for the right down arm
  • right-point: (object) PoseArm object
    • optional
    • pose arm data to use for the right point arm
  • right-restpoint: (object) PoseArm object
    • optional
    • pose arm data to use for the right restpoint arm
  • steepling: (object) PoseArm object
    • optional
    • pose arm data to use for steepling arms
  • def|left-def: (object) PoseArm object
    • optional
    • pose arm data to use for leaning-def-left-def arm
  • def|right-def: (object) PoseArm object
    • optional
    • pose arm data to use for leaning-def-right-def arm

PoseArm object

Represntation of a single arm.

  • tag: (string) name of the arm string to use when rendering this arm
    • required
    • used in format like arms-<tag> or arms-left/right-<tag>
  • layers: (string) a caret (^) delimited string denoting layers for this arm
    • required
    • acceptable values:
      • "*" - this arm exists on all layers
      • "0" - this arm exists on the 0 layer
      • "5" - this arm exists on the 5 layer
      • "10" - this arm exists on the 10 layer
      • "" - this arm does not exist on any layer
    • delimited string should look like 5^10
  • highlight: (object) Highlight object
    • optional
    • highlights to use for this arm

HighlightSplit object

Highlight split objects are only for Split ACS. Keys should be the same as the values used in the pose_map. Values should be Highlight objects, where the keys are the ones listed below for HighlightSplit. These should also be the same as the values used for arm_split.

Here is an abriged example:

{
    "pose_map": {
        "p1": "1",
        "p2": "2",
        "p7": "7"
    },
    "arm_split": {
        "p1": "10",
        "p2": "5^10",
        "p7": "0"
    },
    "highlight": {
        "1": {
            "mapping": {
                "10": {
                    "night": "0"
                }
            }
        },
        "2": {
            "mapping": {
                "5": {
                    "night": "1"
                },
                "10": {
                    "night": "2"
                }
            }
        },
        "7": {
            "mapping": {
                "0": {
                    "night": "3"
                }
            }
        }
    }
}

Highlight object

  • default: (object) Filter object
    • optional
    • default highlights to apply
    • This should be rarely used.
  • mapping: (object) dictionary-based object.
    • optional
    • Keys will vary based on containing object.
    • Values should be Filter objects

Keys for Highlight objects will vary based on the objecting containing the highlight property. All keys are strings.

  • ACS
    • keys should be the same as values used in the pose_map property.
  • Hair
    • front - highlights to apply to the front layer of a hair object
    • back - highlights to apply to the back layer of a hair object
    • def|front - highlights to apply to the front leaning layer of a hair object
    • def|back - highlights to apply to the back leaning layer of a hair object
  • Clothes
    • 0 - highlights to apply to the body-0 layer of a clothes object
    • 1 - highlights to apply to the body-1 layer of a clothes object
    • def|0 - highlights to apply to the body-0 leaning layer of a clothes object
    • def|1 - highlights to apply to the body-1 leaning layer of a clothes object
  • PoseArm object
    • 0 - highlights to apply to the arm-0 layer of an arm object
    • 5 - highlights to apply to the arm-5 layer of an arm object
    • 10 - highlights to apply to the arm-10 layer of an arm object
  • HighlightSplit object
    • 0 - highlights to apply to the acs-0 layer
    • 1 - highlights to apply to the acs-1 layer
    • 5 - highlights to apply to the acs-5 layer
    • 10 - highlights to apply to the acs-10 layer

Filter object

Filter objects map specific filters to highlight codes, which determine which highlight layer to use depending on the current filter. These highlight codes are appended to the end of files (before extension) as -h#, where # is the code.

  • default: (string) default highlight code to use
    • optional
    • always applied regardless of filter
    • this should be rarely used
  • day: (string) highlight code to use for the day filter
    • optional
    • applied when the day filter is used
  • night: (string) highlight code to use for the night filter
    • optional
    • applied when the night filter is used

File locations

All sprite JSONs should be added to game/mod_assets/monika/j/. When MAS is launched, the log/spj.log file will contain messages regarding the sprites, including warnings and errors encountered during parsing. Errors mean the sprite was not loaded. Warnings mean the sprite was loaded, but may have issues later on.

Art files should go in the respective folders:

  • game/mod_assets/monika/a/* - ACS
  • game/mod_assets/monika/c/clothing_name/* - clothes
  • game/mod_assets/monika/h/* - hair
  • game/mod_assets/thumbs/* - thumbnails for selectors

The spj.log log file will contain warnings if the appropriate sprites are not found or not loadable.

Prog points

JSON sprites can still be given prog points, however these are determined programmatically. Prog points should exist at init level -2 in the mas_sprites store with the following name format:

  • ACS:
    • _acs_name_entry
    • _acs_name_exit
  • HAIR:
    • _hair_name_entry
    • _hair_name_exit
  • CLOTHES:
    • _clothes_name_entry
    • _clothes_name_exit

Name in the above formats are replaced with the name property from the JSON.

Prog points are checked for existence and callability on startup, and logged in log/spj.log regardless of dryrun status. Prog points can also be checked using a dev topic located in dev/dev_sprites. This tool is recommended for testing prog points as it catches exceptions and prevents crashes.

Gift reactions

If giftname is filled out, the sprite is added to the reactions framework. This attempts to use explicit labels before falling back to generic ones. Reaction labels should have the following names:

  • ACS : mas_reaction_gift_acs_<name>
  • HAIR: mas_reaction_gift_hair_<name>
  • CLOTHES: mas_reaction_gift_clothes_<name>

where <name> is replaced with the name property from JSON.

The generic reaction label is mas_reaction_gift_generic_sprite_json.

All reaction labels must start with a call to mas_getSpriteObjInfo and end in a call to mas_finishSpriteObjInfo prior to the file deletion function call. See the generic reaction label for an example. See the appropriate functions in zz_reactions for more info.

Available Exprops

exprop acs? hair? clothes? effects value
bare-right-shoulder X marks that these clothes have a bare right shoulder ignored
cosplay X marks that these clothes are a cosplay ignored
costume X marks that these clothes are a costume ignored
desired-ribbon X forces a ribbon to be worn when switching to these clothes name of the ribbon to wear, as a string
drink X marks that this ACS is a drink item ignored
excluded-clothes-props X limits this ACS to only be worn with clothes that do not contain any of the specified ex_props list of ex_props to be excluded, as list of string
excluded-hair-props X limits this ACS to only be worn with hair that do not contain any of the specified ex_props list of ex_props to be excluded, as list of string
food X marks that this ACS is a food item ignored
left-desk-acs X marks that this ACS is on Monika's left side on the desk. Used to avoid stacking ACS on the same spot ignored
lingerie X marks that these clothes are lingerie ignored
no-tails X marks that this hair has no tails ignored
required-clothes-prop X limits this Hair to only be worn with clothes that contain a specificed ex_props the ex_prop desired by this Hair, as a string
required-hair-prop X limits this ACS to only be worn with hair that contains a specified ex_props the ex_prop desired by this ACS, as a string
ribbon X enables ribbons for this hairstyle ignored
ribbon-like X marks that this ACS should be considered similar to a ribbon, but is not a direct version of the main ribbon ignored
ribbon-off X removes ribbon if worn when switching to this hairstyle ignored
ribbon-restore X restores previously used ribbon when switching to this hairstyle, if found ignored
tiedstrand X marks that this hair is a tiedstrand hairstyle ignored
twin-ribbon X marks that this ACS is a twin-ribbon based acs ignored
twintails X marks that this hair is a twintail hairstyle ignored

ACSTemplates

ACSTemplates are used to default certain props. Custom props can still be provided via JSONs, but they will not override defaults provided by the templates. NOTE: ACSTemplates may not be completely updated as of 0.11.0. I will be separating these (and exprops) to a separate page that will be auto-generated.

Templatable props:

  • mux_type
  • ex_props
  • keep_on_desk

Here is a list of the current templates and what they default. Items in all CAPS are described in the 2nd table.

acs-type defaulted mux_type defaulted ex_props
bow DEF_MUX_RB ribbon-like: True, excluded-hair-props: DEF_EXP_TT_EXCL
bunny-scrunchie DEF_MUX_RB ribbon-like: True, excluded-hair-props: DEF_EXP_TT_EXCL
headband DEF_MUX_HB
headset DEF_MUX_HS
left-hair-clip DEF_MUX_LHC left-hair-strand-eye-level: True
left-hair-flower left-hair-flower, left-hair-flower-ear left-hair-strand-eye-level: True
left-hair-flower-ear DEF_MUX_LHFE left-hair-strand-eye-level: True
mug mug
necklace necklace bare collar: True
ribbon DEF_MUX_RB
twin-ribbons DEF_MUX_RB twin-ribbon: True, ribbon-like: True, required-hair-prop: twintails
wrist-bracelet wrist-bracelet bare wrist: True
item value
DEF_EXP_TT_EXCL twintails
DEF_MUX_RB ribbon, bow, bunny-scrunchie, hat, s-type-ribbon, twin-ribbons
DEF_MUX_HAT hat, bow, bunny-scrunchie, earphones, front-hair-flower-crown, headband, headphones, headset, left-hair-flower, ribbon, s-type-ribbon, twin-tibbons
DEF_MUX_HB headband, hat, headphones, headset
DEF_MUX_HS headset, earphones, hat, headband, headphones, left-hair-flower-ear
DEF_MUX_LD chocs, plate, plush_q
DEF_MUX_LHC left-hair-clip
DEF_MUX_LHFE left-hair-flower-ear, earphones, front-hair-flower-crown, hat, headset, headphones, left-hair-flower

Version History

  • 0.11.0 - added keep_on_desk property to ACSTemplates. Removed hover_dlg from JSONs. Added highlight to JSONs. Updated pose_arms for JSONs. Added exprops bare-right-shoulder, drink, excluded-clothes-props, food, left-desk-acs, lingerie, no-tails, required-clothes-prop, tiedstrand
  • 0.10.4 - updated ACSTemplates left-hair-flower and bow, added bunny-scrunchie. excluded-hair-props exprops added.
  • 0.10.3 - updated ACSTemplates left-hair-flower and added left-hair-flower-ear
  • 0.10.2 - ribbon-like, required-hair-prop, twintails, costume, cosplay exprops added. dlg_desc and dlg_plural added. ACSTemplates added.
  • 0.10.0 - Updated to work with the new split-base system
  • 0.9.4 - Created
⚠️ **GitHub.com Fallback** ⚠️