Pressing Competition 2 or Typing Competition 2 is a Godot game which allows you to choose characters and fight against each other.
It’s open-sourced under MIT here
You can find the showcase here
It’s developed with Godot Mono 3.2.3
What you need:
- Godot Mono 3.2.3 or later
- Source code from Github
In the tutorial, you want to get ZJS from Hell Hole Studios into the game.
This tutorial is updated on 2021/1/30 and is aimed for version 1.5 This tutorial is updated again on 2021/3/6 to match 1.10
This tutorial is updated agin on 2021/3/13 to match 1.11
Download source code and import it as Godot project. You are done!
Due to some Godot bugs, please ignore all errors.
Create a new folder under
HHS and add a new script extending
Provide two parameters to
name:String, the name of the group
CharacterBases in this group
Register your group at
Let’s say ZJS’s skill is to deal 1000 damage to himself
Define the following properties here:
skillCost:Int(1-2000). Don’t set it to 0 unless it’s a passive skill.
image:String Image path
skillType:Int(0-1). Optional. Set this to 1 to set the skill to be a passive type.
version:Int(0-1). Optional. Set this to 1 for a more advanced skill overwrite. 1 is recommended for >=1.10 users
nosub:Bool Optional. Setting this to true will make the character unavailable for minions
onSkillA function comes with 6 parameters. It’s called when player uses a skill. It’s also called every frame if it’s a passive skill. This method won’t be called unless
version is set to 1.
me: Character the skill user side’s master
sub: Character the skill user side’s minion
enemy: Character the skill enemy side’s master
enemySub: Character the skill enemy side’s minion
scene: GameSubview current scene
isSub: Bool whether the skill was called by a minion
onSkill is an easier version of
onSkillA. This method won’t be called unless
version is set to 0(default).
me:Character the skill user
enemy:Character skill user’s enemy
scene:GameSubview current GameSubview scene
Let’s take a look at what’s in the class
Character so you know what you can do:
CharacterBase uses Singleton design principle so:
base is read-only. Writing it will cause the next round to be corrupted. Write to corresponding variables instead
Do not use
self or internal variables in onSkill. Writing it will cause the next round to be corrupted. Write to
scene.emit_signal("damage_given",...,...) to deal damage or the HP will not be displayed correctly
Some common scenario
- Increase attack by 1:
- Double skill cost:
- Adding Status:
- Deal 60 damage:
- Heal 60 HP:
- Writing to user variable:
- Writing to scene objects: Lorelei:6
- Initalizing a variable fast: Koishi:6
- Checking minion: Satono:6
- Calling others’ skill: Rin:8
Character.checkAction("attack/defense/skill/gauge")to check if a character is attacking/healing/gauge-filling/using skill at the same frame this is called.
Character.keyholds the bitmask for the actions at this frame
Character.checkA1("attack/defense/skill/gauge")to check if a key is just pressed
Character.checkA2("attack/defense/skill/gauge")to check if a key is pressed/hold
Character.checkB1("attack/defense/skill/gauge",default)to check if a key is just pressed or return default if it’s AI
Character.checkB2("attack/defense/skill/gauge",default)to check if a key is pressed/hold or return default if it’s AI
The last step is to put your picture in the path you set to. Make sure it’s facing right. It’s recommended to put it under
Use status to create lengthy events!
System comes with built-in status:
GDBuff.new(name,duration,damage,interval)will inflict a status called
durationframes long. It will cause
GSBuff.new(name,duration,damage,interval)will inflict a status called
durationframes long. It will lose
damageskill gauge every
GDRBuff.new(name,duration,da,db,interval)will inflict a status called
durationframes long. It will cause
dbdamage randomly every
Custom Status should extends
This is another example:
Note that using self and internal variables are okay:
scene.Global contains the Global variables, use them if you need:
Minions are a new concept and game mechanics in 1.10. The minion is stored in
Global.s2 as a character. It’s basically a character with their HP,heal,atk unused, so don’t deal damage or cast status on them. You can set
nosub to true to prevent a character being selected as minion.
The minion gauge is stored in minion’s
skillGauge variable and the threshold is in
When master attacks, gauge will increase by 10. When master gets hurt, gauge will increase by
You should release your own version of PC2 with credits and link to the original version. You can also have your characters included in the main version with a pull request.
So, with that being said, enjoy modding and creating!