Skip to content
Snirozu edited this page Aug 19, 2025 · 34 revisions

Downloads

Psych Engine
Version
Stable Builds Dev Builds Source Code
0.7.1h GitHub Releases Nightly Link Github Repository

FAQ

Here are the most frequently asked questions!

Playing Questions

When downloading a mod from the host the mod re-downloads again and doesn't get recognized by the game!

Check if the host has the same chart path and data and mod directory name

Or the Host should re-verify the mod in the mods menu

How do I import a mod to this engine?

Via the Mod Downloader, installing mods by dragging and dropping modpacks to the mods folder is not recommended and can cause issues.

Can I use EXEcutable mods?

Yes, they will be automatically ported by the engine.

How can I host the game by myself?

Launch the run-server.bat batch file in the same directory where you launch the game, follow the steps to install the required server components and that should launch the server!

The other player should connect to ws://localhost:2567 (if you're playing locally). If you want to expose the server to the internet or just one person then you can use port forwarding tools like Hamachi or Ngrok.

Why do I get blocked from the server? (*.onrender.com Server)

That means the server is down. The server is hosted on a free host (render.com) that puts inactive servers to sleep, when someone wakes up the server by sending something to it the server takes about one and a half minutes to launch again. If the server doesn't respond for longer than 3 minutes then probably the hosting is down.

Compiling Questions

"Unexpected ." Exception

Update Haxe.

"Type not found..." Exception

Make sure to install the proper libraries and versions of them. The libraries and their versions are listed in the hmm.json file. You can use hmm install to install them or manually using HaxeLib command haxelib install <library> <version>. Restarting the OS is recommended after installing all of the libraries.

Mods

Mods are regular Psych Engine mods with a mod_url.txt which tells the other player which URL they should download in order to get that mod! The best way is to get them from the in-game downloader, there you can search GameBanana mods or enter URLs into the search bar and install them directly to the game!
Alternatively, you can do it the old-fashioned way (https://www.youtube.com/watch?v=fHadYFdeYoI) (not recommended!)

Setting URLs for a Mod/Skin

Instructions:

Go to the Setup Mods option in the Online Settings Menu and paste the DIRECT download link into the option labeled after that mod
MEGA links will probably not work!

Upload Sites

Recommended

Not Recommended (or will not work)

  • Discord - Discord attachments can expire.
  • GameBanana - Depending on the server's mood, the download speed can sometimes be slow or decent. If you do upload your skin there please do it only with assets that you've created.

Skins

Skins are Psych Engine characters that are two character datas for both the Boyfriend's side character_name-player and Dad's side character_name.
They can then be bundled in any type of Psych Engine modpack!

Creating Basic Skin / Psych Character

Instructions:

Create a new character inside the editor and make two versions of it, the first should be for the Opponent and the second for the Player.
Important: The Opponent character should be named after your skin and The Player character should have the suffix "-player" after its name.
These two created characters should be placed in the "characters/" directory INSIDE of your newly created modpack.

Important: To make your skin available for other people, upload a zip file with your skin mod-pack inside of it to some cloud storage service, then redownload your skin from the Mod Downloader menu by pasting the URL of that uploaded zip file.

Also, there's a video tutorial on how to make a skin: https://www.youtube.com/watch?v=0XT2vKgB-Aw

The File Hierarchy should look like this.

╚ Psych Online/
 ╚ mods/
  ╚ Skin Mod/
   ╚ characters/
    ╚ characterName.json
    ╚ characterName-player.json
   ╚ images/
    ╚ characters/
     ╚ characterImage.png
     ╚ characterImage.xml
   ╚ mod_url.txt
Online Character Animations!

General

  • taunt for skin taunt animation, if ALT is pressed (in some states), the animation becomes taunt-alt. (Fallbacks to hey)

Results Screen

  • resultsIdle for the "prepare" animation. (Fallbacks to idle)
  • win for the winning animation. (Fallbacks to hey)
  • lose for the winning animation. (Fallbacks to hurt)
  • tie for the tie animation. (Fallbacks to hurt)
  • winLoop for an animation that plays after the win animation.
  • loseLoop for an animation that plays after the lose animation.
  • tieLoop for an animation that plays after the tie animation.

Skin Select

  • spawn for the animation that plays when the "static man" switches to this character.
Adding Character Mixes

Instructions:

To add custom mixes to your character, first you need to create a list of songs that you want to overwrite, so to do that, create a characters_weeks/ folder in your character's mod folder, and then in it, a .json file with the name of your character.

In the characters_weeks/character.json file write:

{
	"songs": [ // list of songs to overwrite
		["YOUR SONG NAME", "LIST OF DIFFICULTY NAMES TO OVERLOAD"], // format
		["Fresh", "Easy,Normal,Hard"], // example use
		["Dad Battle", "Hard"] // remember not to leave a comma in the last item!
	]
}

For reference, this is how Pico's characters_weeks/pico.json looks: (as of 0.11.5)

{
	"songs": [
		["Bopeebo", "Easy,Normal,Hard"],
		["Fresh", "Easy,Normal,Hard"],
		["Dad Battle", "Hard"],
		["Spookeez", "Easy,Normal,Hard"],
		["South", "Easy,Normal,Hard"],
		["Pico", "Easy,Normal,Hard"],
		["Philly Nice", "Easy,Normal,Hard"],
		["Blammed", "Easy,Normal,Hard"],
		["Eggnog", "Easy,Normal,Hard"],
		["Ugh", "Easy,Normal,Hard"],
		["Guns", "Easy,Normal,Hard"]
	]
}

And now, to add song charts and audios, create new song data files like you would normally do in Psych Engine, but after the song name, add a minus sign followed by a prefix of the name of your character. (ex. "fresh-pico")
So for Pico it will look like this:

╚ data/
 ╚ fresh-pico/
  ╚ events.json
  ╚ fresh-pico.json
  ╚ fresh-pico-easy.json
  ╚ fresh-pico-hard.json
╚ songs/
 ╚ fresh-pico/
  ╚ Inst.ogg
  ╚ Voices-Opponent.ogg
  ╚ Voices-Player.ogg

Important: In the chart data, name the songs like the same way you would do with song files, BUT instead of using the minus sign before the prefix, use space. (ex. "Fresh Pico")

Modding API

Here is the documentation for the Psych Online Lua scripting API.

Methods

List:

  • sendMessage(type:String, message:Dynamic):Void

Broadcasts a custom message to all players.

  • sendMessageTo(toSID:String, type:String, message:Dynamic):Void

Send a custom message to a player with toSID id.

  • playsAsBF():Bool

Checks whether or not you play on the right side.

  • isRoomOwner():Bool

Checks whether or not you are the owner of the current room

  • hasRoomPerms():Bool

Checks whether or not you have Host permissions

  • isRoomConnected():Bool

Checks whether or not you are connected to a room
Check this for true before you use the Online API functions!

  • getStateSong():String

Returns the name of the current song, set by a Host

  • getRoomState():Room

Returns the room state object.

  • listPlayers():Array<String>

Returns a list with SIDs of every player.

  • listPlayersBySide(isBf:Bool):Array<String>

Returns a list with SIDs of every player depending on their side.

Returns an object that holds information about your player in the room.

  • getPlayerSelfSID():String

Returns your room SID

Returns an object that holds information about a room player with SID: playerSID in the room.

  • getPlayerAccuracy(playerSID:String):Float

Returns the note accuracy of a room player, between 0 to 100.

  • getPlayerRating(playerSID:String):String

Returns the full combo rating of a room player.

Events

List:

  • onCustomMessage(sid:String, message:Array<2>[type:String, message:Dynamic]):Void

Called when a player with SID: sid sends a custom message to you.

  • onPlayerPing(sid:Float, ping:Int):Either<Void, FunkinLua.Function_Stop>

Called before the score gets updated in your game.

  • onPlayerBotplay(sid:Float, value:Bool):Either<Void, FunkinLua.Function_Stop>

Called before online botplay text gets displayed in your game.

  • onPlayerNoteHold(sid:Float, value:Bool):Either<Void, FunkinLua.Function_Stop>

Called before character.noteHold variable gets updated in your game.

  • onMessageStrumPlay(sid:String, message:Array<3>[anim:String, strumIndex:Int, resetAnim:Bool]):Either<Void, FunkinLua.Function_Stop>

Called before your game registers that a player with SID: sid plays an animation on some strum note.

  • onMessageCharPlay(sid:String, message:Array<3>[anim:String, gfNote:Bool, specialAnim:Bool]):Either<Void, FunkinLua.Function_Stop>

Called before your game registers that a player with SID: sid plays an animation on their character.

  • onMessageNoteHit(sid:String, message:Array<3>[time:Float, noteData:Int, isSustainNote:Bool, ?ratingImage:String, ?noteType:String, ?noteIndex:Int, ?mustPress:Bool]):Either<Void, FunkinLua.Function_Stop>

Called before your game registers that a player with SID: sid hits a note.

  • onMessageNoteMiss(sid:String, message:Array<3>[time:Float, noteData:Int, isSustainNote:Bool]):Either<Void, FunkinLua.Function_Stop>

Called before your game registers that a player with SID: sid misses a note.

  • onMessageStartSong():Either<Void, FunkinLua.Function_Stop>

Called before the game starts the intro countdown.

  • onMessageEndSong():Either<Void, FunkinLua.Function_Stop>

Called before the game ends the song.

  • onRecalculateRatingPlayer(sid:String):Either<Void, FunkinLua.Function_Stop>

Called before the game recalculates the rating of a player with SID: sid.

  • onUpdateScoreTeam(isRight:Bool, miss:Bool):Void

Called after the game updates the score text of a team, if Teams Mode is enabled.

  • onUpdateScorePlayer(sid:String, miss:Bool):Void

Called after the game updates the score text of a player, if Teams Mode is disabled.