Skip to content
Toby edited this page Mar 30, 2024 · 16 revisions

How custom levels work

Level Configuration

The original game had a system where one file contained the layout of the map (*.lX) another was a base configuration for all levels in one difficulty setting (e.g. easy00.sam) and finally one file for each level (easyXX.sam). Previously only the map file was used, but starting with beta 3 parts of these configuration files are also loaded. For example starting balance, available diseases and rooms and competitor names. Though not all values from these files are desirable a few more will be checked in the future.

As of beta 5 CorsixTH uses the following system:

For all maps a base configuration is loaded from base_config.lua. This is done so that there is always some value for a given variable.

The campaign maps then load e.g. the FULL00.sam file, followed by FULLxx.sam. Finally, if present, an additional originalxx.level file is loaded from the levels folder.

Since the demo files lack any level configuration at all CorsixTH provides some configuration with demo.level.

Custom maps just load their .level file after the base_config file.

Since we don't want to create things more than once the same syntax is used in the new custom level system as was used in the original.

Creating Custom Levels

To create a new custom level the easiest way to start is to copy the file [CorsixTH directory]/Levels/example.level to [CorsixTH User Directory]/Levels/ and give it a new name retaining the file ending. That file contains some general advice to what can be done at the moment.

Each line beginning with a % sign are directives to use when loading the game, such as what the level is called and where to find the map file. The value of the setting should be in quotes. Two new lines creates a new paragraph, but additional new lines in a row are discarded. Available commands:

  • Name: What the level should be called (within quotes)
  • MapFile: The name of the binary map file to load. First the Levels directory of the original game will be searched and then the Levels directory of CorsixTH.
  • LevelBriefing: An introduction text to the level shown in the Single Scenario dialog, or
  • LevelBriefingTable.CODE: Language specific introduction texts, eg %LevelBriefingTable.en.
  • LevelDebriefing: The winning message of the level shown in a fax, or
  • LevelDebriefingTable.CODE: Language specific winning messages, eg %LevelBriefingTable.en.

LevelBriefingTable.CODE and LevelDebriefingTable.CODE can be repeated for as many languages as wished. The code is typically the two letter code for the country or language, eg EN for English, FR for French, sourced from the language files.

Every line that starts with a # sign is a definition. After that comes that variable's name and if it is a table its position in it, e.g. [10] Then each consecutive .VariableName is a value name in that definition and the numbers following these are the actual values. Example:

#objects[22].StartAvail.StartStrength.AvailableForLevel 1 9 1 Ultrascan

This is an object definition, namely the 22nd element in the objects table. There are three variables that define this object, StartAvail , StartStrength and AvailableForLevel . StartAvail is set to 1 (the first integer after the variables), which means that the object (and consequently the associated room) will be available from the start of the level. It will have strength 9, and it is actually available at all on this particular level. The rest of the row, in this case "Ultrascan" is ignored and can, as in this case, be a comment.

Note that object 22 in the objects list is defined to be the Ultrascan, not vice versa.

The following variables are used in both the original game and CorsixTH.

Fields

awards_trophies

Properties that define when the player wins trophies or awards, and how much one gets/loses. Currently most trophies are implemented in CorsixTH, but more will come in the future.

Fields Effect
CansOfCoke How many cans of coke that needs to be sold during a year to get that trophy
CansOfCokeBonus How much is gained by doing so
Reputation The reputation barrier that must be exceeded throughout the whole year to get the corresponding trophy
TrophyReputationBonus What is gained from it
TrophyDeathBonus If the player didn't kill any patients during the year he/she will get this amount of money.
computer

Defines all possible AI opponents.

Fields Effect
Playing Whether this particular opponent is playing or not
Name Their player name
emergency_control

This field defines when emergencies should happen. There are two ways to do it. Either let random emergencies happen in random intervals or specify each emergency.

Random emergencies

If you just want some random emergencies now and then, write

#emergency_control[0].Random 0

If a little more control is desired you can instead write

#emergency_control[0].Mean.Variance X Y

where X and Y are mean and variance for a normal distribution (specifically Box-Muller transformation). To avoid generating overly-repetitive emergencies, it is best to ensure your variance is at least moderately smaller than the mean e.g. a mean of 180 could happily have a variance of 30 (majority of values will be within 150-210).

Fields Effect
Random Tells the game that there are random emergencies on the level. Give it any number.
Mean The mean for a normal distribution.
Variance The variance for a normal distribution.
Controlled emergencies

If you want complete control over your emergencies this is the way to write:

#emergency_control[i].StartMonth.EndMonth.Min.Max.Illness.PercWin.Bonus where i starts at 0.

Fields Effect
StartMonth StartMonth and EndMonth define the interval in which a given emergency should occur. For example February year 2 to April year 2 would translate to StartMonth = 14 and EndMonth = 16.
EndMonth See above
Min The interval Min-Max is how many patients should be affected by the disease.
Max See above
Illness The number of the disease, taken from the expertise list.
PercWin Defines how many percent of the patients that need to be cured to get the bonus.
Bonus How much you then get for each patient cured.

Any number of such entries can be given.

expertise

This property is a table of all diseases in the game, or more exactly the ones which show up in the drug casebook in-game including diagnoses.

Fields Effect
Known Defines if the treatment should be known from the beginning of the level
RschReqd How many research points that are required to improve the effectiveness of the drug - if this is a drug. The original game used this value to determine research required to discover rooms too, so if that information is not present in #objects for the related object this value is used instead. Try to always specify RschReqd for objects that needs to be researched!

gbv

This is some kind of general property gatherer where many different things are defined.

Fields Effect
AbilityThreshold A doctor needs to have a certain general skill to be able to fully master a new profession
AllocDelay Number of months before patient allocation starts to depend on reputation etc.
ResearchPointsDivisor How fast research points are accumulated. 5 is standard.
RschImproveCostPercent How many percent of the original research points that are required to improve the machine.
RschImproveIncrementPercent How many additional percentage points are added to the above value for each upgrade. If these are both 10, for example, the first improvement will cost 20 % of the amount needed to discover the machine. The next one 30 % and so on.
SalaryAbilityDivisor How much more expensive a very skilled doctor is.
SalaryAdd Table of modifiers to salary for doctors' skill level and their professions.
StartCost Drugs also cost money each time they're used
StartRating What effectiveness each new drug has from the beginning
TrainingRate How fast being taught in the training room goes
TrainingValue A table defining how much each type of object increases the effectiveness of the training room

objects

This table contains all objects in the game. Have a look in base_config.lua to see which element corresponds to which object.

Fields Effect
StartAvail If the object is available from the start of the level
StartStrength What initial strength the object has. This value gets improved by research. Only for the machinery purchased after the improvement though.
AvailableForLevel
StartCost How much the object costs to purchase. Machines get a lower cost when improved by research.
RschReqd Specifies how many research points are required to discover the object. Also have a look at expertise.RschReqd for related info. Try to always specify RschReqd for objects that needs to be researched!

popn

Handles the spawn rate of patients. Tells the system how many more patients should arrive a given month. The standard values for example:

#popn[0].Month.Change 0 4

#popn[1].Month.Change 1 1

results in an initial spawn rate of 4 patients per month, and then one more each month, i.e. 5 in February, 6 in March. An additional row

#popn[1].Month.Change 6 0

would halt the increase in June so that there would be 9 patients each month thereafter. Note that these values are global. The patients are then divided among the competing hospitals according to the market share.

Fields Effect
Month The month the new value starts to take effect.
Change The new population increase per month

rooms

All rooms are present here. Indexing starts at 7 for some strange reason. For a list of which room is which index, check out base_config.lua.

Fields Effect
Cost The only thing possible to specify at the moment is the cost of the room, excluding the required objects in it (the objects_needed list).

staff

A table where each element is a staff category.

Fields Effect
MinSalary The minimum salary for each staff type

staff_levels

Properties which specify the behaviour of the dialog where the player can hire new staff. May contain many elements.

Fields Effect
Month Which month this distribution gets active
Nurses How many new nurses to make available for hire
Doctors Doctors for hire
Handymen Handymen for hire
Receptionists Receptionists for hire

visuals and non-visuals

Two tables which define which diseases the hospital may come across during the level. Note the difference between these tables and the expertise table even though they both regard diseases.

Fields Effect
Value Whether the disease is stumbled upon on this level

win_criteria and lose_criteria

Here winning and losing conditions are defined each table element is defined to specify the following possible crieria:

1 = Total reputation

2 = Total balance

3 = Percentage of all patients your hospital has treated

4 = Percentage people that have been cured

5 = Percentage people that have been killed

6 = Hospital value

Fields Effect
Criteria The number of the criteria being defined
Value The value for this criteria to be met
New Variables

Furthermore we are as time goes by introducing some new definitions:

town

Interest rates are defined as per 10,000, ie InterestRate of 100 and OverdraftDiff of 200 means an interest rate of 1% and overdraft interest rate of 3%.

Fields Effect (default)
StartCash Defines how much cash the player should have at the beginning of the level (40,000)
InterestRate The bank's interest rate for loans on this level (100)
StartRep The starting reputation (500)
OverdraftDiff The difference between the regular interest rate and the overdraft interest rate (200)