Jump to content

[Tutorial] How to define a character outside modmain.lua, in its own file


Topy
 Share

Recommended Posts

This can be very useful if you want to create a mod which includes multiple characters, or if you want to keep your modmain clean. For the sake of the example, let's call our character watson

First, here is a proposed folder structure

.
├── bigportraits/
│   └── Here insert your character's bigportraits. For some reason this needs to be at the mod's root
├── characters/
│   └── watson/
│       ├── anim
│       ├── exported
│       └── images
├── scripts/ (This needs to be at the root as well)
│   ├── prefabs/
│   │   ├── watson_none.lua
│   │   └── watson.lua
│   ├── watson_define.lua
│   └── watson_speech.lua
├── modinfo.lua
└── modmain.lua

The important thing here is that you can separate your characters' art.

Now that this is sorted out, let's take a look at the watson_define.lua. This is where you put the code that you would normally put in modmain.lua

local function Define()

  local modenv = require "mymod.modenv"

  -- The character select screen lines
  STRINGS.CHARACTER_TITLES.watson = "The Example"
  STRINGS.CHARACTER_NAMES.watson = "Watson"
  STRINGS.CHARACTER_DESCRIPTIONS.watson = ""
  STRINGS.CHARACTER_QUOTES.watson = "\"Hey I'm a template character\""
  STRINGS.CHARACTER_SURVIVABILITY.watson = "Already dead"

  -- Custom speech strings
  STRINGS.CHARACTERS.watson = require "watson_speech"

  -- The character's name as appears in-game
  STRINGS.NAMES.watson = "watson"
  STRINGS.SKIN_NAMES.watson_none = "watson"

  -- The skins shown in the cycle view window on the character select screen.
  -- A good place to see what you can put in here is in skinutils.lua, in the function GetSkinModes
  local skin_modes = {
    {
      type = "ghost_skin",
      anim_bank = "ghost",
      idle_anim = "idle",
      scale = 0.75,
      offset = { 0, - 25 }
    },
  }

  -- Add mod character to mod character list. Also specify a gender. Possible genders are MALE, FEMALE, ROBOT, NEUTRAL, and PLURAL.
  modenv.AddModCharacter("watson", "MALE", skin_modes)
  modenv.AddMinimapAtlas("characters/watson/images/map_icons/watson.xml")
end

-- This character's assets
local Assets = {
  Asset( "IMAGE", "characters/watson/images/saveslot_portraits/watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/saveslot_portraits/watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/selectscreen_portraits/watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/selectscreen_portraits/watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/selectscreen_portraits/watson_silho.tex" ),
  Asset( "ATLAS", "characters/watson/images/selectscreen_portraits/watson_silho.xml" ),

  Asset( "IMAGE", "bigportraits/watson.tex" ),
  Asset( "ATLAS", "bigportraits/watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/map_icons/watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/map_icons/watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/avatars/avatar_watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/avatars/avatar_watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/avatars/avatar_ghost_watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/avatars/avatar_ghost_watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/avatars/self_inspect_watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/avatars/self_inspect_watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/names_watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/names_watson.xml" ),

  Asset( "IMAGE", "characters/watson/images/names_gold_watson.tex" ),
  Asset( "ATLAS", "characters/watson/images/names_gold_watson.xml" ),
}

-- This character's prefab files
local PrefabFiles = {
  "watson",
  "watson_none",
}

return {
  Define = Define,
  Assets = Assets,
  PrefabFiles = PrefabFiles
}

There are a few things going on here. First I wrapped the usual character code in a Define function. This will allow us to call it inside modmain.lua.

We also defined local variables PrefabFiles and Assets here. This will allow us to define each character's assets and prefabs separately without having to change anything in modmain.lua.

Finally, you may have noticed this line.

local modenv = require "mymod.modenv"

You'll see how we export the mod environment in the modmain.lua file. This allows us to call mod-specific functions such as AddModCharacter or AddMinimapAtlas outside of modmain.lua. Those functions are defined in modutil.lua

The other character files are the usual ones.

Now that this is done, let's take a look at modmain.lua

-- Main file for the mod

local require = GLOBAL.require
GLOBAL.package.loaded["mymod.modenv"] = env

-- Declare Assets and PrefabFiles, required for the mod
Assets = {}
PrefabFiles = {}

-- Characters available in the mod
local char_list = {
  "watson"
}

-- Create automatically all the characters
for key,value in ipairs(char_list) do
  local char = require(value.."_define")      -- Try to import the character's define module that we created above
  char.Define()       -- Define the character

  -- Add its Assets to the mod's
  for key, val in ipairs(char.Assets) do
    table.insert(Assets, val)
  end

  -- Add its PrefabFiles to the mod's
  for key, val in ipairs(char.PrefabFiles) do
    table.insert(PrefabFiles, val)
  end

end

With this architecture, you can easily add/remove multiple characters to your mod by making it modular and keeping modmain clean.

That's it!

  • Like 1
  • Health 3
Link to comment
Share on other sites

Please note that if you move your character's art in subdirectories, the art autocompiler will not work, as it expects your exported art to be in the root of the mod. I'm currently looking into creating a CLI utility to manually compile art from anywhere, not sure If I'll make it tho

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...