<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.jftse.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=XxharCs</id>
	<title>JFTSE Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.jftse.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=XxharCs"/>
	<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php/Special:Contributions/XxharCs"/>
	<updated>2026-05-05T15:30:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Game_Modes&amp;diff=160</id>
		<title>Game Modes</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Game_Modes&amp;diff=160"/>
		<updated>2026-05-04T14:48:53Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: added tournament mode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Game Modes =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Fantasy Tennis featured several different game modes, each offering a different style of play.&lt;br /&gt;
&lt;br /&gt;
The main game modes were Basic Mode, Battle Mode, and Guardian Mode. In addition to these core modes, the game also included Battlemon support, chat-oriented modes such as House Mode, a Quest Mode, and later Club Match in some versions.&lt;br /&gt;
&lt;br /&gt;
Depending on the region and version, the available features could differ slightly, but the overall mode structure remained centered around competitive tennis, combat-based matches, cooperative play, and social side content.&lt;br /&gt;
&lt;br /&gt;
== Single Play Mode ==&lt;br /&gt;
&lt;br /&gt;
== Basic Mode ==&lt;br /&gt;
&lt;br /&gt;
Basic Mode was the standard tennis mode in Fantasy Tennis.&lt;br /&gt;
&lt;br /&gt;
It followed normal tennis rules and could be played in singles or doubles. This mode represented the core competitive gameplay of Fantasy Tennis and was the closest to a traditional tennis match.&lt;br /&gt;
&lt;br /&gt;
Basic Mode focused on movement, positioning, timing, and rally control. For many players, it was the main mode for learning the fundamentals of the game.&lt;br /&gt;
&lt;br /&gt;
== Battle Mode ==&lt;br /&gt;
&lt;br /&gt;
Battle Mode was a more action-oriented variation of the game.&lt;br /&gt;
&lt;br /&gt;
Instead of only playing for points, each side had HP. Missing the ball or taking damage from attacks reduced HP, and the match ended when one side ran out of health. Battle Mode also included items and special attacks, making it much more chaotic than Basic Mode.&lt;br /&gt;
&lt;br /&gt;
This mode gave Fantasy Tennis a more arcade-like identity and was one of the features that made it stand out from a normal tennis game.&lt;br /&gt;
&lt;br /&gt;
== Guardian Mode ==&lt;br /&gt;
&lt;br /&gt;
Guardian Mode was the cooperative PvE mode.&lt;br /&gt;
&lt;br /&gt;
Players could team up and face one or more Guardians, which acted as boss-style enemies. After successful runs, players had a chance to obtain special materials or items, which added a progression element to the mode.&lt;br /&gt;
&lt;br /&gt;
Guardian Mode offered a different pace from the competitive modes and became an important part of the game’s wider progression and replay value.&lt;br /&gt;
&lt;br /&gt;
== Battlemon Mode ==&lt;br /&gt;
&lt;br /&gt;
Battlemons were pet companions that could be used alongside the main match modes.&lt;br /&gt;
&lt;br /&gt;
Historical descriptions indicate that both Basic Mode and Battle Mode could also be played with Battlemons. In practice, this added another layer to the match structure and gave players more variety in how they approached games.&lt;br /&gt;
&lt;br /&gt;
Battlemons were one of the more distinctive features of Fantasy Tennis and helped separate it from more conventional sports games.&lt;br /&gt;
&lt;br /&gt;
== House Mode and Chat ==&lt;br /&gt;
&lt;br /&gt;
Fantasy Tennis also included social spaces outside of normal matches.&lt;br /&gt;
&lt;br /&gt;
Players could communicate in chat areas located on the courts or in House Mode. Houses could be customized with furniture, wallpaper, carpets, and other decorations. Some versions also allowed players to find additional items through activities such as fishing or interacting with objects in the garden.&lt;br /&gt;
&lt;br /&gt;
These features made Fantasy Tennis feel more like a light online world rather than only a menu-based sports game.&lt;br /&gt;
&lt;br /&gt;
== Quest Mode ==&lt;br /&gt;
&lt;br /&gt;
Quest Mode was another part of the game’s side content.&lt;br /&gt;
&lt;br /&gt;
In this mode, players could complete tasks or objectives outside of the standard competitive match structure. While it was not as central as Basic, Battle, or Guardian, it added more variety to the overall game.&lt;br /&gt;
&lt;br /&gt;
== Club Match ==&lt;br /&gt;
&lt;br /&gt;
Club Match was added later in the European version of Fantasy Tennis.&lt;br /&gt;
&lt;br /&gt;
This system allowed clubs to compete against each other in ranked matches. The format included multiple match types such as Basic 1vs1, Basic 2vs2, Battle 1vs1, Battle 2vs2, and Battlemon. Club Match gave organized groups a competitive objective beyond normal matchmaking.&lt;br /&gt;
&lt;br /&gt;
== Tournament Mode ==&lt;br /&gt;
&lt;br /&gt;
This system allowed players to compete against each other by registering to available tournaments. Torunament Mode used a 64 Players bracket system.&lt;br /&gt;
&lt;br /&gt;
== Regional Notes ==&lt;br /&gt;
&lt;br /&gt;
The game first appeared in Korea under the name Fanta Tennis and later had versions in other Asian regions, including Thailand, where it was operated by Ini3. In Europe, the game was released as Fantasy Tennis.&lt;br /&gt;
&lt;br /&gt;
Although region-specific versions could differ in presentation and updates, the identity of the game remained based on a mix of standard tennis, combat-based modes, cooperative play, and social features.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
The game mode structure was one of the defining features of Fantasy Tennis.&lt;br /&gt;
&lt;br /&gt;
Instead of relying on only one type of match, the game offered multiple ways to play:&lt;br /&gt;
* Basic Mode for standard tennis&lt;br /&gt;
* Battle Mode for HP-based action matches&lt;br /&gt;
* Guardian Mode for cooperative PvE&lt;br /&gt;
* Battlemon for pet-supported matches&lt;br /&gt;
* House Mode and chat spaces for social interaction&lt;br /&gt;
* Quest Mode for side content&lt;br /&gt;
* Club Match for organized club competition&lt;br /&gt;
* Tournament Mode for organized player and club competition&lt;br /&gt;
&lt;br /&gt;
This variety helped Fantasy Tennis stand out from more traditional online sports games.&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Beginner%27s_Guide&amp;diff=154</id>
		<title>Beginner&#039;s Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Beginner%27s_Guide&amp;diff=154"/>
		<updated>2026-05-04T14:25:39Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Beginner Guide =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Fantasy Tennis is not a game where most new players should jump straight into competitive modes.&lt;br /&gt;
&lt;br /&gt;
For beginners, the most effective path is usually to start with the tutorial, then spend time in Guardian Mode to level up, get items, and build a stronger character. After that, it becomes much easier to move into Basic and Battle.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
If you are new, start with the tutorial.&lt;br /&gt;
&lt;br /&gt;
The tutorial helps you understand the controls, movement, timing, and the general flow of the game. Skipping it usually only makes the beginning harder.&lt;br /&gt;
&lt;br /&gt;
== Start with Guardian Mode ==&lt;br /&gt;
&lt;br /&gt;
After the tutorial, Guardian Mode is usually the best place for new players to begin.&lt;br /&gt;
&lt;br /&gt;
Guardian is one of the most important modes for early progression. It allows you to level up your character, gain rewards, and collect items that help you become stronger.&lt;br /&gt;
&lt;br /&gt;
If your goal is to compete later in Basic or Battle, Guardian is where that journey usually starts.&lt;br /&gt;
&lt;br /&gt;
== Why Guardian Comes First ==&lt;br /&gt;
&lt;br /&gt;
For many beginners, Basic and Battle can be much harder if they enter too early without levels, items, or experience.&lt;br /&gt;
&lt;br /&gt;
Guardian gives you time to improve your character, get more comfortable with the game, and build a better foundation before moving into more competitive modes.&lt;br /&gt;
&lt;br /&gt;
That is why it usually makes the most sense to focus on Guardian first instead of rushing straight into PvP.&lt;br /&gt;
&lt;br /&gt;
== Tips for Guardian ==&lt;br /&gt;
[[File:Screenshot 2026-05-03 200053.png|thumb|150px|alt=Carnival Pro Coin Gacha|Carnival Pro Coin Gacha]]&lt;br /&gt;
To maximize the rewards from playing Guardian, buy the &amp;quot;Carnival Pro Coin&amp;quot; Gacha with the initial Gold given to new Characters. The droprate of the Gold and EXP rings are greatest in the &amp;quot;Carnival Pro Coin&amp;quot; Gacha. The Gold and EXP rings doubles the rewards (Gold x2 / EXP x2). It is a consumable item, once equipped it will use 1 ring per round.&lt;br /&gt;
[[File:Housing.png|thumb|150px|alt=Housing|Housing]]&lt;br /&gt;
Once you have reached a certain amount of Gold, it is recommended to invest in a House. Houses will provide additional gold and EXP boosts. A Level 1 House gives 30% Bonus to Gold and and EXP and a Level 4 House up to 45%. Before you can level up your house, you have to reach a certain level of Housing points, those and the maximum House bonus can be aquired by buying furniture and filling your House on the Main Screen.&lt;br /&gt;
&lt;br /&gt;
== Basic and Battle ==&lt;br /&gt;
&lt;br /&gt;
Once you have made progress in Guardian, you will be in a much better position to move into Basic and Battle.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Basic&#039;&#039;&#039; is the core competitive tennis experience.&lt;br /&gt;
* &#039;&#039;&#039;Battle&#039;&#039;&#039; is more action-heavy and chaotic.&lt;br /&gt;
* &#039;&#039;&#039;Guardian&#039;&#039;&#039; is the main early progression path.&lt;br /&gt;
&lt;br /&gt;
Basic and Battle make much more sense once you already have some levels, items, and general experience with the game.&lt;br /&gt;
&lt;br /&gt;
== Community and Help ==&lt;br /&gt;
&lt;br /&gt;
Do not be afraid to ask other players for help.&lt;br /&gt;
&lt;br /&gt;
Fantasy Tennis can feel confusing at the beginning, especially when it comes to progression, items, builds, and knowing what to do first. One of the best things you can do as a beginner is connect with other players.&lt;br /&gt;
&lt;br /&gt;
Ask questions in Discord, in game, or anywhere the community is active. Most experienced players would rather answer a simple question than see a new player quit because the game feels overwhelming.&lt;br /&gt;
&lt;br /&gt;
Getting help from other players can make the early game much easier and help you understand the game faster.&lt;br /&gt;
&lt;br /&gt;
== Recommended Progression ==&lt;br /&gt;
&lt;br /&gt;
The simplest beginner path is:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tutorial → Guardian → Basic/Battle&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First learn the game, then build your character in Guardian, and then move into the other modes once you have a stronger foundation.&lt;br /&gt;
&lt;br /&gt;
== Common Beginner Mistakes ==&lt;br /&gt;
&lt;br /&gt;
* Skipping the tutorial&lt;br /&gt;
* Going into Basic or Battle too early&lt;br /&gt;
* Ignoring Guardian progression&lt;br /&gt;
* Overthinking builds too soon&lt;br /&gt;
* Playing too aggressively without understanding the game first&lt;br /&gt;
* Not asking other players for help when confused&lt;br /&gt;
&lt;br /&gt;
== Final Tips ==&lt;br /&gt;
&lt;br /&gt;
If you are completely new to Fantasy Tennis, do the tutorial first and then focus mainly on Guardian Mode.&lt;br /&gt;
&lt;br /&gt;
Use Guardian to level up, collect items, and strengthen your character. Once you have built a better foundation, moving into Basic and Battle will feel much more natural and rewarding.&lt;br /&gt;
&lt;br /&gt;
Also, try to connect with other players. Asking for help in Discord or in game can save you a lot of confusion and help you improve much faster.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Troubleshooting&amp;diff=146</id>
		<title>Troubleshooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Troubleshooting&amp;diff=146"/>
		<updated>2026-05-04T10:01:29Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Troubleshooting &amp;amp; Fixes =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page covers common problems and fixes for Fantasy Tennis.&lt;br /&gt;
&lt;br /&gt;
If the game does not start correctly, shows login errors, disconnects with version-related messages, or lag delay, check the sections below.&lt;br /&gt;
&lt;br /&gt;
== Common Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Old Version Error (4002, -62) ===&lt;br /&gt;
&lt;br /&gt;
If you receive the following message:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You have been disconnected because you tried to connect with an old version.  &lt;br /&gt;
Application will now shut down.  &lt;br /&gt;
(code = 4002, -62)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
as of now, there are 4 common causes for this problem:&lt;br /&gt;
&lt;br /&gt;
* C++ 2015 (x86) is not installed&lt;br /&gt;
* &#039;&#039;&#039;d3dx9_43.dll&#039;&#039;&#039; is missing&lt;br /&gt;
* Windows Firewall, Defender, or antivirus deleted &#039;&#039;&#039;JFTSE.dll&#039;&#039;&#039;&lt;br /&gt;
* The game files are out of date&lt;br /&gt;
&lt;br /&gt;
==== Fix 1: C++ 2015 (x86) is not installed ====&lt;br /&gt;
&lt;br /&gt;
Install the Visual C++ Redistributable (x86):&lt;br /&gt;
&lt;br /&gt;
[https://aka.ms/vs/17/release/vc_redist.x86.exe Download C++ 2015 x86 Redistributable]&lt;br /&gt;
&lt;br /&gt;
==== Fix 2: d3dx9_43.dll is missing ====&lt;br /&gt;
&lt;br /&gt;
If you receive an error saying that &#039;&#039;&#039;d3dx9_43.dll&#039;&#039;&#039; is missing, install the DirectX runtime:&lt;br /&gt;
&lt;br /&gt;
[https://www.microsoft.com/en-us/download/details.aspx?id=35 Download DirectX End-User Runtime]&lt;br /&gt;
&lt;br /&gt;
==== Fix 3: JFTSE.dll was deleted ====&lt;br /&gt;
&lt;br /&gt;
Windows Defender, Firewall, or third-party antivirus software may block, quarantine, or delete &#039;&#039;&#039;JFTSE.dll&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What to do:&#039;&#039;&#039;&lt;br /&gt;
* Check your antivirus quarantine&lt;br /&gt;
* Restore &#039;&#039;&#039;JFTSE.dll&#039;&#039;&#039; if it was removed&lt;br /&gt;
* Add the full game folder to your antivirus or Defender exclusions&lt;br /&gt;
* Make sure the anti-cheat files are not being blocked&lt;br /&gt;
&lt;br /&gt;
==== Fix 4: Files are out of date ====&lt;br /&gt;
&lt;br /&gt;
Always launch the game with:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FT_Launcher.exe&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This will check for updates and download missing or outdated files.&lt;br /&gt;
&lt;br /&gt;
=== User Already Logged In (4002, -2) ===&lt;br /&gt;
&lt;br /&gt;
If you receive the following message:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This user id is currently logged on.  &lt;br /&gt;
Please try again later.  &lt;br /&gt;
(code = 4002, -2)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
then your account is still marked as logged in on the server.&lt;br /&gt;
&lt;br /&gt;
This can happen if the game did not close correctly, the connection was interrupted, or the previous session did not reset properly.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What to do:&#039;&#039;&#039;&lt;br /&gt;
* Wait a few minutes and try again&lt;br /&gt;
* Make sure the game is fully closed&lt;br /&gt;
* Restart the launcher and try again&lt;br /&gt;
* If the problem continues, contact the moderators through &#039;&#039;&#039;#support-ticket&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== This User ID has expired. (4002, -3) ===&lt;br /&gt;
&lt;br /&gt;
If you see this message, your account has not been confirmed yet and access to the game is denied.&lt;br /&gt;
&lt;br /&gt;
For newly registered accounts, you must confirm your account using the registration confirmation email sent by &#039;&#039;&#039;JFTSE Security&#039;&#039;&#039;. This email may appear in your &#039;&#039;&#039;Spam&#039;&#039;&#039; folder.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What to do:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Check the email address you used during registration. Look in your inbox and &#039;&#039;&#039;Spam&#039;&#039;&#039; folder for an email from &#039;&#039;&#039;JFTSE Security&#039;&#039;&#039;, then click the confirmation link inside.&lt;br /&gt;
&lt;br /&gt;
* If you cannot find the confirmation email or the link has expired, request a new registration confirmation email from the website.&lt;br /&gt;
&lt;br /&gt;
* If you used the wrong email address during registration or still cannot receive the email, contact the moderators through &#039;&#039;&#039;#support-ticket&#039;&#039;&#039; and click &#039;&#039;&#039;Create Ticket&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Recommended Fix Order ==&lt;br /&gt;
&lt;br /&gt;
If you are not sure what is causing the issue, try the following in order:&lt;br /&gt;
&lt;br /&gt;
# Install the C++ 2015 (x86) Redistributable&lt;br /&gt;
# Install the DirectX runtime&lt;br /&gt;
# Check whether &#039;&#039;&#039;JFTSE.dll&#039;&#039;&#039; was deleted or quarantined&lt;br /&gt;
# Run &#039;&#039;&#039;FT_Launcher.exe&#039;&#039;&#039;&lt;br /&gt;
# Restart the PC and try again&lt;br /&gt;
# If the account is still marked as logged in, contact &#039;&#039;&#039;@ModMail&#039;&#039;&#039; on Discord&lt;br /&gt;
&lt;br /&gt;
== Mac Users ==&lt;br /&gt;
&lt;br /&gt;
Fantasy Tennis is a Windows game.&lt;br /&gt;
&lt;br /&gt;
Mac users may be able to run the game through &#039;&#039;&#039;Parallels Desktop&#039;&#039;&#039; by installing Windows in a virtual machine.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Possible setup:&#039;&#039;&#039;&lt;br /&gt;
* Install &#039;&#039;&#039;Parallels Desktop&#039;&#039;&#039;&lt;br /&gt;
* Install &#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
* Install Fantasy Tennis inside Windows&lt;br /&gt;
* Run &#039;&#039;&#039;FT_Launcher.exe&#039;&#039;&#039;&lt;br /&gt;
* Start the game from the Windows environment&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
Compatibility may vary depending on the setup, especially with anti-cheat related components.&lt;br /&gt;
&lt;br /&gt;
== Reduce Lag, Delay via Vpn Gamer for South American Players ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notice&#039;&#039;&#039;: This is &#039;&#039;&#039;information of public interest&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Since the JFTSE Fantasy Tennis server is located in &#039;&#039;&#039;Europe&#039;&#039;&#039;, the only way for South Americans to have a direct connection is through a gaming VPN; this is a fact. Although, depending on the region and routes, they may not suffer as much, they can still have an even better experience when trying to play in Europe.&lt;br /&gt;
&lt;br /&gt;
You can try using ExitLag&#039;s paid VPN, which costs $28 dollars for 365 days, and that&#039;s what Is recommended because, in addition to making the connection more stable, it also reduces lag, delay maximum as possible. Or you can use Cloudflare&#039;s with warp free VPN, which offers a significant reduction, although there&#039;s more variation.&lt;br /&gt;
&lt;br /&gt;
First, here are the links to &#039;&#039;&#039;free days to test ExitLag:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[https://www.exitlag.com/pt ExitLag em Português]&lt;br /&gt;
&lt;br /&gt;
[https://www.exitlag.com/es ExitLag en Español]&lt;br /&gt;
&lt;br /&gt;
How to use it? Always open the ExitLag program, search for Fantasy Tennis in the program&#039;s search bar, and select the Automatic Europe route. After applying the routes, then minimize the program and open FT_Launcher to play and enjoy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now cloudflare with warp free vpn:&lt;br /&gt;
&lt;br /&gt;
[https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/ Download the CloudFlare with warp in english]&lt;br /&gt;
&lt;br /&gt;
How to use it? Always open the CloudFlare program, click the gear icon, select the option 1.1.1.1 with warp, and activate it using the large button, then minimize the program and open FT_Launcher to play and enjoy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
[https://www.exitlag.com/en ExitLag English Website]&lt;br /&gt;
ExitLag program works on almost all WORLD including America, Asia, Oceania and Africa. Recommended for windows 10, 11, but take attention windows 7 some players related wont working. Only by testing will you see if it actually improves things for you in practice, as many factors influence the final result of how efficient ExitLag will be for you.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* Do not launch outdated executables directly if &#039;&#039;&#039;FT_Launcher.exe&#039;&#039;&#039; is available&lt;br /&gt;
* If the launcher does not repair the client, reinstall the game files and update again&lt;br /&gt;
* If security software keeps deleting files, create a permanent exclusion for the full game folder&lt;br /&gt;
* If login problems continue, use &#039;&#039;&#039;@ModMail&#039;&#039;&#039; on Discord&lt;br /&gt;
* &#039;&#039;&#039;Discord support: &#039;&#039;&#039;[https://discord.com/invite/YkxTGXwug3 Official Discord Server]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=145</id>
		<title>JFTSE Wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=145"/>
		<updated>2026-05-04T09:49:21Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= JFTSE Wiki =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-size: 16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Please [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account to edit and contribute.&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Wiki is a community driven knowledge base for everything related to &#039;&#039;&#039;JFTSE and Fantasy Tennis&#039;&#039;&#039;. Here you will find guides, tutorials, tips, tricks, and information about gameplay mechanics, server configurations and much more.&lt;br /&gt;
&lt;br /&gt;
This Wiki should be considered a place where community members can create new informative webpages that cover specific topics, &lt;br /&gt;
and where fellow community members can contribute to and improve existing pages.&lt;br /&gt;
&lt;br /&gt;
We strongly believe in the idea that this Wiki should be a free and open method of overlaying information to everyone. Therefore, our stance is that everyone should be able to contribute to this Wiki, as long as the information is accurate and relevant. As a guest, you are free to access and read all the information the Wiki has to offer. As a community member, you are free to contribute to the Wiki by creating new pages, editing existing pages, and discussing the content of the Wiki with other community members as long as you conform to the [[JFTSE Wiki:Community Rules|Community Rules]].&lt;br /&gt;
&lt;br /&gt;
= 📚 Usage And Information =&lt;br /&gt;
=== Information ===&lt;br /&gt;
* [[About_JFTSE|About JFTSE]]&lt;br /&gt;
* [[About_Fantasy_Tennis|About Fantasy Tennis]]&lt;br /&gt;
* [[JFTSE Wiki:Community Rules|Community Rules]]&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
&amp;lt;strong&amp;gt;Only registered JFTSE users can edit pages.&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
To contribute, [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account and help expand the knowledge base!&amp;lt;br&amp;gt;&lt;br /&gt;
Please read and follow the [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] before contributing.&lt;br /&gt;
&lt;br /&gt;
= 🛠 Getting Started =&lt;br /&gt;
* [[Game Lore]] - Dive into the world of Fantasy Tennis.&lt;br /&gt;
* [[Game Installation Guide]] - Step-by-step guide on installing the game.&lt;br /&gt;
* [[Beginner&#039;s Guide]] - Basics of gameplay, controls and UI.&lt;br /&gt;
* [[Gameplay Mechanics]] - Strategies, combos and in-depth gameplay mechanics.&lt;br /&gt;
* [[Troubleshooting|Troubleshooting &amp;amp; Fixes]] - Solutions for common issues.&lt;br /&gt;
&lt;br /&gt;
= 📖 Game Information =&lt;br /&gt;
* [[Characters]] - Information about the characters in Fantasy Tennis.&lt;br /&gt;
* [[Items]] - List of items and their effects.&lt;br /&gt;
* [[Skills]] - List of skills and their effects.&lt;br /&gt;
* [[Maps]] - Learn about the different maps in Fantasy Tennis.&lt;br /&gt;
* [[Game Modes]] - Information about the different game modes.&lt;br /&gt;
* [[Guides &amp;amp; Tutorials]] - Learn tips and tricks from experienced players.&lt;br /&gt;
&lt;br /&gt;
= 📜 Server Information =&lt;br /&gt;
* [[Database Schema &amp;amp; Cheatsheet]] - Database Schema used for Fantasy Tennis &amp;amp; Cheatsheet.&lt;br /&gt;
* [[Server Configuration]] - Information about server configuration.&lt;br /&gt;
* [[Packet Schema (.packet) Format]] - Defines the schema language used to declare and generate network packets.&lt;br /&gt;
&lt;br /&gt;
= 🔗 Useful Links =&lt;br /&gt;
* [https://jftse.com/ JFTSE Website]&lt;br /&gt;
* [https://discord.gg/YkxTGXwug3 Discord]&lt;br /&gt;
* [[Special:RecentChanges|Recent Changes]]&lt;br /&gt;
* [[Special:AllPages|All Pages]]&lt;br /&gt;
* [[Special:Random|Random Page]]&lt;br /&gt;
* [[Special:Categories|Categories]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Game_Installation_Guide&amp;diff=101</id>
		<title>Game Installation Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Game_Installation_Guide&amp;diff=101"/>
		<updated>2026-03-16T15:29:31Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Undo revision 96 by RiggedFish (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== &amp;lt;big&amp;gt;&#039;&#039;&#039;FantaTennis – Steam Deck Compatibility &amp;amp; Setup Guide&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
This entry documents the current working method for running FantaTennis on the Steam Deck. &lt;br /&gt;
&lt;br /&gt;
Due to the game’s launcher, patcher, and anti‑cheat system, it cannot be launched directly through Steam, regardless of Proton version. &lt;br /&gt;
&lt;br /&gt;
The procedure below outlines the reliable way to install, patch, and run the game.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;&#039;&#039;&#039;Overview&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
FantaTennis does not natively support SteamOS or Proton. &lt;br /&gt;
&lt;br /&gt;
The game’s patcher and anti‑cheat fail to initialize when launched through Steam, making Desktop Mode and a Wine frontend (&#039;&#039;Q4Wine&#039;&#039;) mandatory. &lt;br /&gt;
&lt;br /&gt;
Once the initial setup is complete, your settings and input configuration persist, but the game must still be launched through Desktop Mode.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;&#039;&#039;&#039;Prerequisites&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
* Steam Deck running SteamOS (&#039;&#039;current version&#039;&#039;)&lt;br /&gt;
* &lt;br /&gt;
* Desktop Mode access&lt;br /&gt;
* &lt;br /&gt;
* Q4Wine installed&lt;br /&gt;
* &lt;br /&gt;
* FantaTennis JTFSE game files downloaded from the official JTFSE website&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;&amp;lt;big&amp;gt;Installation &amp;amp; First‑Time Setup&amp;lt;/big&amp;gt;&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;1. Switch to Desktop Mode&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Hold the Power Button → select Switch to Desktop.&lt;br /&gt;
* &lt;br /&gt;
* FantaTennis will not launch through Steam, regardless of Proton version.&lt;br /&gt;
* &lt;br /&gt;
* The patcher and anti‑cheat also fail under Steam’s runtime.&lt;br /&gt;
* &lt;br /&gt;
* You must launch the game from Desktop Mode every time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;2. Download the Game&amp;lt;/big&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Download the FantaTennis JTFSE installer from the official JTFSE website.&lt;br /&gt;
* &lt;br /&gt;
* Extract or place the game folder wherever you prefer on your Steam Deck’s storage.&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;3. Install Q4Wine&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
* &lt;br /&gt;
* Open Discover in Desktop Mode.&lt;br /&gt;
* &lt;br /&gt;
* Search for Q4Wine and install it.&lt;br /&gt;
* &lt;br /&gt;
* Q4Wine will serve as the launcher for both the patcher and the game executable.&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;&#039;&#039;&#039;Running the Patcher (&amp;lt;small&amp;gt;&#039;&#039;Mandatory First Step&#039;&#039;&amp;lt;/small&amp;gt;)&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;4. Launch FT_Launcher.exe via Q4Wine&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Open Q4Wine.&lt;br /&gt;
* Add or navigate to the FantaTennis folder.&lt;br /&gt;
* &lt;br /&gt;
* Right‑click FT_Launcher.exe → Run.&lt;br /&gt;
* &lt;br /&gt;
* Open Advanced Options and set:&lt;br /&gt;
 Priority = 0  &lt;br /&gt;
 (This is required for the launcher to behave correctly.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;5. Allow the Patcher to Run&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The launcher will begin downloading and applying patches.&lt;br /&gt;
* &lt;br /&gt;
* Let it complete without interruption.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;6. Do NOT Start the Game After Patching&#039;&#039;&#039;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* When the patcher finishes, do not click any BAT files or the Start button.&lt;br /&gt;
* &lt;br /&gt;
* Starting the game at this stage will cause anti‑cheat issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;7. Close the Patcher&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Once the folder size increases and all patches are applied, close the launcher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;8. Close Q4Wine Completely&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Ensure all Q4Wine sockets/tickets are cleared.&lt;br /&gt;
* &lt;br /&gt;
* Optionally reboot your Steam Deck to guarantee a clean state.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;&#039;&#039;&#039;First Actual Game Launch (&amp;lt;small&amp;gt;&#039;&#039;Required Once&#039;&#039;&amp;lt;/small&amp;gt;)&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;9. Launch FantaTennis.exe via Q4Wine&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Open Q4Wine again and run FantaTennis.exe directly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;10. Set Virtual Desktop Size&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* In the Q4Wine run window, set:&lt;br /&gt;
* &lt;br /&gt;
  Virtual Desktop Size = 1920×1080&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;11. Set Priority&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Under Advanced Options, set:&lt;br /&gt;
&lt;br /&gt;
  Priority = 0&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;12. Confirm Settings&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Click OK to launch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;13. Wait for Anti‑Cheat Initialization&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The anti‑cheat will patch and install required components.&lt;br /&gt;
* &lt;br /&gt;
* This may take a moment; do not interrupt it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;14. Game Launches&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* You can now log in.&lt;br /&gt;
* &lt;br /&gt;
* Adjust your Settings immediately:&lt;br /&gt;
* &lt;br /&gt;
* Configure controls for Steam Deck input instead of keyboard.&lt;br /&gt;
* &lt;br /&gt;
* These settings will persist for future sessions.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;&#039;&#039;&#039;Regular Use After Initial Setup&#039;&#039;&#039;&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;15. Using the Launcher Normally&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* After the first successful launch, you may return to using FT_Launcher.exe.&lt;br /&gt;
* &lt;br /&gt;
* This ensures the game is patched before each session.&lt;br /&gt;
* &lt;br /&gt;
* Once patched, you can launch the game normally through the launcher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;16. Anti‑Cheat Stuck?&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If the game hangs on the anti‑cheat screen after launching from the launcher:&lt;br /&gt;
* &lt;br /&gt;
* Restart your Steam Deck.&lt;br /&gt;
* The anti‑cheat can become stuck and cannot unload itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;17. Recommended Reliable Startup Method&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;For a guaranteed clean launch every time:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Run FT_Launcher.exe first.&lt;br /&gt;
* &lt;br /&gt;
* Let it check and apply patches.&lt;br /&gt;
* &lt;br /&gt;
* Close the launcher completely.&lt;br /&gt;
* &lt;br /&gt;
* Launch FantaTennis.exe directly via Q4Wine (&#039;&#039;same method as the first launch&#039;&#039;).&lt;br /&gt;
* &lt;br /&gt;
&#039;&#039;&#039;This avoids anti‑cheat lockups and ensures consistent startup success.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=100</id>
		<title>Packet Structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=100"/>
		<updated>2026-03-16T15:24:10Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Structure =&lt;br /&gt;
&lt;br /&gt;
All communication between the client and server uses a binary packet format.&lt;br /&gt;
&lt;br /&gt;
Each packet consists of a fixed 8 byte header (metadata) followed by a variable length payload.&lt;br /&gt;
&lt;br /&gt;
== Packet Layout ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Offset   Size   Field&lt;br /&gt;
0x00     2      serialnum&lt;br /&gt;
0x02     2      checksum&lt;br /&gt;
0x04     2      packet id&lt;br /&gt;
0x06     2      data length&lt;br /&gt;
0x08     n      data (payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Header Fields ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| serialnum&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Serial value used by the protocol for packet validation and sequencing.&lt;br /&gt;
|-&lt;br /&gt;
| checksum&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Checksum used by the protocol to verify packet integrity.&lt;br /&gt;
|-&lt;br /&gt;
| packet id&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Identifier that determines the packet type and how the payload should be interpreted.&lt;br /&gt;
|-&lt;br /&gt;
| data length&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Length of the payload (data) in bytes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
The payload immediately follows the header and contains packet specific data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data length = number of bytes following the header&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure of the payload depends entirely on the packetId.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The maximum packet size is limited to &#039;&#039;&#039;16384 bytes&#039;&#039;&#039;.  &lt;br /&gt;
Since the packet header has a fixed size of &#039;&#039;&#039;8 bytes&#039;&#039;&#039;, the remaining &#039;&#039;&#039;16376 bytes&#039;&#039;&#039; are available for payload data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Maximum packet size : 16384 bytes&lt;br /&gt;
Header size         : 8 bytes&lt;br /&gt;
Maximum payload     : 16376 bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Packet ==&lt;br /&gt;
&lt;br /&gt;
The following packet was captured from the server while processing a point update during a match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2026-03-16 14:57:47,231 [epollEventLoopGroup-3-2] PacketLogger [decode] DEBUG RECV [12 bytes]&lt;br /&gt;
CMSGPoint { &amp;quot;id&amp;quot;: &amp;quot;0x183F&amp;quot;, &amp;quot;len&amp;quot;: 4, &amp;quot;data&amp;quot;: { &amp;quot;pointsTeam&amp;quot;: 1, &amp;quot;unk0&amp;quot;: 0, &amp;quot;ballState&amp;quot;: 4, &amp;quot;playerPosition&amp;quot;: 10 } }&lt;br /&gt;
&lt;br /&gt;
--- Hex Dump ---&lt;br /&gt;
B8 79 BF 07 3F 18 04 00    01 00 04 0A&lt;br /&gt;
===&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The total packet size is 12 bytes:&lt;br /&gt;
&lt;br /&gt;
* 8 bytes header&lt;br /&gt;
* 4 bytes payload&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B8 79 -&amp;gt; serialnum&lt;br /&gt;
BF 07 -&amp;gt; checksum&lt;br /&gt;
3F 18 -&amp;gt; packet id (0x183F)&lt;br /&gt;
04 00 -&amp;gt; data length (4 bytes)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
01 00 04 0A&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which the packet parser interprets as:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
! Hex&lt;br /&gt;
|-&lt;br /&gt;
| pointsTeam&lt;br /&gt;
| 1&lt;br /&gt;
| 01&lt;br /&gt;
|-&lt;br /&gt;
| unk0&lt;br /&gt;
| 0&lt;br /&gt;
| 00&lt;br /&gt;
|-&lt;br /&gt;
| ballState&lt;br /&gt;
| 4&lt;br /&gt;
| 04&lt;br /&gt;
|-&lt;br /&gt;
| playerPosition&lt;br /&gt;
| 10&lt;br /&gt;
| 0A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Packet Interpretation ===&lt;br /&gt;
&lt;br /&gt;
From the packet metadata:&lt;br /&gt;
&lt;br /&gt;
* packet id = &#039;&#039;&#039;0x183F&#039;&#039;&#039;&lt;br /&gt;
* payload length = &#039;&#039;&#039;4 bytes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The server maps this packetId to the packet type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMSGPoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The payload is then decoded according to the structure defined for that packet type.&lt;br /&gt;
&lt;br /&gt;
== Byte Order ==&lt;br /&gt;
&lt;br /&gt;
All packet fields are encoded using little-endian byte order.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
17 00 -&amp;gt; 0x0017 -&amp;gt; 23&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet Interface Contract ==&lt;br /&gt;
&lt;br /&gt;
All packets in the server implementation follow the IPacket interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.jftse.server.core.protocol;&lt;br /&gt;
&lt;br /&gt;
public interface IPacket {&lt;br /&gt;
&lt;br /&gt;
    byte[] toBytes();&lt;br /&gt;
&lt;br /&gt;
    char getDataLength();&lt;br /&gt;
&lt;br /&gt;
    char getPacketId();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSerial();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSum();&lt;br /&gt;
&lt;br /&gt;
    String toString();&lt;br /&gt;
&lt;br /&gt;
    // must be implemented by the concrete class for field deserialization&lt;br /&gt;
    static &amp;lt;T extends IPacket&amp;gt; T fromBytes(byte[] packet) {&lt;br /&gt;
        throw new UnsupportedOperationException(&amp;quot;fromBytes method not implemented&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This interface defines the minimal contract required for packet serialization and metadata access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fromBytes(payload)&amp;lt;/code&amp;gt; is called by the Packet Deserializer, a registered packet class must implement it.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Example implementation for CMSG_AuthLogin (auto-generated).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static CMSGAuthLogin fromBytes(byte[] rawData) {&lt;br /&gt;
    CMSGAuthLogin msg = new CMSGAuthLogin();&lt;br /&gt;
    ByteBuffer buffer = ByteBuffer.wrap(rawData).order(ByteOrder.nativeOrder());&lt;br /&gt;
&lt;br /&gt;
    msg.metaData.checkSerial = buffer.getChar(0);&lt;br /&gt;
    msg.metaData.checkSum = buffer.getChar(2);&lt;br /&gt;
    msg.metaData.packetId = buffer.getChar(4);&lt;br /&gt;
    msg.metaData.dataLen = buffer.getChar(6);&lt;br /&gt;
&lt;br /&gt;
    msg.data = new byte[msg.metaData.dataLen];&lt;br /&gt;
    BitKit.blockCopy(rawData, 8, msg.data, 0, msg.metaData.dataLen);&lt;br /&gt;
&lt;br /&gt;
    msg.username = msg.readString();&lt;br /&gt;
    msg.token = msg.readFixedString(16);&lt;br /&gt;
    msg.timestamp = msg.readLong();&lt;br /&gt;
    return msg;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet Schema ==&lt;br /&gt;
&lt;br /&gt;
Packet structures themselves are defined using the &#039;&#039;&#039;[[Packet Schema (.packet) Format]]&#039;&#039;&#039;.  &lt;br /&gt;
These schema files describe the payload layout for each packet id and are used to generate the corresponding packet classes automatically.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=99</id>
		<title>Packet Structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=99"/>
		<updated>2026-03-16T15:23:20Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Structure =&lt;br /&gt;
&lt;br /&gt;
All communication between the client and server uses a binary packet format.&lt;br /&gt;
&lt;br /&gt;
Each packet consists of a fixed 8 byte header (metadata) followed by a variable length payload.&lt;br /&gt;
&lt;br /&gt;
== Packet Layout ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Offset   Size   Field&lt;br /&gt;
0x00     2      serialnum&lt;br /&gt;
0x02     2      checksum&lt;br /&gt;
0x04     2      packet id&lt;br /&gt;
0x06     2      data length&lt;br /&gt;
0x08     n      data (payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Header Fields ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| serialnum&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Serial value used by the protocol for packet validation and sequencing.&lt;br /&gt;
|-&lt;br /&gt;
| checksum&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Checksum used by the protocol to verify packet integrity.&lt;br /&gt;
|-&lt;br /&gt;
| packet id&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Identifier that determines the packet type and how the payload should be interpreted.&lt;br /&gt;
|-&lt;br /&gt;
| data length&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Length of the payload (data) in bytes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
The payload immediately follows the header and contains packet specific data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dataLength = number of bytes following the header&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure of the payload depends entirely on the packetId.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The maximum packet size is limited to &#039;&#039;&#039;16384 bytes&#039;&#039;&#039;.  &lt;br /&gt;
Since the packet header has a fixed size of &#039;&#039;&#039;8 bytes&#039;&#039;&#039;, the remaining &#039;&#039;&#039;16376 bytes&#039;&#039;&#039; are available for payload data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Maximum packet size : 16384 bytes&lt;br /&gt;
Header size         : 8 bytes&lt;br /&gt;
Maximum payload     : 16376 bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Packet ==&lt;br /&gt;
&lt;br /&gt;
The following packet was captured from the server while processing a point update during a match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2026-03-16 14:57:47,231 [epollEventLoopGroup-3-2] PacketLogger [decode] DEBUG RECV [12 bytes]&lt;br /&gt;
CMSGPoint { &amp;quot;id&amp;quot;: &amp;quot;0x183F&amp;quot;, &amp;quot;len&amp;quot;: 4, &amp;quot;data&amp;quot;: { &amp;quot;pointsTeam&amp;quot;: 1, &amp;quot;unk0&amp;quot;: 0, &amp;quot;ballState&amp;quot;: 4, &amp;quot;playerPosition&amp;quot;: 10 } }&lt;br /&gt;
&lt;br /&gt;
--- Hex Dump ---&lt;br /&gt;
B8 79 BF 07 3F 18 04 00    01 00 04 0A&lt;br /&gt;
===&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The total packet size is 12 bytes:&lt;br /&gt;
&lt;br /&gt;
* 8 bytes header&lt;br /&gt;
* 4 bytes payload&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B8 79 -&amp;gt; serialnum&lt;br /&gt;
BF 07 -&amp;gt; checksum&lt;br /&gt;
3F 18 -&amp;gt; packet id (0x183F)&lt;br /&gt;
04 00 -&amp;gt; data length (4 bytes)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
01 00 04 0A&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which the packet parser interprets as:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
! Hex&lt;br /&gt;
|-&lt;br /&gt;
| pointsTeam&lt;br /&gt;
| 1&lt;br /&gt;
| 01&lt;br /&gt;
|-&lt;br /&gt;
| unk0&lt;br /&gt;
| 0&lt;br /&gt;
| 00&lt;br /&gt;
|-&lt;br /&gt;
| ballState&lt;br /&gt;
| 4&lt;br /&gt;
| 04&lt;br /&gt;
|-&lt;br /&gt;
| playerPosition&lt;br /&gt;
| 10&lt;br /&gt;
| 0A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Packet Interpretation ===&lt;br /&gt;
&lt;br /&gt;
From the packet metadata:&lt;br /&gt;
&lt;br /&gt;
* packet id = &#039;&#039;&#039;0x183F&#039;&#039;&#039;&lt;br /&gt;
* payload length = &#039;&#039;&#039;4 bytes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The server maps this packetId to the packet type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMSGPoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The payload is then decoded according to the structure defined for that packet type.&lt;br /&gt;
&lt;br /&gt;
== Byte Order ==&lt;br /&gt;
&lt;br /&gt;
All packet fields are encoded using little-endian byte order.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
17 00 -&amp;gt; 0x0017 -&amp;gt; 23&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet Interface Contract ==&lt;br /&gt;
&lt;br /&gt;
All packets in the server implementation follow the IPacket interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.jftse.server.core.protocol;&lt;br /&gt;
&lt;br /&gt;
public interface IPacket {&lt;br /&gt;
&lt;br /&gt;
    byte[] toBytes();&lt;br /&gt;
&lt;br /&gt;
    char getDataLength();&lt;br /&gt;
&lt;br /&gt;
    char getPacketId();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSerial();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSum();&lt;br /&gt;
&lt;br /&gt;
    String toString();&lt;br /&gt;
&lt;br /&gt;
    // must be implemented by the concrete class for field deserialization&lt;br /&gt;
    static &amp;lt;T extends IPacket&amp;gt; T fromBytes(byte[] packet) {&lt;br /&gt;
        throw new UnsupportedOperationException(&amp;quot;fromBytes method not implemented&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This interface defines the minimal contract required for packet serialization and metadata access.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fromBytes(payload)&amp;lt;/code&amp;gt; is called by the Packet Deserializer, a registered packet class must implement it.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Example implementation for CMSG_AuthLogin (auto-generated).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static CMSGAuthLogin fromBytes(byte[] rawData) {&lt;br /&gt;
    CMSGAuthLogin msg = new CMSGAuthLogin();&lt;br /&gt;
    ByteBuffer buffer = ByteBuffer.wrap(rawData).order(ByteOrder.nativeOrder());&lt;br /&gt;
&lt;br /&gt;
    msg.metaData.checkSerial = buffer.getChar(0);&lt;br /&gt;
    msg.metaData.checkSum = buffer.getChar(2);&lt;br /&gt;
    msg.metaData.packetId = buffer.getChar(4);&lt;br /&gt;
    msg.metaData.dataLen = buffer.getChar(6);&lt;br /&gt;
&lt;br /&gt;
    msg.data = new byte[msg.metaData.dataLen];&lt;br /&gt;
    BitKit.blockCopy(rawData, 8, msg.data, 0, msg.metaData.dataLen);&lt;br /&gt;
&lt;br /&gt;
    msg.username = msg.readString();&lt;br /&gt;
    msg.token = msg.readFixedString(16);&lt;br /&gt;
    msg.timestamp = msg.readLong();&lt;br /&gt;
    return msg;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet Schema ==&lt;br /&gt;
&lt;br /&gt;
Packet structures themselves are defined using the &#039;&#039;&#039;[[Packet Schema (.packet) Format]]&#039;&#039;&#039;.  &lt;br /&gt;
These schema files describe the payload layout for each packet id and are used to generate the corresponding packet classes automatically.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Category:Protocol&amp;diff=98</id>
		<title>Category:Protocol</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Category:Protocol&amp;diff=98"/>
		<updated>2026-03-16T15:07:51Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=97</id>
		<title>Packet Structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Structure&amp;diff=97"/>
		<updated>2026-03-16T15:07:28Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Packet Structure =  All communication between the client and server uses a binary packet format.  Each packet consists of a fixed 8 byte header (metadata) followed by a variable length payload.  == Packet Layout ==  &amp;lt;pre&amp;gt; Offset   Size   Field 0x00     2      checkSerial 0x02     2      checkSum 0x04     2      packetId 0x06     2      dataLength 0x08     n      data (payload) &amp;lt;/pre&amp;gt;  == Header Fields ==  {| class=&amp;quot;wikitable&amp;quot; ! Field ! Size ! Description |- | checkSeri...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Structure =&lt;br /&gt;
&lt;br /&gt;
All communication between the client and server uses a binary packet format.&lt;br /&gt;
&lt;br /&gt;
Each packet consists of a fixed 8 byte header (metadata) followed by a variable length payload.&lt;br /&gt;
&lt;br /&gt;
== Packet Layout ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Offset   Size   Field&lt;br /&gt;
0x00     2      checkSerial&lt;br /&gt;
0x02     2      checkSum&lt;br /&gt;
0x04     2      packetId&lt;br /&gt;
0x06     2      dataLength&lt;br /&gt;
0x08     n      data (payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Header Fields ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| checkSerial&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Serial value used by the protocol for packet validation and sequencing.&lt;br /&gt;
|-&lt;br /&gt;
| checkSum&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Checksum used by the protocol to verify packet integrity.&lt;br /&gt;
|-&lt;br /&gt;
| packetId&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Identifier that determines the packet type and how the payload should be interpreted.&lt;br /&gt;
|-&lt;br /&gt;
| dataLength&lt;br /&gt;
| 2 bytes&lt;br /&gt;
| Length of the payload (data) in bytes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
The payload immediately follows the header and contains packet specific data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dataLength = number of bytes following the header&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure of the payload depends entirely on the packetId.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The maximum packet size is limited to &#039;&#039;&#039;16384 bytes&#039;&#039;&#039;.  &lt;br /&gt;
Since the packet header has a fixed size of &#039;&#039;&#039;8 bytes&#039;&#039;&#039;, the remaining &#039;&#039;&#039;16376 bytes&#039;&#039;&#039; are available for payload data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Maximum packet size : 16384 bytes&lt;br /&gt;
Header size         : 8 bytes&lt;br /&gt;
Maximum payload     : 16376 bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Packet ==&lt;br /&gt;
&lt;br /&gt;
The following packet was captured from the server while processing a point update during a match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2026-03-16 14:57:47,231 [epollEventLoopGroup-3-2] PacketLogger [decode] DEBUG RECV [12 bytes]&lt;br /&gt;
CMSGPoint { &amp;quot;id&amp;quot;: &amp;quot;0x183F&amp;quot;, &amp;quot;len&amp;quot;: 4, &amp;quot;data&amp;quot;: { &amp;quot;pointsTeam&amp;quot;: 1, &amp;quot;unk0&amp;quot;: 0, &amp;quot;ballState&amp;quot;: 4, &amp;quot;playerPosition&amp;quot;: 10 } }&lt;br /&gt;
&lt;br /&gt;
--- Hex Dump ---&lt;br /&gt;
B8 79 BF 07 3F 18 04 00    01 00 04 0A&lt;br /&gt;
===&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The total packet size is 12 bytes:&lt;br /&gt;
&lt;br /&gt;
* 8 bytes header&lt;br /&gt;
* 4 bytes payload&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B8 79 -&amp;gt; checkSerial&lt;br /&gt;
BF 07 -&amp;gt; checkSum&lt;br /&gt;
3F 18 -&amp;gt; packetId (0x183F)&lt;br /&gt;
04 00 -&amp;gt; dataLength (4 bytes)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
01 00 04 0A&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which the packet parser interprets as:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
! Hex&lt;br /&gt;
|-&lt;br /&gt;
| pointsTeam&lt;br /&gt;
| 1&lt;br /&gt;
| 01&lt;br /&gt;
|-&lt;br /&gt;
| unk0&lt;br /&gt;
| 0&lt;br /&gt;
| 00&lt;br /&gt;
|-&lt;br /&gt;
| ballState&lt;br /&gt;
| 4&lt;br /&gt;
| 04&lt;br /&gt;
|-&lt;br /&gt;
| playerPosition&lt;br /&gt;
| 10&lt;br /&gt;
| 0A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Packet Interpretation ===&lt;br /&gt;
&lt;br /&gt;
From the packet metadata:&lt;br /&gt;
&lt;br /&gt;
* packetId = &#039;&#039;&#039;0x183F&#039;&#039;&#039;&lt;br /&gt;
* payload length = &#039;&#039;&#039;4 bytes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The server maps this packetId to the packet type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMSGPoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The payload is then decoded according to the structure defined for that packet type.&lt;br /&gt;
&lt;br /&gt;
== Byte Order ==&lt;br /&gt;
&lt;br /&gt;
All packet fields are encoded using little-endian byte order.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
17 00 -&amp;gt; 0x0017 -&amp;gt; 23&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Packet Interface Contract ==&lt;br /&gt;
&lt;br /&gt;
All packets in the server implementation follow the IPacket interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.jftse.server.core.protocol;&lt;br /&gt;
&lt;br /&gt;
public interface IPacket {&lt;br /&gt;
&lt;br /&gt;
    byte[] toBytes();&lt;br /&gt;
&lt;br /&gt;
    char getDataLength();&lt;br /&gt;
&lt;br /&gt;
    char getPacketId();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSerial();&lt;br /&gt;
&lt;br /&gt;
    char getCheckSum();&lt;br /&gt;
&lt;br /&gt;
    String toString();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This interface defines the minimal contract required for packet serialization and metadata access.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=93</id>
		<title>Packet Schema (.packet) Format</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=93"/>
		<updated>2025-12-18T15:41:14Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Schema (.packet) Format =&lt;br /&gt;
This page explains how to define Fantasy Tennis packets using the schema based &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; format consumed by &amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt;. The generator turns these schema files into Java classes (packets and nested structures), including parsing for client packets and auto writing for server packets.&lt;br /&gt;
&lt;br /&gt;
== Where .packet files live ==&lt;br /&gt;
&amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt; scans a directory tree for files ending in &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;server-core/src/main/packets/&amp;lt;/code&amp;gt;). The folder structure becomes the Java package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.&amp;lt;relative folders...&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server-core/src/main/packets/&lt;br /&gt;
  auth/&lt;br /&gt;
    CMSG_Login.packet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generates classes in:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.auth&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Message blocks ==&lt;br /&gt;
A schema file can contain one or multiple &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; blocks.&lt;br /&gt;
&lt;br /&gt;
=== Packet message (has packet id) ===&lt;br /&gt;
Use this to define an actual network packet (generates a class that implements &amp;lt;code&amp;gt;IPacket&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message CMSG_Login (0xFA1) {&lt;br /&gt;
    string username = 1;&lt;br /&gt;
    string password = 2 [encoding = utf8];&lt;br /&gt;
    int32 version = 3;&lt;br /&gt;
    byte unk0 = 4;&lt;br /&gt;
    string hwid = 5 [encoding = utf8];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;(0x....)&amp;lt;/code&amp;gt; makes it a packet class and sets &amp;lt;code&amp;gt;PACKET_ID&amp;lt;/code&amp;gt;.&lt;br /&gt;
* If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; (case-insensitive), it is treated as a client packet (read/parse from bytes).&lt;br /&gt;
* Otherwise it is treated as a server packet (write/build to bytes).&lt;br /&gt;
&lt;br /&gt;
=== Struct / nested message (no packet id) ===&lt;br /&gt;
Use this to define a reusable structure you can reference as a field type in other messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then use it inside a packet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field syntax ==&lt;br /&gt;
Each field line follows this shape:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[repeated] &amp;lt;type&amp;gt; &amp;lt;name&amp;gt; = &amp;lt;number&amp;gt; [&amp;lt;options&amp;gt;];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 gold = 1;&lt;br /&gt;
repeated int32 itemIds = 2;&lt;br /&gt;
string nickname = 3 [len = 16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field numbering rules (IMPORTANT) ==&lt;br /&gt;
Field numbers are validated strictly:&lt;br /&gt;
&lt;br /&gt;
* Must start at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
* Must be sequential with no gaps (&amp;lt;code&amp;gt;1,2,3,...&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Must not contain duplicates&lt;br /&gt;
&lt;br /&gt;
If you skip a number (or duplicate one), generation fails.&lt;br /&gt;
&lt;br /&gt;
== Reserved field names ==&lt;br /&gt;
Do &#039;&#039;&#039;not&#039;&#039;&#039; use these field names:&lt;br /&gt;
* &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They are reserved internally by the generated packet classes.&lt;br /&gt;
&lt;br /&gt;
== Supported base types ==&lt;br /&gt;
These are recognized and mapped by the generator. Sizes refer to how values are written to / read from the packet payload.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Schema type !! Java type !! Payload representation&lt;br /&gt;
|-&lt;br /&gt;
| int / int32 / uint32 || int || 4 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| long / int64 / uint64 || long || 8 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| short / int16 / uint16 || short || 2 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| char || char || 2 bytes (UTF-16 / Java &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| byte / int8 / uint8 || byte || 1 byte&lt;br /&gt;
|-&lt;br /&gt;
| bool / boolean || boolean || 1 byte (0 = false, 1 = true)&lt;br /&gt;
|-&lt;br /&gt;
| float || float || 4 bytes (IEEE-754, little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| double || double || 8 bytes (IEEE-754, little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| string || String || Variable length, null-terminated (UTF-16LE by default; UTF-8 if specified)&lt;br /&gt;
|-&lt;br /&gt;
| date || java.util.Date || 8 bytes (Windows FILETIME)&lt;br /&gt;
|-&lt;br /&gt;
| bytes || byte[] || Raw byte sequence (length defined by schema)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Anything else is treated as a custom/nested message type (must be defined as &amp;lt;code&amp;gt;message &amp;amp;lt;TypeName&amp;amp;gt; { ... }&amp;lt;/code&amp;gt; somewhere in the scanned schema set).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Notes:&#039;&#039;&lt;br /&gt;
* All numeric values are written using little-endian byte order.&lt;br /&gt;
* &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; corresponds to Java &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; and is always 2 bytes wide.&lt;br /&gt;
* String encoding can be overridden using &amp;lt;code&amp;gt;[encoding=utf8]&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== repeated fields ==&lt;br /&gt;
Use &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; for lists/arrays (except &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt;, which is already a raw byte array).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 values = 1;&lt;br /&gt;
repeated Player players = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How repeated is encoded ===&lt;br /&gt;
By default, repeated fields are encoded as:&lt;br /&gt;
# a count prefix (&#039;&#039;&#039;1 byte&#039;&#039;&#039; by default), then&lt;br /&gt;
# that many elements&lt;br /&gt;
&lt;br /&gt;
On the read side, the count prefix is always read as a single byte unless you force fixed length via &amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the write side, you can control the numeric type used for the count prefix via &amp;lt;code&amp;gt;[type=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
Options go in square brackets:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string name = 1 [len = 16];&lt;br /&gt;
repeated Player players = 2 [type = short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Options are parsed as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key = value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
separated by commas.&lt;br /&gt;
&lt;br /&gt;
=== len (strings, bytes, repeated) ===&lt;br /&gt;
&amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; changes how a field is read/written.&lt;br /&gt;
&lt;br /&gt;
==== string + len ====&lt;br /&gt;
Reads a fixed-length string (UTF-8) of exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string nickname = 1 [len = 16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== bytes + len ====&lt;br /&gt;
Reads exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
bytes payload = 1 [len = 64];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; has no &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt;, it reads “the rest of the packet payload”.&lt;br /&gt;
&lt;br /&gt;
==== repeated + len ====&lt;br /&gt;
Reads a fixed number of elements (no count prefix is consumed on read):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 fixedSet = 1 [len = 10];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic length references (len = msg.&amp;amp;lt;field&amp;amp;gt;) ===&lt;br /&gt;
In addition to constant values, the &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; option may reference a previously read field using the generated packet instance via &amp;lt;code&amp;gt;msg.&amp;amp;lt;fieldName&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This allows defining dynamic-length fields whose size depends on earlier values in the packet payload.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
* The referenced field &#039;&#039;&#039;must appear earlier&#039;&#039;&#039; in the schema.&lt;br /&gt;
* The referenced field must already be fully read when the dynamic field is processed.&lt;br /&gt;
* This is most commonly used with &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; fields.&lt;br /&gt;
* The reference uses the generated packet instance (&amp;lt;code&amp;gt;msg&amp;lt;/code&amp;gt;), not raw schema names.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message CMSG_GuildCreate (0x200B) {&lt;br /&gt;
    string name = 1;&lt;br /&gt;
    string introduction = 2;&lt;br /&gt;
    bool isPublic = 3;&lt;br /&gt;
    byte levelRestriction = 4;&lt;br /&gt;
    byte allowedCharacterTypeCount = 5;&lt;br /&gt;
    repeated byte allowedCharacterType = 6 [len = msg.allowedCharacterTypeCount];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
* &amp;lt;code&amp;gt;allowedCharacterTypeCount&amp;lt;/code&amp;gt; is read first&lt;br /&gt;
* &amp;lt;code&amp;gt;allowedCharacterType&amp;lt;/code&amp;gt; reads exactly that many elements&lt;br /&gt;
* No count prefix is read for the repeated field&lt;br /&gt;
&lt;br /&gt;
==== Notes ====&lt;br /&gt;
* Dynamic references are evaluated at runtime during packet parsing.&lt;br /&gt;
* If the referenced value is invalid or out of bounds, parsing behavior is undefined.&lt;br /&gt;
* Only simple field references are supported (no expressions or calculations).&lt;br /&gt;
&lt;br /&gt;
=== type (size/count prefix control) ===&lt;br /&gt;
&amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; controls the integer type used when writing sizes/counts (and can also force a cast for some primitives).&lt;br /&gt;
&lt;br /&gt;
==== repeated + type ====&lt;br /&gt;
Controls the numeric type used to write the list size:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated Player players = 1 [type = short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This writes &amp;lt;code&amp;gt;(short) players.size()&amp;lt;/code&amp;gt; before the elements.&lt;br /&gt;
&lt;br /&gt;
==== primitive field + type ====&lt;br /&gt;
If you set &amp;lt;code&amp;gt;type=...&amp;lt;/code&amp;gt; on a supported primitive field, the generator will cast when writing. This is useful when the schema expresses a value as &amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt; but the protocol stores it smaller:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 flags = 1 [type = byte];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== encoding=utf8 (strings) ===&lt;br /&gt;
For writing strings:&lt;br /&gt;
* Default writing uses UTF-16LE + &amp;lt;code&amp;gt;0x0000&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
* With &amp;lt;code&amp;gt;[encoding = utf8]&amp;lt;/code&amp;gt; it writes UTF-8 + &amp;lt;code&amp;gt;0x00&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string password = 1 [encoding = utf8];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reading strings:&lt;br /&gt;
* Variable-length &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; is auto-detected by the generated reader (UTF-16LE vs ASCII/UTF-8 style).&lt;br /&gt;
* Fixed-length strings (&amp;lt;code&amp;gt;[len = ...]&amp;lt;/code&amp;gt;) are read as UTF-8 bytes.&lt;br /&gt;
&lt;br /&gt;
== Client vs Server packet behavior ==&lt;br /&gt;
The generator treats packets differently depending on the message name.&lt;br /&gt;
&lt;br /&gt;
=== Client packets (CMSG*) ===&lt;br /&gt;
If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;cmsg&amp;lt;/code&amp;gt;:&lt;br /&gt;
* The generated class registers itself with &amp;lt;code&amp;gt;PacketRegistry&amp;lt;/code&amp;gt; in a static block.&lt;br /&gt;
* &amp;lt;code&amp;gt;fromBytes(...)&amp;lt;/code&amp;gt; parses all defined fields in schema order.&lt;br /&gt;
* A generic &amp;lt;code&amp;gt;read(Class&amp;amp;lt;T&amp;amp;gt;)&amp;lt;/code&amp;gt; API exists plus type-specific read helpers.&lt;br /&gt;
&lt;br /&gt;
These are also included in the generated &amp;lt;code&amp;gt;PacketAutoRegister&amp;lt;/code&amp;gt; list.&lt;br /&gt;
&lt;br /&gt;
=== Server packets (everything else) ===&lt;br /&gt;
For non-&amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; packet messages:&lt;br /&gt;
* The builder’s &amp;lt;code&amp;gt;build()&amp;lt;/code&amp;gt; writes fields into the internal byte buffer automatically (in schema order).&lt;br /&gt;
* &amp;lt;code&amp;gt;toBytes()&amp;lt;/code&amp;gt; returns the full header + payload.&lt;br /&gt;
&lt;br /&gt;
== Nested/composite messages ==&lt;br /&gt;
Any &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; without a packet id becomes a plain Java class with fields, getters/setters, and a builder.&lt;br /&gt;
&lt;br /&gt;
When you reference that message name as a field type inside a packet, the generator writes/reads its subfields in order.&lt;br /&gt;
&lt;br /&gt;
== Full example: Player list packet ==&lt;br /&gt;
This shows nested messages and a repeated composite type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message ClothEquipment {&lt;br /&gt;
    int32 hair = 1;&lt;br /&gt;
    int32 face = 2;&lt;br /&gt;
    int32 dress = 3;&lt;br /&gt;
    int32 pants = 4;&lt;br /&gt;
    int32 socks = 5;&lt;br /&gt;
    int32 shoes = 6;&lt;br /&gt;
    int32 gloves = 7;&lt;br /&gt;
    int32 racket = 8;&lt;br /&gt;
    int32 glasses = 9;&lt;br /&gt;
    int32 bag = 10;&lt;br /&gt;
    int32 hat = 11;&lt;br /&gt;
    int32 dye = 12;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message Player {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    string name = 2;&lt;br /&gt;
    byte level = 3;&lt;br /&gt;
    boolean created = 4;&lt;br /&gt;
    boolean canDelete = 5;&lt;br /&gt;
    int32 gold = 6;&lt;br /&gt;
    byte playerType = 7;&lt;br /&gt;
    byte str = 8;&lt;br /&gt;
    byte sta = 9;&lt;br /&gt;
    byte dex = 10;&lt;br /&gt;
    byte wil = 11;&lt;br /&gt;
    byte statPoints = 12;&lt;br /&gt;
    boolean oldRenameAllowed = 13;&lt;br /&gt;
    boolean renameAllowed = 14;&lt;br /&gt;
    ClothEquipment clothEquipment = 15;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Practical tips / gotchas ==&lt;br /&gt;
* Keep schema field order exactly matching the on wire protocol order. The generator reads/writes strictly in schema order.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;[type = short]&amp;lt;/code&amp;gt; (or another type) on &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; if the protocol’s list length prefix is not 1 byte.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; for raw data blocks; don’t try &amp;lt;code&amp;gt;repeated byte&amp;lt;/code&amp;gt; unless you specifically want a length-prefixed list of bytes.&lt;br /&gt;
* Avoid &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt; as field names.&lt;br /&gt;
* Don’t skip field numbers, generation will fail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=92</id>
		<title>JFTSE Wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=92"/>
		<updated>2025-12-18T15:27:23Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= JFTSE Wiki =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-size: 16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Please [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account to edit and contribute.&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Wiki is a community driven knowledge base for everything related to &#039;&#039;&#039;JFTSE and Fantasy Tennis&#039;&#039;&#039;. Here you will find guides, tutorials, tips, tricks, and information about gameplay mechanics, server configurations and much more.&lt;br /&gt;
&lt;br /&gt;
This Wiki should be considered a place where community members can create new informative webpages that cover specific topics, &lt;br /&gt;
and where fellow community members can contribute to and improve existing pages.&lt;br /&gt;
&lt;br /&gt;
We strongly believe in the idea that this Wiki should be a free and open method of overlaying information to everyone. Therefore, our stance is that everyone should be able to contribute to this Wiki, as long as the information is accurate and relevant. As a guest, you are free to access and read all the information the Wiki has to offer. As a community member, you are free to contribute to the Wiki by creating new pages, editing existing pages, and discussing the content of the Wiki with other community members as long as you conform to the [[JFTSE Wiki:Community Rules|Community Rules]].&lt;br /&gt;
&lt;br /&gt;
= 📚 Usage And Information =&lt;br /&gt;
=== Information ===&lt;br /&gt;
* [[About_JFTSE|About JFTSE]]&lt;br /&gt;
* [[About_Fantasy_Tennis|About Fantasy Tennis]]&lt;br /&gt;
* [[JFTSE Wiki:Community Rules|Community Rules]]&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
&amp;lt;strong&amp;gt;Only registered JFTSE users can edit pages.&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
To contribute, [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account and help expand the knowledge base!&amp;lt;br&amp;gt;&lt;br /&gt;
Please read and follow the [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] before contributing.&lt;br /&gt;
&lt;br /&gt;
= 🛠 Getting Started =&lt;br /&gt;
* [[Game Lore]] - Dive into the world of Fantasy Tennis.&lt;br /&gt;
* [[Game Installation Guide]] - Step-by-step guide on installing the game.&lt;br /&gt;
* [[Beginner&#039;s Guide]] - Basics of gameplay, controls and UI.&lt;br /&gt;
* [[Gameplay Mechanics]] - Strategies, combos and in-depth gameplay mechanics.&lt;br /&gt;
* [[Troubleshooting|Troubleshooting &amp;amp; Fixes]] - Solutions for common issues.&lt;br /&gt;
&lt;br /&gt;
= 📖 Game Information =&lt;br /&gt;
* [[Characters]] - Information about the characters in Fantasy Tennis.&lt;br /&gt;
* [[Items]] - List of items and their effects.&lt;br /&gt;
* [[Skills]] - List of skills and their effects.&lt;br /&gt;
* [[Maps]] - Learn about the different maps in Fantasy Tennis.&lt;br /&gt;
* [[Game Modes]] - Information about the different game modes.&lt;br /&gt;
* [[Guides &amp;amp; Tutorials]] - Learn tips and tricks from experienced players.&lt;br /&gt;
&lt;br /&gt;
= 📜 Server Information =&lt;br /&gt;
* [[Database Schema &amp;amp; Cheatsheet]] - Database Schema used for Fantasy Tennis &amp;amp; Cheatsheet.&lt;br /&gt;
* [[Server Configuration]] - Information about server configuration.&lt;br /&gt;
* [[Packet Schema (.packet) Format]] - Defines the schema language used to declare and generate network packets.&lt;br /&gt;
&lt;br /&gt;
= 🔗 Useful Links =&lt;br /&gt;
* [https://jftse.com/ JFTSE Website]&lt;br /&gt;
* [https://discord.gg/MwamzbMTMy Discord]&lt;br /&gt;
* [[Special:RecentChanges|Recent Changes]]&lt;br /&gt;
* [[Special:AllPages|All Pages]]&lt;br /&gt;
* [[Special:Random|Random Page]]&lt;br /&gt;
* [[Special:Categories|Categories]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=91</id>
		<title>Packet Schema (.packet) Format</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=91"/>
		<updated>2025-12-18T15:24:14Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Schema (.packet) Format =&lt;br /&gt;
This page explains how to define Fantasy Tennis packets using the schema based &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; format consumed by &amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt;. The generator turns these schema files into Java classes (packets and nested structures), including parsing for client packets and auto writing for server packets.&lt;br /&gt;
&lt;br /&gt;
== Where .packet files live ==&lt;br /&gt;
&amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt; scans a directory tree for files ending in &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;server-core/src/main/packets/&amp;lt;/code&amp;gt;). The folder structure becomes the Java package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.&amp;lt;relative folders...&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server-core/src/main/packets/&lt;br /&gt;
  auth/&lt;br /&gt;
    CMSG_Login.packet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generates classes in:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.auth&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Message blocks ==&lt;br /&gt;
A schema file can contain one or multiple &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; blocks.&lt;br /&gt;
&lt;br /&gt;
=== Packet message (has packet id) ===&lt;br /&gt;
Use this to define an actual network packet (generates a class that implements &amp;lt;code&amp;gt;IPacket&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message CMSG_Login (0xFA1) {&lt;br /&gt;
    string username = 1;&lt;br /&gt;
    string password = 2 [encoding = utf8];&lt;br /&gt;
    int32 version = 3;&lt;br /&gt;
    byte unk0 = 4;&lt;br /&gt;
    string hwid = 5 [encoding = utf8];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;(0x....)&amp;lt;/code&amp;gt; makes it a packet class and sets &amp;lt;code&amp;gt;PACKET_ID&amp;lt;/code&amp;gt;.&lt;br /&gt;
* If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; (case-insensitive), it is treated as a client packet (read/parse from bytes).&lt;br /&gt;
* Otherwise it is treated as a server packet (write/build to bytes).&lt;br /&gt;
&lt;br /&gt;
=== Struct / nested message (no packet id) ===&lt;br /&gt;
Use this to define a reusable structure you can reference as a field type in other messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then use it inside a packet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field syntax ==&lt;br /&gt;
Each field line follows this shape:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[repeated] &amp;lt;type&amp;gt; &amp;lt;name&amp;gt; = &amp;lt;number&amp;gt; [&amp;lt;options&amp;gt;];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 gold = 1;&lt;br /&gt;
repeated int32 itemIds = 2;&lt;br /&gt;
string nickname = 3 [len=16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field numbering rules (IMPORTANT) ==&lt;br /&gt;
Field numbers are validated strictly:&lt;br /&gt;
&lt;br /&gt;
* Must start at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
* Must be sequential with no gaps (&amp;lt;code&amp;gt;1,2,3,...&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Must not contain duplicates&lt;br /&gt;
&lt;br /&gt;
If you skip a number (or duplicate one), generation fails.&lt;br /&gt;
&lt;br /&gt;
== Reserved field names ==&lt;br /&gt;
Do &#039;&#039;&#039;not&#039;&#039;&#039; use these field names:&lt;br /&gt;
* &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They are reserved internally by the generated packet classes.&lt;br /&gt;
&lt;br /&gt;
== Supported base types ==&lt;br /&gt;
These are recognized and mapped by the generator. Sizes refer to how values are written to / read from the packet payload.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Schema type !! Java type !! Payload representation&lt;br /&gt;
|-&lt;br /&gt;
| int / int32 / uint32 || int || 4 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| long / int64 / uint64 || long || 8 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| short / int16 / uint16 || short || 2 bytes (little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| char || char || 2 bytes (UTF-16 / Java &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| byte / int8 / uint8 || byte || 1 byte&lt;br /&gt;
|-&lt;br /&gt;
| bool / boolean || boolean || 1 byte (0 = false, 1 = true)&lt;br /&gt;
|-&lt;br /&gt;
| float || float || 4 bytes (IEEE-754, little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| double || double || 8 bytes (IEEE-754, little-endian)&lt;br /&gt;
|-&lt;br /&gt;
| string || String || Variable length, null-terminated (UTF-16LE by default; UTF-8 if specified)&lt;br /&gt;
|-&lt;br /&gt;
| date || java.util.Date || 8 bytes (Windows FILETIME)&lt;br /&gt;
|-&lt;br /&gt;
| bytes || byte[] || Raw byte sequence (length defined by schema)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Anything else is treated as a custom/nested message type (must be defined as &amp;lt;code&amp;gt;message &amp;amp;lt;TypeName&amp;amp;gt; { ... }&amp;lt;/code&amp;gt; somewhere in the scanned schema set).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Notes:&#039;&#039;&lt;br /&gt;
* All numeric values are written using little-endian byte order.&lt;br /&gt;
* &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; corresponds to Java &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; and is always 2 bytes wide.&lt;br /&gt;
* String encoding can be overridden using &amp;lt;code&amp;gt;[encoding=utf8]&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== repeated fields ==&lt;br /&gt;
Use &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; for lists/arrays (except &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt;, which is already a raw byte array).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 values = 1;&lt;br /&gt;
repeated Player players = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How repeated is encoded ===&lt;br /&gt;
By default, repeated fields are encoded as:&lt;br /&gt;
# a count prefix (&#039;&#039;&#039;1 byte&#039;&#039;&#039; by default), then&lt;br /&gt;
# that many elements&lt;br /&gt;
&lt;br /&gt;
On the read side, the count prefix is always read as a single byte unless you force fixed length via &amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the write side, you can control the numeric type used for the count prefix via &amp;lt;code&amp;gt;[type=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
Options go in square brackets:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string name = 1 [len=16];&lt;br /&gt;
repeated Player players = 2 [type=short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Options are parsed as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key = value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
separated by commas.&lt;br /&gt;
&lt;br /&gt;
=== len (strings, bytes, repeated) ===&lt;br /&gt;
&amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; changes how a field is read/written.&lt;br /&gt;
&lt;br /&gt;
==== string + len ====&lt;br /&gt;
Reads a fixed-length string (UTF-8) of exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string nickname = 1 [len=16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== bytes + len ====&lt;br /&gt;
Reads exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
bytes payload = 1 [len=64];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; has no &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt;, it reads “the rest of the packet payload”.&lt;br /&gt;
&lt;br /&gt;
==== repeated + len ====&lt;br /&gt;
Reads a fixed number of elements (no count prefix is consumed on read):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 fixedSet = 1 [len=10];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== type (size/count prefix control) ===&lt;br /&gt;
&amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; controls the integer type used when writing sizes/counts (and can also force a cast for some primitives).&lt;br /&gt;
&lt;br /&gt;
==== repeated + type ====&lt;br /&gt;
Controls the numeric type used to write the list size:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated Player players = 1 [type=short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This writes &amp;lt;code&amp;gt;(short) players.size()&amp;lt;/code&amp;gt; before the elements.&lt;br /&gt;
&lt;br /&gt;
==== primitive field + type ====&lt;br /&gt;
If you set &amp;lt;code&amp;gt;type=...&amp;lt;/code&amp;gt; on a supported primitive field, the generator will cast when writing. This is useful when the schema expresses a value as &amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt; but the protocol stores it smaller:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 flags = 1 [type=byte];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== encoding=utf8 (strings) ===&lt;br /&gt;
For writing strings:&lt;br /&gt;
* Default writing uses UTF-16LE + &amp;lt;code&amp;gt;0x0000&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
* With &amp;lt;code&amp;gt;[encoding=utf8]&amp;lt;/code&amp;gt; it writes UTF-8 + &amp;lt;code&amp;gt;0x00&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string password = 1 [encoding = utf8];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reading strings:&lt;br /&gt;
* Variable-length &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; is auto-detected by the generated reader (UTF-16LE vs ASCII/UTF-8 style).&lt;br /&gt;
* Fixed-length strings (&amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;) are read as UTF-8 bytes.&lt;br /&gt;
&lt;br /&gt;
== Client vs Server packet behavior ==&lt;br /&gt;
The generator treats packets differently depending on the message name.&lt;br /&gt;
&lt;br /&gt;
=== Client packets (CMSG*) ===&lt;br /&gt;
If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;cmsg&amp;lt;/code&amp;gt;:&lt;br /&gt;
* The generated class registers itself with &amp;lt;code&amp;gt;PacketRegistry&amp;lt;/code&amp;gt; in a static block.&lt;br /&gt;
* &amp;lt;code&amp;gt;fromBytes(...)&amp;lt;/code&amp;gt; parses all defined fields in schema order.&lt;br /&gt;
* A generic &amp;lt;code&amp;gt;read(Class&amp;amp;lt;T&amp;amp;gt;)&amp;lt;/code&amp;gt; API exists plus type-specific read helpers.&lt;br /&gt;
&lt;br /&gt;
These are also included in the generated &amp;lt;code&amp;gt;PacketAutoRegister&amp;lt;/code&amp;gt; list.&lt;br /&gt;
&lt;br /&gt;
=== Server packets (everything else) ===&lt;br /&gt;
For non-&amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; packet messages:&lt;br /&gt;
* The builder’s &amp;lt;code&amp;gt;build()&amp;lt;/code&amp;gt; writes fields into the internal byte buffer automatically (in schema order).&lt;br /&gt;
* &amp;lt;code&amp;gt;toBytes()&amp;lt;/code&amp;gt; returns the full header + payload.&lt;br /&gt;
&lt;br /&gt;
== Nested/composite messages ==&lt;br /&gt;
Any &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; without a packet id becomes a plain Java class with fields, getters/setters, and a builder.&lt;br /&gt;
&lt;br /&gt;
When you reference that message name as a field type inside a packet, the generator writes/reads its subfields in order.&lt;br /&gt;
&lt;br /&gt;
== Full example: Player list packet ==&lt;br /&gt;
This shows nested messages and a repeated composite type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message ClothEquipment {&lt;br /&gt;
    int32 hair = 1;&lt;br /&gt;
    int32 face = 2;&lt;br /&gt;
    int32 dress = 3;&lt;br /&gt;
    int32 pants = 4;&lt;br /&gt;
    int32 socks = 5;&lt;br /&gt;
    int32 shoes = 6;&lt;br /&gt;
    int32 gloves = 7;&lt;br /&gt;
    int32 racket = 8;&lt;br /&gt;
    int32 glasses = 9;&lt;br /&gt;
    int32 bag = 10;&lt;br /&gt;
    int32 hat = 11;&lt;br /&gt;
    int32 dye = 12;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message Player {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    string name = 2;&lt;br /&gt;
    byte level = 3;&lt;br /&gt;
    boolean created = 4;&lt;br /&gt;
    boolean canDelete = 5;&lt;br /&gt;
    int32 gold = 6;&lt;br /&gt;
    byte playerType = 7;&lt;br /&gt;
    byte str = 8;&lt;br /&gt;
    byte sta = 9;&lt;br /&gt;
    byte dex = 10;&lt;br /&gt;
    byte wil = 11;&lt;br /&gt;
    byte statPoints = 12;&lt;br /&gt;
    boolean oldRenameAllowed = 13;&lt;br /&gt;
    boolean renameAllowed = 14;&lt;br /&gt;
    ClothEquipment clothEquipment = 15;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Practical tips / gotchas ==&lt;br /&gt;
* Keep schema field order exactly matching the on wire protocol order. The generator reads/writes strictly in schema order.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;[type=short]&amp;lt;/code&amp;gt; (or another type) on &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; if the protocol’s list length prefix is not 1 byte.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; for raw data blocks; don’t try &amp;lt;code&amp;gt;repeated byte&amp;lt;/code&amp;gt; unless you specifically want a length-prefixed list of bytes.&lt;br /&gt;
* Avoid &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt; as field names.&lt;br /&gt;
* Don’t skip field numbers, generation will fail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=90</id>
		<title>Packet Schema (.packet) Format</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Packet_Schema_(.packet)_Format&amp;diff=90"/>
		<updated>2025-12-18T15:10:16Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Packet Schema (.packet) Format = This page explains how to define Fantasy Tennis packets using the schema based &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; format consumed by &amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt;. The generator turns these schema files into Java classes (packets and nested structures), including parsing for client packets and auto writing for server packets.  == Where .packet files live == &amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt; scans a directory tree for files ending in &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;ser...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Packet Schema (.packet) Format =&lt;br /&gt;
This page explains how to define Fantasy Tennis packets using the schema based &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; format consumed by &amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt;. The generator turns these schema files into Java classes (packets and nested structures), including parsing for client packets and auto writing for server packets.&lt;br /&gt;
&lt;br /&gt;
== Where .packet files live ==&lt;br /&gt;
&amp;lt;code&amp;gt;FTPacketGen&amp;lt;/code&amp;gt; scans a directory tree for files ending in &amp;lt;code&amp;gt;.packet&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;server-core/src/main/packets/&amp;lt;/code&amp;gt;). The folder structure becomes the Java package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.&amp;lt;relative folders...&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server-core/src/main/packets/&lt;br /&gt;
  auth/&lt;br /&gt;
    CMSG_Login.packet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generates classes in:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.jftse.server.core.shared.packets.auth&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Message blocks ==&lt;br /&gt;
A schema file can contain one or multiple &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; blocks.&lt;br /&gt;
&lt;br /&gt;
=== Packet message (has packet id) ===&lt;br /&gt;
Use this to define an actual network packet (generates a class that implements &amp;lt;code&amp;gt;IPacket&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message CMSG_Login (0xFA1) {&lt;br /&gt;
    string username = 1;&lt;br /&gt;
    string password = 2 [encoding = utf8];&lt;br /&gt;
    int32 version = 3;&lt;br /&gt;
    byte unk0 = 4;&lt;br /&gt;
    string hwid = 5 [encoding = utf8];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;(0x....)&amp;lt;/code&amp;gt; makes it a packet class and sets &amp;lt;code&amp;gt;PACKET_ID&amp;lt;/code&amp;gt;.&lt;br /&gt;
* If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; (case-insensitive), it is treated as a client packet (read/parse from bytes).&lt;br /&gt;
* Otherwise it is treated as a server packet (write/build to bytes).&lt;br /&gt;
&lt;br /&gt;
=== Struct / nested message (no packet id) ===&lt;br /&gt;
Use this to define a reusable structure you can reference as a field type in other messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then use it inside a packet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field syntax ==&lt;br /&gt;
Each field line follows this shape:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[repeated] &amp;lt;type&amp;gt; &amp;lt;name&amp;gt; = &amp;lt;number&amp;gt; [&amp;lt;options&amp;gt;];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 gold = 1;&lt;br /&gt;
repeated int32 itemIds = 2;&lt;br /&gt;
string nickname = 3 [len=16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field numbering rules (IMPORTANT) ==&lt;br /&gt;
Field numbers are validated strictly:&lt;br /&gt;
&lt;br /&gt;
* Must start at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
* Must be sequential with no gaps (&amp;lt;code&amp;gt;1,2,3,...&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Must not contain duplicates&lt;br /&gt;
&lt;br /&gt;
If you skip a number (or duplicate one), generation fails.&lt;br /&gt;
&lt;br /&gt;
== Reserved field names ==&lt;br /&gt;
Do &#039;&#039;&#039;not&#039;&#039;&#039; use these field names:&lt;br /&gt;
* &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They are reserved internally by the generated packet classes.&lt;br /&gt;
&lt;br /&gt;
== Supported base types ==&lt;br /&gt;
These are recognized and mapped by the generator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Schema type !! Java type&lt;br /&gt;
|-&lt;br /&gt;
| int / int32 / uint32 || int&lt;br /&gt;
|-&lt;br /&gt;
| long / int64 / uint64 || long&lt;br /&gt;
|-&lt;br /&gt;
| short / int16 / uint16 || short&lt;br /&gt;
|-&lt;br /&gt;
| char || char&lt;br /&gt;
|-&lt;br /&gt;
| byte / int8 / uint8 || byte&lt;br /&gt;
|-&lt;br /&gt;
| bool / boolean || boolean&lt;br /&gt;
|-&lt;br /&gt;
| float || float&lt;br /&gt;
|-&lt;br /&gt;
| double || double&lt;br /&gt;
|-&lt;br /&gt;
| string || String&lt;br /&gt;
|-&lt;br /&gt;
| date || java.util.Date&lt;br /&gt;
|-&lt;br /&gt;
| bytes || byte[]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Anything else is treated as a custom/nested message type (must be defined as &amp;lt;code&amp;gt;message &amp;amp;lt;TypeName&amp;amp;gt; { ... }&amp;lt;/code&amp;gt; somewhere in the scanned schema set).&lt;br /&gt;
&lt;br /&gt;
== repeated fields ==&lt;br /&gt;
Use &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; for lists/arrays (except &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt;, which is already a raw byte array).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 values = 1;&lt;br /&gt;
repeated Player players = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How repeated is encoded ===&lt;br /&gt;
By default, repeated fields are encoded as:&lt;br /&gt;
# a count prefix (&#039;&#039;&#039;1 byte&#039;&#039;&#039; by default), then&lt;br /&gt;
# that many elements&lt;br /&gt;
&lt;br /&gt;
On the read side, the count prefix is always read as a single byte unless you force fixed length via &amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the write side, you can control the numeric type used for the count prefix via &amp;lt;code&amp;gt;[type=...]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
Options go in square brackets:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string name = 1 [len=16];&lt;br /&gt;
repeated Player players = 2 [type=short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Options are parsed as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key = value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
separated by commas.&lt;br /&gt;
&lt;br /&gt;
=== len (strings, bytes, repeated) ===&lt;br /&gt;
&amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; changes how a field is read/written.&lt;br /&gt;
&lt;br /&gt;
==== string + len ====&lt;br /&gt;
Reads a fixed-length string (UTF-8) of exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string nickname = 1 [len=16];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== bytes + len ====&lt;br /&gt;
Reads exactly &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt; bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
bytes payload = 1 [len=64];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; has no &amp;lt;code&amp;gt;len&amp;lt;/code&amp;gt;, it reads “the rest of the packet payload”.&lt;br /&gt;
&lt;br /&gt;
==== repeated + len ====&lt;br /&gt;
Reads a fixed number of elements (no count prefix is consumed on read):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated int32 fixedSet = 1 [len=10];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== type (size/count prefix control) ===&lt;br /&gt;
&amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; controls the integer type used when writing sizes/counts (and can also force a cast for some primitives).&lt;br /&gt;
&lt;br /&gt;
==== repeated + type ====&lt;br /&gt;
Controls the numeric type used to write the list size:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
repeated Player players = 1 [type=short];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This writes &amp;lt;code&amp;gt;(short) players.size()&amp;lt;/code&amp;gt; before the elements.&lt;br /&gt;
&lt;br /&gt;
==== primitive field + type ====&lt;br /&gt;
If you set &amp;lt;code&amp;gt;type=...&amp;lt;/code&amp;gt; on a supported primitive field, the generator will cast when writing. This is useful when the schema expresses a value as &amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt; but the protocol stores it smaller:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
int32 flags = 1 [type=byte];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== encoding=utf8 (strings) ===&lt;br /&gt;
For writing strings:&lt;br /&gt;
* Default writing uses UTF-16LE + &amp;lt;code&amp;gt;0x0000&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
* With &amp;lt;code&amp;gt;[encoding=utf8]&amp;lt;/code&amp;gt; it writes UTF-8 + &amp;lt;code&amp;gt;0x00&amp;lt;/code&amp;gt; terminator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
string password = 1 [encoding = utf8];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reading strings:&lt;br /&gt;
* Variable-length &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; is auto-detected by the generated reader (UTF-16LE vs ASCII/UTF-8 style).&lt;br /&gt;
* Fixed-length strings (&amp;lt;code&amp;gt;[len=...]&amp;lt;/code&amp;gt;) are read as UTF-8 bytes.&lt;br /&gt;
&lt;br /&gt;
== Client vs Server packet behavior ==&lt;br /&gt;
The generator treats packets differently depending on the message name.&lt;br /&gt;
&lt;br /&gt;
=== Client packets (CMSG*) ===&lt;br /&gt;
If the message name starts with &amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;cmsg&amp;lt;/code&amp;gt;:&lt;br /&gt;
* The generated class registers itself with &amp;lt;code&amp;gt;PacketRegistry&amp;lt;/code&amp;gt; in a static block.&lt;br /&gt;
* &amp;lt;code&amp;gt;fromBytes(...)&amp;lt;/code&amp;gt; parses all defined fields in schema order.&lt;br /&gt;
* A generic &amp;lt;code&amp;gt;read(Class&amp;amp;lt;T&amp;amp;gt;)&amp;lt;/code&amp;gt; API exists plus type-specific read helpers.&lt;br /&gt;
&lt;br /&gt;
These are also included in the generated &amp;lt;code&amp;gt;PacketAutoRegister&amp;lt;/code&amp;gt; list.&lt;br /&gt;
&lt;br /&gt;
=== Server packets (everything else) ===&lt;br /&gt;
For non-&amp;lt;code&amp;gt;CMSG&amp;lt;/code&amp;gt; packet messages:&lt;br /&gt;
* The builder’s &amp;lt;code&amp;gt;build()&amp;lt;/code&amp;gt; writes fields into the internal byte buffer automatically (in schema order).&lt;br /&gt;
* &amp;lt;code&amp;gt;toBytes()&amp;lt;/code&amp;gt; returns the full header + payload.&lt;br /&gt;
&lt;br /&gt;
== Nested/composite messages ==&lt;br /&gt;
Any &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; without a packet id becomes a plain Java class with fields, getters/setters, and a builder.&lt;br /&gt;
&lt;br /&gt;
When you reference that message name as a field type inside a packet, the generator writes/reads its subfields in order.&lt;br /&gt;
&lt;br /&gt;
== Full example: Player list packet ==&lt;br /&gt;
This shows nested messages and a repeated composite type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
message Account {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    int32 id2 = 2;&lt;br /&gt;
    byte tutorialCount = 3;&lt;br /&gt;
    int32 lastPlayedPlayerId = 4;&lt;br /&gt;
    boolean gameMaster = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message ClothEquipment {&lt;br /&gt;
    int32 hair = 1;&lt;br /&gt;
    int32 face = 2;&lt;br /&gt;
    int32 dress = 3;&lt;br /&gt;
    int32 pants = 4;&lt;br /&gt;
    int32 socks = 5;&lt;br /&gt;
    int32 shoes = 6;&lt;br /&gt;
    int32 gloves = 7;&lt;br /&gt;
    int32 racket = 8;&lt;br /&gt;
    int32 glasses = 9;&lt;br /&gt;
    int32 bag = 10;&lt;br /&gt;
    int32 hat = 11;&lt;br /&gt;
    int32 dye = 12;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message Player {&lt;br /&gt;
    int32 id = 1;&lt;br /&gt;
    string name = 2;&lt;br /&gt;
    byte level = 3;&lt;br /&gt;
    boolean created = 4;&lt;br /&gt;
    boolean canDelete = 5;&lt;br /&gt;
    int32 gold = 6;&lt;br /&gt;
    byte playerType = 7;&lt;br /&gt;
    byte str = 8;&lt;br /&gt;
    byte sta = 9;&lt;br /&gt;
    byte dex = 10;&lt;br /&gt;
    byte wil = 11;&lt;br /&gt;
    byte statPoints = 12;&lt;br /&gt;
    boolean oldRenameAllowed = 13;&lt;br /&gt;
    boolean renameAllowed = 14;&lt;br /&gt;
    ClothEquipment clothEquipment = 15;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
message SMSG_PlayerList (0x1005) {&lt;br /&gt;
    Account account = 1;&lt;br /&gt;
    repeated Player players = 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Practical tips / gotchas ==&lt;br /&gt;
* Keep schema field order exactly matching the on wire protocol order. The generator reads/writes strictly in schema order.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;[type=short]&amp;lt;/code&amp;gt; (or another type) on &amp;lt;code&amp;gt;repeated&amp;lt;/code&amp;gt; if the protocol’s list length prefix is not 1 byte.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt; for raw data blocks; don’t try &amp;lt;code&amp;gt;repeated byte&amp;lt;/code&amp;gt; unless you specifically want a length-prefixed list of bytes.&lt;br /&gt;
* Avoid &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;metaData&amp;lt;/code&amp;gt; as field names.&lt;br /&gt;
* Don’t skip field numbers, generation will fail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Protocol]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=89</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=89"/>
		<updated>2025-08-06T13:18:53Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.max_per_room&#039;&#039;&#039; || int || 10 || Maximum number of fish allowed per room.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.count&#039;&#039;&#039; || int || 4 || Number of fish to spawn initially per spawn location.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.inactivity.timeout&#039;&#039;&#039; || int || 10 || Timeout for inactive fish before despawning (in minutes).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.chance&#039;&#039;&#039; || int || 20 || Chance for fish to spawn at a location (in percent).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.min_time&#039;&#039;&#039; || double || 6.0 || Minimum time between fish spawns (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.max_time&#039;&#039;&#039; || double || 8.0 || Maximum time between fish spawns (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.normal1&#039;&#039;&#039; || double || 2.0 || Standard swimming speed for fish (variant 1).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.normal2&#039;&#039;&#039; || double || 3.0 || Standard swimming speed for fish (variant 2).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.attack&#039;&#039;&#039; || double || 4.0 || Speed used by fish when attacking bait.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.scared&#039;&#039;&#039; || double || 10.0 || Speed used by fish when frightened.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.disengage&#039;&#039;&#039; || double || 10.0 || Speed used by fish when disengaging from bait.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.turning.normal&#039;&#039;&#039; || double || 3.0 || Normal turning speed of fish (in degrees).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.turning.disengage&#039;&#039;&#039; || double || 6.0 || Turning speed during disengagement (in degrees).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.bite.success.chance&#039;&#039;&#039; || int || 40 || Chance for a successful bite once bait is reached (in percent).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.bite.attempt.interval&#039;&#039;&#039; || double || 2.0 || Interval between bite attempts (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.attack&#039;&#039;&#039; || double || 4.0 || Attack radius relative to fish length.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.bait.too_close&#039;&#039;&#039; || double || 6.0 || Distance considered too close to bait to attack (relative to length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.frightened&#039;&#039;&#039; || double || 10.0 || Radius for detecting frightening stimuli (relative to length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.bait.detection&#039;&#039;&#039; || double || 10.0 || Detection radius for bait (relative to fish length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.random_position&#039;&#039;&#039; || double || 10.0 || Maximum distance from spawn point for roaming (5.0 = 1 square).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.movement.chance1&#039;&#039;&#039; || int || 40 || Chance for idle fish to start swimming movement (pattern 1).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.movement.chance2&#039;&#039;&#039; || int || 25 || Chance for idle fish to start swimming movement (pattern 2).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Map_2_Scenarios ===&lt;br /&gt;
Establishes the link between maps (`S_Maps`) and scenarios (`M_Scenarios`). Without defining mappings in this table, the scenario system will not function correctly.&lt;br /&gt;
&lt;br /&gt;
This table uses a many-to-many relationship, ensuring that:&lt;br /&gt;
* Each scenario can be assigned to multiple maps.&lt;br /&gt;
* Each map can be associated with multiple scenarios.&lt;br /&gt;
&lt;br /&gt;
The relationship is defined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Description&lt;br /&gt;
|-&lt;br /&gt;
| `scenario_id` || References `M_Scenarios.id`, linking the scenario.&lt;br /&gt;
|-&lt;br /&gt;
| `map_id` || References `S_Maps.id`, linking the map.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mapping structure allows flexibility, ensuring that game modes can be dynamically adjusted based on the assigned scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines connections between various entities within the game, enabling precise control over item drops, multipliers, and other gameplay mechanics. Relationships are established using two key fields:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;`id_f`&#039;&#039;&#039; (`id_from`): Represents the originating entity of the relationship, such as a Product or Multiplier.&lt;br /&gt;
* &#039;&#039;&#039;`id_t`&#039;&#039;&#039; (`id_to`): Represents the target entity of the relationship, such as a Guardian, Boss Guardian, or Map.&lt;br /&gt;
&lt;br /&gt;
When linking products specifically to guardians, the &#039;&#039;&#039;`productIndex`&#039;&#039;&#039; from the product definition is used for &#039;&#039;&#039;`id_f`&#039;&#039;&#039;, and the &#039;&#039;&#039;`guardian_2_maps.id`&#039;&#039;&#039; (not the direct Guardian or Boss Guardian ID) is used for &#039;&#039;&#039;`id_t`&#039;&#039;&#039;. Each relationship is further described by its type and role, defining how it influences gameplay.&lt;br /&gt;
&lt;br /&gt;
Relationships can be individually toggled on or off via the &#039;&#039;&#039;`status`&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
==== Advanced Item Drop Control (Role ID 1) ====&lt;br /&gt;
Additionally, enhanced item drop control is available specifically for the &#039;&#039;&#039;Item Drop&#039;&#039;&#039; role (role ID &#039;&#039;&#039;1&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
* Default item weight is &#039;&#039;&#039;20.0&#039;&#039;&#039; when no specific weight is provided.&lt;br /&gt;
* A fixed weight of &#039;&#039;&#039;15.0&#039;&#039;&#039; is used to determine scenarios where no item is awarded (displayed as an &amp;quot;X&amp;quot;).&lt;br /&gt;
* Drop exclusivity can be defined specifically for:&lt;br /&gt;
** &#039;&#039;&#039;`forHardMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Hard Mode]].&lt;br /&gt;
** &#039;&#039;&#039;`forRandomMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Random Mode]].&lt;br /&gt;
* The &#039;&#039;&#039;`levelReq`&#039;&#039;&#039; field, currently unused, is reserved for future use to restrict drops based on player levels in a planned progression system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quantity Determination for Item Drops:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Quantity Result&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; is set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; not set || Exact quantity from &#039;&#039;&#039;`qty`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; not set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| All quantity fields &#039;&#039;&#039;NULL&#039;&#039;&#039; || Defaults based on item type:&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039;: Min 1 / Max 3&lt;br /&gt;
* &#039;&#039;&#039;Quick&#039;&#039;&#039;: Min 5 / Max 100&lt;br /&gt;
* &#039;&#039;&#039;Parts &amp;amp; Others&#039;&#039;&#039;: Min 1 / Max 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; both set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines supported relationship types, describing what entities can be linked together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|-&lt;br /&gt;
| 9  || Fishing: Product to Group&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the supported roles that relationships can take, describing their in game functionality:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Fishing Item Drop&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Notes &amp;amp; Additional Information ===&lt;br /&gt;
* The database schema is subject to updates as new mechanics and features are introduced.&lt;br /&gt;
* Some tables may have additional columns not explicitly documented if they are not required for core functionality.&lt;br /&gt;
* Unused fields, such as `levelReq` in `S_Relationships`, are placeholders for future game progression updates.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Commands&amp;diff=88</id>
		<title>Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Commands&amp;diff=88"/>
		<updated>2025-08-06T09:40:36Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ingame Commands =&lt;br /&gt;
&lt;br /&gt;
This page provides a list of available ingame commands for &#039;&#039;&#039;Fantasy Tennis&#039;&#039;&#039; within &#039;&#039;&#039;JFTSE&#039;&#039;&#039;. Commands must be prefixed with a `-` to execute. Some commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== General Commands ==&lt;br /&gt;
These commands can be used by all players.&lt;br /&gt;
&lt;br /&gt;
=== 🎲 Random Mode ===&lt;br /&gt;
[[Guardian Random Mode|Random guardians]] will spawn instead of the default ones (boss remains the same).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-random&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔥 Hard Mode ===&lt;br /&gt;
Enables &#039;&#039;&#039;[[Guardian Hard Mode|Hard Mode]]&#039;&#039;&#039;, increasing enemy stats and spawning additional guardians.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-hard&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Gacha Opening ===&lt;br /&gt;
Opens gachas without animation for faster processing.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Gacha Name&amp;quot; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Western Coin&amp;quot; 50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Note:&amp;lt;/span&amp;gt;&#039;&#039;&#039; Some gachas contain &amp;quot;ll&amp;quot; (e.g., `&amp;quot;Rare Box ll&amp;quot;`), requiring a lowercase `L` in the command.&lt;br /&gt;
&lt;br /&gt;
=== 🏆 Arcade Mode ===&lt;br /&gt;
Enters &#039;&#039;&#039;Arcade Mode&#039;&#039;&#039;. WIP.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-arcade&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Pointback ===&lt;br /&gt;
Allows players to vote for resetting the last point in &#039;&#039;&#039;[[Basic Mode]]&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-pb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;Note:&#039;&#039;&#039; All players must vote using `-pb` before a new point is made.&lt;br /&gt;
&lt;br /&gt;
== GM Commands ==&lt;br /&gt;
These commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 🚫 Player Management ===&lt;br /&gt;
Banning, unbanning, and kicking players.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-ban &amp;lt;player&amp;gt;&lt;br /&gt;
-unban &amp;lt;player&amp;gt;&lt;br /&gt;
-serverKick &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 📝 Server Notice ===&lt;br /&gt;
Sets and broadcasts a &#039;&#039;&#039;server wide notice&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-sN &amp;lt;message&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Reset &amp;amp; Reload ===&lt;br /&gt;
Resets or reloads server data.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rsLogin &amp;lt;player&amp;gt;    # Resets login status&lt;br /&gt;
-reloadScripts       # Reloads all scripts&lt;br /&gt;
-event               # Event configuration&lt;br /&gt;
-reloadFish          # Reloads fish settings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Item &amp;amp; Gift Commands ===&lt;br /&gt;
Used to grant items, experience, or gold to players.&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;another player&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-give &amp;lt;player&amp;gt; &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;yourself&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-get &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send a &#039;&#039;&#039;gift&#039;&#039;&#039; to another player:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-gift &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Help Command ==&lt;br /&gt;
Displays all commands and their description.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-help&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;Notes:&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
* Commands &#039;&#039;&#039;must always start with `-`&#039;&#039;&#039;.&lt;br /&gt;
* Some commands may have additional restrictions (e.g., requiring level 60).&lt;br /&gt;
* GM commands are &#039;&#039;&#039;restricted&#039;&#039;&#039; to authorized users.&lt;br /&gt;
&lt;br /&gt;
For further details, refer to the ingame chat.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=87</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=87"/>
		<updated>2025-08-06T09:35:04Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.max_per_room&#039;&#039;&#039; || int || 10 || Maximum number of fish allowed per room.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.count&#039;&#039;&#039; || int || 4 || Number of fish to spawn initially per spawn location.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.inactivity.timeout&#039;&#039;&#039; || int || 10 || Timeout for inactive fish before despawning (in minutes).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.chance&#039;&#039;&#039; || int || 20 || Chance for fish to spawn at a location (in percent).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.min_time&#039;&#039;&#039; || double || 6.0 || Minimum time between fish spawns (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.spawn.max_time&#039;&#039;&#039; || double || 8.0 || Maximum time between fish spawns (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.normal1&#039;&#039;&#039; || double || 2.0 || Standard swimming speed for fish (variant 1).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.normal2&#039;&#039;&#039; || double || 3.0 || Standard swimming speed for fish (variant 2).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.attack&#039;&#039;&#039; || double || 4.0 || Speed used by fish when attacking bait.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.scared&#039;&#039;&#039; || double || 10.0 || Speed used by fish when frightened.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.disengage&#039;&#039;&#039; || double || 10.0 || Speed used by fish when disengaging from bait.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.turning.normal&#039;&#039;&#039; || double || 3.0 || Normal turning speed of fish (in degrees).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.speed.turning.disengage&#039;&#039;&#039; || double || 6.0 || Turning speed during disengagement (in degrees).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.bite.success.chance&#039;&#039;&#039; || int || 40 || Chance for a successful bite once bait is reached (in percent).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.bite.attempt.interval&#039;&#039;&#039; || double || 2.0 || Interval between bite attempts (in seconds).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.attack&#039;&#039;&#039; || double || 4.0 || Attack radius relative to fish length.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.bait.too_close&#039;&#039;&#039; || double || 6.0 || Distance considered too close to bait to attack (relative to length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.frightened&#039;&#039;&#039; || double || 10.0 || Radius for detecting frightening stimuli (relative to length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.bait.detection&#039;&#039;&#039; || double || 10.0 || Detection radius for bait (relative to fish length).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.radius.random_position&#039;&#039;&#039; || double || 10.0 || Maximum distance from spawn point for roaming (5.0 = 1 square).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.movement.chance1&#039;&#039;&#039; || int || 40 || Chance for idle fish to start swimming movement (pattern 1).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fish.movement.chance2&#039;&#039;&#039; || int || 25 || Chance for idle fish to start swimming movement (pattern 2).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Map_2_Scenarios ===&lt;br /&gt;
Establishes the link between maps (`S_Maps`) and scenarios (`M_Scenarios`). Without defining mappings in this table, the scenario system will not function correctly.&lt;br /&gt;
&lt;br /&gt;
This table uses a many-to-many relationship, ensuring that:&lt;br /&gt;
* Each scenario can be assigned to multiple maps.&lt;br /&gt;
* Each map can be associated with multiple scenarios.&lt;br /&gt;
&lt;br /&gt;
The relationship is defined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Description&lt;br /&gt;
|-&lt;br /&gt;
| `scenario_id` || References `M_Scenarios.id`, linking the scenario.&lt;br /&gt;
|-&lt;br /&gt;
| `map_id` || References `S_Maps.id`, linking the map.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mapping structure allows flexibility, ensuring that game modes can be dynamically adjusted based on the assigned scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines connections between various entities within the game, enabling precise control over item drops, multipliers, and other gameplay mechanics. Relationships are established using two key fields:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;`id_f`&#039;&#039;&#039; (`id_from`): Represents the originating entity of the relationship, such as a Product or Multiplier.&lt;br /&gt;
* &#039;&#039;&#039;`id_t`&#039;&#039;&#039; (`id_to`): Represents the target entity of the relationship, such as a Guardian, Boss Guardian, or Map.&lt;br /&gt;
&lt;br /&gt;
When linking products specifically to guardians, the &#039;&#039;&#039;`productIndex`&#039;&#039;&#039; from the product definition is used for &#039;&#039;&#039;`id_f`&#039;&#039;&#039;, and the &#039;&#039;&#039;`guardian_2_maps.id`&#039;&#039;&#039; (not the direct Guardian or Boss Guardian ID) is used for &#039;&#039;&#039;`id_t`&#039;&#039;&#039;. Each relationship is further described by its type and role, defining how it influences gameplay.&lt;br /&gt;
&lt;br /&gt;
Relationships can be individually toggled on or off via the &#039;&#039;&#039;`status`&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
==== Advanced Item Drop Control (Role ID 1) ====&lt;br /&gt;
Additionally, enhanced item drop control is available specifically for the &#039;&#039;&#039;Item Drop&#039;&#039;&#039; role (role ID &#039;&#039;&#039;1&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
* Default item weight is &#039;&#039;&#039;20.0&#039;&#039;&#039; when no specific weight is provided.&lt;br /&gt;
* A fixed weight of &#039;&#039;&#039;15.0&#039;&#039;&#039; is used to determine scenarios where no item is awarded (displayed as an &amp;quot;X&amp;quot;).&lt;br /&gt;
* Drop exclusivity can be defined specifically for:&lt;br /&gt;
** &#039;&#039;&#039;`forHardMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Hard Mode]].&lt;br /&gt;
** &#039;&#039;&#039;`forRandomMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Random Mode]].&lt;br /&gt;
* The &#039;&#039;&#039;`levelReq`&#039;&#039;&#039; field, currently unused, is reserved for future use to restrict drops based on player levels in a planned progression system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quantity Determination for Item Drops:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Quantity Result&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; is set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; not set || Exact quantity from &#039;&#039;&#039;`qty`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; not set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| All quantity fields &#039;&#039;&#039;NULL&#039;&#039;&#039; || Defaults based on item type:&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039;: Min 1 / Max 3&lt;br /&gt;
* &#039;&#039;&#039;Quick&#039;&#039;&#039;: Min 5 / Max 100&lt;br /&gt;
* &#039;&#039;&#039;Parts &amp;amp; Others&#039;&#039;&#039;: Min 1 / Max 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; both set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines supported relationship types, describing what entities can be linked together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the supported roles that relationships can take, describing their in game functionality:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Notes &amp;amp; Additional Information ===&lt;br /&gt;
* The database schema is subject to updates as new mechanics and features are introduced.&lt;br /&gt;
* Some tables may have additional columns not explicitly documented if they are not required for core functionality.&lt;br /&gt;
* Unused fields, such as `levelReq` in `S_Relationships`, are placeholders for future game progression updates.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=86</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=86"/>
		<updated>2025-07-08T11:53:57Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || &amp;lt;code&amp;gt;FTClient, Room, RoomPlayer&amp;lt;/code&amp;gt; || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || &amp;lt;code&amp;gt;MatchplayGame, Room&amp;lt;/code&amp;gt; || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || &amp;lt;code&amp;gt;MatchplayBasicGame / MatchplayBattleGame / MatchplayGuardianGame, Room, ConcurrentLinkedDeque&amp;amp;lt;FTClient&amp;amp;gt;&amp;lt;/code&amp;gt; || Match ends. Game object can be one of these three&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || &amp;lt;code&amp;gt;FTClient, MatchplayGame, RoomPlayer, Skill, SkillUse, C2SMatchplayUsesSkill&amp;lt;/code&amp;gt; || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || &amp;lt;code&amp;gt;FTClient, SkillCrystal, int randomSkillIndex&amp;lt;/code&amp;gt; || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(1) FTClient, MatchplayGame, Skill&lt;br /&gt;
&lt;br /&gt;
(2) FTConnection, MatchplayGame, short newHealth, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&lt;br /&gt;
(3) FTConnection, MatchplayGame, short newHealth, Skill, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
|| Supports multiple overloads. A target is hit during battle or guardian mode. See [[Event_MP_PLAYER_HITS_TARGET|Event MP_PLAYER_HITS_TARGET]]&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the &amp;quot;Parameters &amp;quot; column, Java &#039;&#039;&#039;types&#039;&#039;&#039; are shown (e.g. &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MatchplayGame&amp;lt;/code&amp;gt;), not variable names.&amp;lt;br&amp;gt;&lt;br /&gt;
This is to help you identify the object classes you can interact with inside your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=85</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=85"/>
		<updated>2025-07-08T11:53:34Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || &amp;lt;code&amp;gt;FTClient, Room, RoomPlayer&amp;lt;/code&amp;gt; || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || &amp;lt;code&amp;gt;FTClient, Room&amp;lt;/code&amp;gt; || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || &amp;lt;code&amp;gt;MatchplayBasicGame / MatchplayBattleGame / MatchplayGuardianGame, Room, ConcurrentLinkedDeque&amp;amp;lt;FTClient&amp;amp;gt;&amp;lt;/code&amp;gt; || Match ends. Game object can be one of these three&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || &amp;lt;code&amp;gt;FTClient, MatchplayGame, RoomPlayer, Skill, SkillUse, C2SMatchplayUsesSkill&amp;lt;/code&amp;gt; || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || &amp;lt;code&amp;gt;FTClient, SkillCrystal, int randomSkillIndex&amp;lt;/code&amp;gt; || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(1) FTClient, MatchplayGame, Skill&lt;br /&gt;
&lt;br /&gt;
(2) FTConnection, MatchplayGame, short newHealth, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&lt;br /&gt;
(3) FTConnection, MatchplayGame, short newHealth, Skill, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
|| Supports multiple overloads. A target is hit during battle or guardian mode. See [[Event_MP_PLAYER_HITS_TARGET|Event MP_PLAYER_HITS_TARGET]]&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the &amp;quot;Parameters &amp;quot; column, Java &#039;&#039;&#039;types&#039;&#039;&#039; are shown (e.g. &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MatchplayGame&amp;lt;/code&amp;gt;), not variable names.&amp;lt;br&amp;gt;&lt;br /&gt;
This is to help you identify the object classes you can interact with inside your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Creating_custom_events&amp;diff=84</id>
		<title>Creating custom events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Creating_custom_events&amp;diff=84"/>
		<updated>2025-07-08T11:10:21Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Scripted Event System =&lt;br /&gt;
&lt;br /&gt;
This page documents how to implement custom in-game event logic using the internal JavaScript scripting system.&lt;br /&gt;
&lt;br /&gt;
All scripts are located in:&lt;br /&gt;
&amp;lt;pre&amp;gt;game-server/src/main/resources/scripts/event&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Files are named as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;amp;lt;ID&amp;amp;gt;_&amp;amp;lt;name&amp;amp;gt;.js&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
* &amp;lt;code&amp;gt;1_exampleEvent.js&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;2_exampleEvent2.js&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;3_weeklyLogin.js&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Registering to an Event ==&lt;br /&gt;
&lt;br /&gt;
Scripts are registered to server events via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    // Runs on player login&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example for match end:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_MATCH_END&amp;quot;, function(game, room, clients) {&lt;br /&gt;
    // Runs when match ends&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The string refers to a constant from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum:&lt;br /&gt;
&amp;lt;pre&amp;gt;com.jftse.emulator.server.core.life.event.GameEventType&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Script Environment ==&lt;br /&gt;
&lt;br /&gt;
The following bindings are available in every script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gameManager&lt;br /&gt;
serviceManager&lt;br /&gt;
threadManager&lt;br /&gt;
eventHandler&lt;br /&gt;
state&lt;br /&gt;
geb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These expose access to game services, event queues, persistent state, and event registration.&lt;br /&gt;
&lt;br /&gt;
== Using Persistent State ==&lt;br /&gt;
&lt;br /&gt;
To save player-specific or global data across restarts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let accountId = client.getAccountId();&lt;br /&gt;
let loginData = JSON.parse(state.get(&amp;quot;loginTracker&amp;quot;, accountId) || &amp;quot;{}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
loginData.lastLogin = new Date().toISOString();&lt;br /&gt;
&lt;br /&gt;
state.set(&amp;quot;loginTracker&amp;quot;, accountId, JSON.stringify(loginData));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows tracking login streaks, cooldowns, event progress, and more.&lt;br /&gt;
&lt;br /&gt;
== Java Class Access ==&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;code&amp;gt;Java.type(...)&amp;lt;/code&amp;gt; to access and work with server-side Java classes directly from your script.  &lt;br /&gt;
This allows you to integrate deeply with server logic, access player data, send packets, schedule tasks, and more.&lt;br /&gt;
&lt;br /&gt;
=== Example: Give gold and send a chat message ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
helper.giveGold(500);&lt;br /&gt;
helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;You received 500 gold!&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Send a room chat packet manually ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let S2CChatRoomAnswerPacket = Java.type(&amp;quot;com.jftse.emulator.server.core.packets.chat.S2CChatRoomAnswerPacket&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let packet = new S2CChatRoomAnswerPacket(2, &amp;quot;Server&amp;quot;, &amp;quot;Welcome!&amp;quot;);&lt;br /&gt;
client.getConnection().sendTCP(packet);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Access services via ServiceManager ===&lt;br /&gt;
You can access any backend service via the pre-bound &amp;lt;code&amp;gt;serviceManager&amp;lt;/code&amp;gt; instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let playerService = serviceManager.getPlayerService();&lt;br /&gt;
let player = playerService.findById(playerId);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Schedule delayed task with EventHandler ===&lt;br /&gt;
Use &amp;lt;code&amp;gt;eventHandler.createRunnableEvent&amp;lt;/code&amp;gt; to run code after a delay (milliseconds):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
&lt;br /&gt;
let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;This message appears after 3 seconds!&amp;quot;);&lt;br /&gt;
}, 3000);&lt;br /&gt;
&lt;br /&gt;
eventHandler.offer(event);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* Only use classes that exist in the current server (game-server or chat-server).&lt;br /&gt;
* Prefer using available bindings like &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gameManager&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;serviceManager&amp;lt;/code&amp;gt; when possible.&lt;br /&gt;
* Combine everything — services, packets, player APIs — to build your own gameplay features.&lt;br /&gt;
&lt;br /&gt;
== Example Scripts ==&lt;br /&gt;
&lt;br /&gt;
These examples demonstrate how to respond to server events using the `geb.on(...)` method in JavaScript. Each file is named using the format `id_name.js` (e.g. `1_exampleEvent.js`) and is auto-loaded from the event script folder if placed there.&lt;br /&gt;
&lt;br /&gt;
=== 1_exampleEvent.js ===&lt;br /&gt;
Send a login greeting to a player using a helper class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
    let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;Welcome back, player!&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2_exampleEvent2.js ===&lt;br /&gt;
Rewards gold and a message to every player in a finished multiplayer match:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_MATCH_END&amp;quot;, function(game, room, clients) {&lt;br /&gt;
    clients.forEach(function(client) {&lt;br /&gt;
        let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.giveGold(200);&lt;br /&gt;
        helper.sendChat(&amp;quot;Match&amp;quot;, &amp;quot;You earned 200 gold for finishing!&amp;quot;);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3_weeklyLogin.js ===&lt;br /&gt;
Tracks login streaks using `state` storage (per account):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function (client) {&lt;br /&gt;
    const accountId = client.getAccountId();&lt;br /&gt;
    const playerId = client.getActivePlayerId();&lt;br /&gt;
    const today = new Date().toISOString().split(&#039;T&#039;)[0];&lt;br /&gt;
&lt;br /&gt;
    if (!accountId || !playerId) return;&lt;br /&gt;
&lt;br /&gt;
    let loginState;&lt;br /&gt;
    try {&lt;br /&gt;
        loginState = JSON.parse(state.get(&amp;quot;weeklyLogin&amp;quot;, accountId) || &amp;quot;{}&amp;quot;);&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        loginState = {};&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    loginState.playerId = loginState.playerId || playerId;&lt;br /&gt;
    loginState.lastLoginDate = loginState.lastLoginDate || null;&lt;br /&gt;
    loginState.loginCount = loginState.loginCount || 0;&lt;br /&gt;
&lt;br /&gt;
    if (loginState.lastLoginDate !== today) {&lt;br /&gt;
        loginState.lastLoginDate = today;&lt;br /&gt;
        loginState.loginCount += 1;&lt;br /&gt;
&lt;br /&gt;
        state.set(&amp;quot;weeklyLogin&amp;quot;, accountId, JSON.stringify(loginState));&lt;br /&gt;
&lt;br /&gt;
        let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.sendChat(&amp;quot;System&amp;quot;, `You&#039;ve logged in ${loginState.loginCount} time(s) this week!`);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4_exampleDelayedEvent.js ===&lt;br /&gt;
Sends a delayed chat message 3 seconds after login:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;This message was delayed by 3 seconds.&amp;quot;);&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    eventHandler.offer(event);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Event Types and Registration ==&lt;br /&gt;
&lt;br /&gt;
To register for events, you call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;EVENT_NAME&amp;quot;, function(...) { ... });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid event names come from the enum:&lt;br /&gt;
&amp;lt;pre&amp;gt;com.jftse.emulator.server.core.life.event.GameEventType&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples include:&lt;br /&gt;
* &amp;lt;code&amp;gt;ON_LOGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LOBBY_JOINED&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MP_MATCH_END&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not all enum values are triggered yet. If an event you need doesn’t fire or seems unsupported:&lt;br /&gt;
* Ask in Discord (`#event-creators-club`)&lt;br /&gt;
* Provide the name you need (e.g. &amp;lt;code&amp;gt;MP_PLAYER_HITS_TARGET&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Describe what data you&#039;d want passed (e.g. &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;score&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;game&amp;lt;/code&amp;gt;, etc.)&lt;br /&gt;
&lt;br /&gt;
The dev team can wire up new events if they make sense.&lt;br /&gt;
&lt;br /&gt;
=== Manually Triggering Events from Script ===&lt;br /&gt;
&lt;br /&gt;
You can also call any other registered event manually inside your script using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.call(&amp;quot;EVENT_NAME&amp;quot;, ...args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is useful for composing logic across multiple scripts, chaining behaviors, or invoking shared logic.  &lt;br /&gt;
The called event must have been previously registered using &amp;lt;code&amp;gt;geb.on(...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    geb.call(&amp;quot;GREET_PLAYER&amp;quot;, client);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
geb.on(&amp;quot;GREET_PLAYER&amp;quot;, function(client) {&lt;br /&gt;
    let helper = new (Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;))(client);&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;Welcome!&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;state.get(...)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;state.set(...)&amp;lt;/code&amp;gt; to persist data per player, account, or globally&lt;br /&gt;
* Validate input: check &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;playerId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;room&amp;lt;/code&amp;gt;, etc. before acting&lt;br /&gt;
* Use &amp;lt;code&amp;gt;eventHandler.createRunnableEvent(...)&amp;lt;/code&amp;gt; to delay code execution&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
    // delayed logic&lt;br /&gt;
}, 3000);&lt;br /&gt;
eventHandler.offer(event);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* You can access Java classes via &amp;lt;code&amp;gt;Java.type(&amp;quot;...&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Stick to one purpose per script — modularity helps with debugging&lt;br /&gt;
* Explore existing scripts and backend source to learn event arguments&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&lt;br /&gt;
Join us in &#039;&#039;&#039;#event-creators-club&#039;&#039;&#039; on Discord.  &lt;br /&gt;
You can share your scripts, get help, request missing events, or propose new scripting features.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=83</id>
		<title>Event MP PLAYER HITS TARGET</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=83"/>
		<updated>2025-07-08T11:08:08Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;MP_PLAYER_HITS_TARGET&#039;&#039;&#039; is one of these events that are called from multiple places with multiple argument count.&lt;br /&gt;
&lt;br /&gt;
Therefore accessing the parameters passed to that event require proper handling to avoid errors.&lt;br /&gt;
&lt;br /&gt;
Currently it is called 3 times in sum:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, ftClient, game, skill); // ftClient might be changed to connection in future&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skillHitsTarget);&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skill, skillHitsTarget);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to register and handle it the following way:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_PLAYER_HITS_TARGET&amp;quot;, function () {&lt;br /&gt;
    switch (arguments.length) {&lt;br /&gt;
        case 3:&lt;br /&gt;
            handleUniqueSkill(arguments[0], arguments[1], arguments[2]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            handleBallLossDamage(arguments[0], arguments[1], arguments[2], arguments[3]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            handleSkillDamage(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);&lt;br /&gt;
        default:&lt;br /&gt;
            logUnexpectedArgs(arguments);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt; is a built-in object in JavaScript functions, especially in non-arrow (&amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt;) style functions. It is implicitly available inside any function declared with the classic &amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt; syntax.&lt;br /&gt;
&lt;br /&gt;
It is:&lt;br /&gt;
* an array-like object&lt;br /&gt;
* holds all the values passed to the function&lt;br /&gt;
* always available in classic functions (not in arrow &amp;lt;code&amp;gt;functions ()=&amp;gt;{}&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=82</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=82"/>
		<updated>2025-07-08T11:06:37Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || &amp;lt;code&amp;gt;FTClient, Room, RoomPlayer&amp;lt;/code&amp;gt; || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || &amp;lt;code&amp;gt;MatchplayBasicGame / MatchplayBattleGame / MatchplayGuardianGame, Room, ConcurrentLinkedDeque&amp;amp;lt;FTClient&amp;amp;gt;&amp;lt;/code&amp;gt; || Match ends. Game object can be one of these three&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || &amp;lt;code&amp;gt;FTClient, MatchplayGame, RoomPlayer, Skill, SkillUse, C2SMatchplayUsesSkill&amp;lt;/code&amp;gt; || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || &amp;lt;code&amp;gt;FTClient, SkillCrystal, int randomSkillIndex&amp;lt;/code&amp;gt; || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(1) FTClient, MatchplayGame, Skill&lt;br /&gt;
&lt;br /&gt;
(2) FTConnection, MatchplayGame, short newHealth, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&lt;br /&gt;
(3) FTConnection, MatchplayGame, short newHealth, Skill, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
|| Supports multiple overloads. A target is hit during battle or guardian mode. See [[Event_MP_PLAYER_HITS_TARGET|Event MP_PLAYER_HITS_TARGET]]&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the &amp;quot;Parameters &amp;quot; column, Java &#039;&#039;&#039;types&#039;&#039;&#039; are shown (e.g. &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MatchplayGame&amp;lt;/code&amp;gt;), not variable names.&amp;lt;br&amp;gt;&lt;br /&gt;
This is to help you identify the object classes you can interact with inside your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=81</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=81"/>
		<updated>2025-07-08T11:03:24Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || ||  &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || &amp;lt;code&amp;gt;FTClient, Room, RoomPlayer&amp;lt;/code&amp;gt; || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || &amp;lt;code&amp;gt;MatchplayBasicGame / MatchplayBattleGame / MatchplayGuardianGame, Room, ConcurrentLinkedDeque&amp;amp;lt;FTClient&amp;amp;gt;&amp;lt;/code&amp;gt; || Match ends. Game object can be one of these three&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || &amp;lt;code&amp;gt;FTClient, MatchplayGame, RoomPlayer, Skill, SkillUse, C2SMatchplayUsesSkill&amp;lt;/code&amp;gt; || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || &amp;lt;code&amp;gt;FTClient, SkillCrystal, int randomSkillIndex&amp;lt;/code&amp;gt; || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(1) FTClient, MatchplayGame, Skill&lt;br /&gt;
&lt;br /&gt;
(2) FTConnection, MatchplayGame, short newHealth, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&lt;br /&gt;
(3) FTConnection, MatchplayGame, short newHealth, Skill, C2SMatchplaySkillHitsTarget&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
|| Supports multiple overloads. A target is hit during battle or guardian mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Parameters !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || &amp;lt;code&amp;gt;long diff&amp;lt;/code&amp;gt; || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt; || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the &amp;quot;Parameters &amp;quot; column, Java &#039;&#039;&#039;types&#039;&#039;&#039; are shown (e.g. &amp;lt;code&amp;gt;FTClient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MatchplayGame&amp;lt;/code&amp;gt;), not variable names.&amp;lt;br&amp;gt;&lt;br /&gt;
This is to help you identify the object classes you can interact with inside your script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=80</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=80"/>
		<updated>2025-07-08T10:34:30Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || Match ends&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || A target is hit during battle or guardian mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=79</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=79"/>
		<updated>2025-07-08T10:31:24Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || Match ends&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || A target is hit during battle or guardian mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ❌ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Legend ==&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Category:Event&amp;diff=78</id>
		<title>Category:Event</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Category:Event&amp;diff=78"/>
		<updated>2025-07-08T10:26:38Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;Category:Scripting&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Category:Scripting&amp;diff=77</id>
		<title>Category:Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Category:Scripting&amp;diff=77"/>
		<updated>2025-07-08T10:26:22Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;Category:Server&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=76</id>
		<title>List of GameEventType Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=List_of_GameEventType_Events&amp;diff=76"/>
		<updated>2025-07-08T10:25:51Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;== List of Events (GameEventType) ==  This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.  All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &amp;#039;&amp;#039;&amp;#039;game server&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;chat server&amp;#039;&amp;#039;&amp;#039; codebase.   These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.  == Game Server Events ==  {| class=&amp;quot;wikitable sortable&amp;quot; ! Event Name !! Called? !! Description |-...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== List of Events (GameEventType) ==&lt;br /&gt;
&lt;br /&gt;
This page lists the currently available events you can hook into using the &amp;lt;code&amp;gt;geb.on(&amp;quot;EVENT_NAME&amp;quot;, ...)&amp;lt;/code&amp;gt; function from JavaScript.&lt;br /&gt;
&lt;br /&gt;
All events come from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum in either the &#039;&#039;&#039;game server&#039;&#039;&#039; or &#039;&#039;&#039;chat server&#039;&#039;&#039; codebase.  &lt;br /&gt;
These are used in event scripts placed inside &amp;lt;code&amp;gt;scripts/event/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Game Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ✅ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_INIT_HP || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_DAMAGE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_POINT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| CHALLENGE_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| EMBLEM_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ENCHANT_ON_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_ENCHANT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| GACHA_OPENED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| RECIPE_COMBINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| INVENTORY_ITEM_TIME_EXPIRED || ❌ || Time-based item expired&lt;br /&gt;
|-&lt;br /&gt;
| ON_PLAYER_ANNOUNCE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| PLAYER_QUICK_SLOT_USE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_JOINED || ❌ || Player entered the lobby&lt;br /&gt;
|-&lt;br /&gt;
| LOBBY_LEFT || ❌ || Player left the lobby&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LOBBY_JOINED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_CREATED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_JOINED || ❌ || Player joined a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_LEFT || ❌ || Player left a room&lt;br /&gt;
|-&lt;br /&gt;
| ROOM_POSITION_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ROOM_MAP_CHANGED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_RELAY_CONNECTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_TRIGGERED || ✅ || After skipping the match intro, this is called before Player stats are sent to the client&lt;br /&gt;
|-&lt;br /&gt;
| MP_GAME_ANIM_SKIP_END || ✅ || Skipping match intro finished and is called right before guardian serve in battle or guardian mode, or serve in basic mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_START || ❌ || Match begins&lt;br /&gt;
|-&lt;br /&gt;
| MP_MATCH_END || ✅ || Match ends&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_USE_SKILL || ✅ || A skill was used&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_PICKING_UP_CRYSTAL || ✅ || Player crystal pickup&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_HITS_TARGET || ✅ || A target is hit during battle or guardian mode&lt;br /&gt;
|-&lt;br /&gt;
| MP_PLAYER_SWAP_QUICK_SLOT_ITEMS || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_MAINTENANCE_REQUESTED || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_SHOP_LOAD_PREPARE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| SHOP_ITEM_BOUGHT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_INIT || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| TUTORIAL_FINISH || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_DEV_PACKET || ❌ || Developer-only test packet&lt;br /&gt;
|-&lt;br /&gt;
| SESSION_TIME_UPDATE || ❌ || &lt;br /&gt;
|-&lt;br /&gt;
| ON_HEARTBEAT || ❌ || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Chat Server Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Event Name !! Called? !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ON_TICK || ✅ || Called on every server tick&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGIN || ❌ || Player logs in&lt;br /&gt;
|-&lt;br /&gt;
| ON_LOGOUT || ❌ || Player logs out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
;✅ : Event is currently called (triggered by the server)&lt;br /&gt;
;❌ : Event exists but is not currently triggered&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Don&#039;t see your needed event called yet?&#039;&#039;  &lt;br /&gt;
→ You can still write scripts using them and ask for the event to be wired on Discord.  &lt;br /&gt;
Include the event name and what parameters your handler expects.&lt;br /&gt;
&lt;br /&gt;
== Event Lists ==&lt;br /&gt;
* [[#Game Server Events|Game Server]]&lt;br /&gt;
* [[#Chat Server Events|Chat Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=75</id>
		<title>Event MP PLAYER HITS TARGET</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=75"/>
		<updated>2025-07-08T09:45:37Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;MP_PLAYER_HITS_TARGET&#039;&#039;&#039; is one of these events that are called from multiple places with multiple argument count.&lt;br /&gt;
&lt;br /&gt;
Therefore accessing the parameters passed to that event require proper handling to avoid errors.&lt;br /&gt;
&lt;br /&gt;
Currently it is called 3 times in sum:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, ftClient, game, skill); // ftClient might be changed to connection in future&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skillHitsTarget);&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skill, skillHitsTarget);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to register and handle it the following way:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_PLAYER_HITS_TARGET&amp;quot;, function () {&lt;br /&gt;
    switch (arguments.length) {&lt;br /&gt;
        case 3:&lt;br /&gt;
            handleUniqueSkill(arguments[0], arguments[1], arguments[2]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            handleBallLossDamage(arguments[0], arguments[1], arguments[2], arguments[3]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            handleSkillDamage(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);&lt;br /&gt;
        default:&lt;br /&gt;
            logUnexpectedArgs(arguments);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt; is a built-in object in JavaScript functions, especially in non-arrow (&amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt;) style functions. It is implicitly available inside any function declared with the classic &amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt; syntax.&lt;br /&gt;
&lt;br /&gt;
It is:&lt;br /&gt;
* an array-like object&lt;br /&gt;
* holds all the values passed to the function&lt;br /&gt;
* always available in classic functions (not in arrow &amp;lt;code&amp;gt;functions ()=&amp;gt;{}&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category:Event]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=74</id>
		<title>Event MP PLAYER HITS TARGET</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=74"/>
		<updated>2025-07-08T09:45:07Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;MP_PLAYER_HITS_TARGET&#039;&#039;&#039; is one of these events that are called from multiple places with multiple argument count.&lt;br /&gt;
&lt;br /&gt;
Therefore accessing the parameters passed to that event require proper handling to avoid errors.&lt;br /&gt;
&lt;br /&gt;
Currently it is called 3 times in sum:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, ftClient, game, skill); // ftClient might be changed to connection in future&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skillHitsTarget);&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skill, skillHitsTarget);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to register and handle it the following way:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_PLAYER_HITS_TARGET&amp;quot;, function () {&lt;br /&gt;
    switch (arguments.length) {&lt;br /&gt;
        case 3:&lt;br /&gt;
            handleUniqueSkill(arguments[0], arguments[1], arguments[2]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            handleBallLossDamage(arguments[0], arguments[1], arguments[2], arguments[3]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            handleSkillDamage(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);&lt;br /&gt;
        default:&lt;br /&gt;
            logUnexpectedArgs(arguments);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt; is a built-in object in JavaScript functions, especially in non-arrow (&amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt;) style functions. It is implicitly available inside any function declared with the classic &amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt; syntax.&lt;br /&gt;
&lt;br /&gt;
It is:&lt;br /&gt;
* an array-like object&lt;br /&gt;
* holds all the values passed to the function&lt;br /&gt;
* always available in classic functions (not in arrow &amp;lt;code&amp;gt;functions ()=&amp;gt;{}&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=73</id>
		<title>Event MP PLAYER HITS TARGET</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Event_MP_PLAYER_HITS_TARGET&amp;diff=73"/>
		<updated>2025-07-08T09:44:43Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Event MP_PLAYER_HITS_TARGET =  &amp;#039;&amp;#039;&amp;#039;MP_PLAYER_HITS_TARGET&amp;#039;&amp;#039;&amp;#039; is one of these events that are called from multiple places with multiple argument count.  Therefore accessing the parameters passed to that event require proper handling to avoid errors.  Currently it is called 3 times in sum: &amp;lt;pre&amp;gt; GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, ftClient, game, skill); // ftClient might be changed to connection in future GameEventBus.call(GameEventType.MP_PLAYER_HITS_T...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Event MP_PLAYER_HITS_TARGET =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MP_PLAYER_HITS_TARGET&#039;&#039;&#039; is one of these events that are called from multiple places with multiple argument count.&lt;br /&gt;
&lt;br /&gt;
Therefore accessing the parameters passed to that event require proper handling to avoid errors.&lt;br /&gt;
&lt;br /&gt;
Currently it is called 3 times in sum:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, ftClient, game, skill); // ftClient might be changed to connection in future&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skillHitsTarget);&lt;br /&gt;
GameEventBus.call(GameEventType.MP_PLAYER_HITS_TARGET, connection, game, newHealth, skill, skillHitsTarget);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to register and handle it the following way:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_PLAYER_HITS_TARGET&amp;quot;, function () {&lt;br /&gt;
    switch (arguments.length) {&lt;br /&gt;
        case 3:&lt;br /&gt;
            handleUniqueSkill(arguments[0], arguments[1], arguments[2]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            handleBallLossDamage(arguments[0], arguments[1], arguments[2], arguments[3]);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            handleSkillDamage(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);&lt;br /&gt;
        default:&lt;br /&gt;
            logUnexpectedArgs(arguments);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt; is a built-in object in JavaScript functions, especially in non-arrow (&amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt;) style functions. It is implicitly available inside any function declared with the classic &amp;lt;code&amp;gt;function (...) {}&amp;lt;/code&amp;gt; syntax.&lt;br /&gt;
&lt;br /&gt;
It is:&lt;br /&gt;
* an array-like object&lt;br /&gt;
* holds all the values passed to the function&lt;br /&gt;
* always available in classic functions (not in arrow &amp;lt;code&amp;gt;functions ()=&amp;gt;{}&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Creating_custom_events&amp;diff=72</id>
		<title>Creating custom events</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Creating_custom_events&amp;diff=72"/>
		<updated>2025-07-07T11:32:41Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Scripted Event System =  This page documents how to implement custom in-game event logic using the internal JavaScript scripting system.  All scripts are located in: &amp;lt;pre&amp;gt;game-server/src/main/resources/scripts/event&amp;lt;/pre&amp;gt;  Files are named as: &amp;lt;pre&amp;gt;&amp;amp;lt;ID&amp;amp;gt;_&amp;amp;lt;name&amp;amp;gt;.js&amp;lt;/pre&amp;gt; Example: * &amp;lt;code&amp;gt;1_exampleEvent.js&amp;lt;/code&amp;gt; * &amp;lt;code&amp;gt;2_exampleEvent2.js&amp;lt;/code&amp;gt; * &amp;lt;code&amp;gt;3_weeklyLogin.js&amp;lt;/code&amp;gt;  == Registering to an Event ==  Scripts are registered to server events via: &amp;lt;pre&amp;gt; g...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Scripted Event System =&lt;br /&gt;
&lt;br /&gt;
This page documents how to implement custom in-game event logic using the internal JavaScript scripting system.&lt;br /&gt;
&lt;br /&gt;
All scripts are located in:&lt;br /&gt;
&amp;lt;pre&amp;gt;game-server/src/main/resources/scripts/event&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Files are named as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;amp;lt;ID&amp;amp;gt;_&amp;amp;lt;name&amp;amp;gt;.js&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
* &amp;lt;code&amp;gt;1_exampleEvent.js&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;2_exampleEvent2.js&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;3_weeklyLogin.js&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Registering to an Event ==&lt;br /&gt;
&lt;br /&gt;
Scripts are registered to server events via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    // Runs on player login&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example for match end:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_MATCH_END&amp;quot;, function(game, room, clients) {&lt;br /&gt;
    // Runs when match ends&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The string refers to a constant from the &amp;lt;code&amp;gt;GameEventType&amp;lt;/code&amp;gt; enum:&lt;br /&gt;
&amp;lt;pre&amp;gt;com.jftse.emulator.server.core.life.event.GameEventType&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Script Environment ==&lt;br /&gt;
&lt;br /&gt;
The following bindings are available in every script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gameManager&lt;br /&gt;
serviceManager&lt;br /&gt;
threadManager&lt;br /&gt;
eventHandler&lt;br /&gt;
state&lt;br /&gt;
geb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These expose access to game services, event queues, persistent state, and event registration.&lt;br /&gt;
&lt;br /&gt;
== Using Persistent State ==&lt;br /&gt;
&lt;br /&gt;
To save player-specific or global data across restarts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let accountId = client.getAccountId();&lt;br /&gt;
let loginData = JSON.parse(state.get(&amp;quot;loginTracker&amp;quot;, accountId) || &amp;quot;{}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
loginData.lastLogin = new Date().toISOString();&lt;br /&gt;
&lt;br /&gt;
state.set(&amp;quot;loginTracker&amp;quot;, accountId, JSON.stringify(loginData));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows tracking login streaks, cooldowns, event progress, and more.&lt;br /&gt;
&lt;br /&gt;
== Java Class Access ==&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;code&amp;gt;Java.type(...)&amp;lt;/code&amp;gt; to access and work with server-side Java classes directly from your script.  &lt;br /&gt;
This allows you to integrate deeply with server logic, access player data, send packets, schedule tasks, and more.&lt;br /&gt;
&lt;br /&gt;
=== Example: Give gold and send a chat message ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
helper.giveGold(500);&lt;br /&gt;
helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;You received 500 gold!&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Send a room chat packet manually ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let S2CChatRoomAnswerPacket = Java.type(&amp;quot;com.jftse.emulator.server.core.packets.chat.S2CChatRoomAnswerPacket&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let packet = new S2CChatRoomAnswerPacket(2, &amp;quot;Server&amp;quot;, &amp;quot;Welcome!&amp;quot;);&lt;br /&gt;
client.getConnection().sendTCP(packet);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Access services via ServiceManager ===&lt;br /&gt;
You can access any backend service via the pre-bound &amp;lt;code&amp;gt;serviceManager&amp;lt;/code&amp;gt; instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let playerService = serviceManager.getPlayerService();&lt;br /&gt;
let player = playerService.findById(playerId);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example: Schedule delayed task with EventHandler ===&lt;br /&gt;
Use &amp;lt;code&amp;gt;eventHandler.createRunnableEvent&amp;lt;/code&amp;gt; to run code after a delay (milliseconds):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
&lt;br /&gt;
let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;This message appears after 3 seconds!&amp;quot;);&lt;br /&gt;
}, 3000);&lt;br /&gt;
&lt;br /&gt;
eventHandler.offer(event);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* Only use classes that exist in the current server (game-server or chat-server).&lt;br /&gt;
* Prefer using available bindings like &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gameManager&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;serviceManager&amp;lt;/code&amp;gt; when possible.&lt;br /&gt;
* Combine everything — services, packets, player APIs — to build your own gameplay features.&lt;br /&gt;
&lt;br /&gt;
== Example Scripts ==&lt;br /&gt;
&lt;br /&gt;
These examples demonstrate how to respond to server events using the `geb.on(...)` method in JavaScript. Each file is named using the format `id_name.js` (e.g. `1_exampleEvent.js`) and is auto-loaded from the event script folder if placed there.&lt;br /&gt;
&lt;br /&gt;
=== 1_exampleEvent.js ===&lt;br /&gt;
Send a login greeting to a player using a helper class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
    let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;Welcome back, player!&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2_exampleEvent2.js ===&lt;br /&gt;
Rewards gold and a message to every player in a finished multiplayer match:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;MP_MATCH_END&amp;quot;, function(game, room, clients) {&lt;br /&gt;
    clients.forEach(function(client) {&lt;br /&gt;
        let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.giveGold(200);&lt;br /&gt;
        helper.sendChat(&amp;quot;Match&amp;quot;, &amp;quot;You earned 200 gold for finishing!&amp;quot;);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3_weeklyLogin.js ===&lt;br /&gt;
Tracks login streaks using `state` storage (per account):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function (client) {&lt;br /&gt;
    const accountId = client.getAccountId();&lt;br /&gt;
    const playerId = client.getActivePlayerId();&lt;br /&gt;
    const today = new Date().toISOString().split(&#039;T&#039;)[0];&lt;br /&gt;
&lt;br /&gt;
    if (!accountId || !playerId) return;&lt;br /&gt;
&lt;br /&gt;
    let loginState;&lt;br /&gt;
    try {&lt;br /&gt;
        loginState = JSON.parse(state.get(&amp;quot;weeklyLogin&amp;quot;, accountId) || &amp;quot;{}&amp;quot;);&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        loginState = {};&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    loginState.playerId = loginState.playerId || playerId;&lt;br /&gt;
    loginState.lastLoginDate = loginState.lastLoginDate || null;&lt;br /&gt;
    loginState.loginCount = loginState.loginCount || 0;&lt;br /&gt;
&lt;br /&gt;
    if (loginState.lastLoginDate !== today) {&lt;br /&gt;
        loginState.lastLoginDate = today;&lt;br /&gt;
        loginState.loginCount += 1;&lt;br /&gt;
&lt;br /&gt;
        state.set(&amp;quot;weeklyLogin&amp;quot;, accountId, JSON.stringify(loginState));&lt;br /&gt;
&lt;br /&gt;
        let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.sendChat(&amp;quot;System&amp;quot;, `You&#039;ve logged in ${loginState.loginCount} time(s) this week!`);&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4_exampleDelayedEvent.js ===&lt;br /&gt;
Sends a delayed chat message 3 seconds after login:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    let PlayerScriptableImpl = Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
        let helper = new PlayerScriptableImpl(client);&lt;br /&gt;
        helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;This message was delayed by 3 seconds.&amp;quot;);&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    eventHandler.offer(event);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Event Types and Registration ==&lt;br /&gt;
&lt;br /&gt;
To register for events, you call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;EVENT_NAME&amp;quot;, function(...) { ... });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid event names come from the enum:&lt;br /&gt;
&amp;lt;pre&amp;gt;com.jftse.emulator.server.core.life.event.GameEventType&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples include:&lt;br /&gt;
* &amp;lt;code&amp;gt;ON_LOGIN&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LOBBY_JOINED&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MP_MATCH_END&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not all enum values are triggered yet. If an event you need doesn’t fire or seems unsupported:&lt;br /&gt;
* Ask in Discord (`#event-creators-club`)&lt;br /&gt;
* Provide the name you need (e.g. &amp;lt;code&amp;gt;MP_PLAYER_HITS_TARGET&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Describe what data you&#039;d want passed (e.g. &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;score&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;game&amp;lt;/code&amp;gt;, etc.)&lt;br /&gt;
&lt;br /&gt;
The dev team can wire up new events if they make sense.&lt;br /&gt;
&lt;br /&gt;
=== Manually Triggering Events from Script ===&lt;br /&gt;
&lt;br /&gt;
You can also call any other registered event manually inside your script using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.call(&amp;quot;EVENT_NAME&amp;quot;, ...args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is useful for composing logic across multiple scripts, chaining behaviors, or invoking shared logic.  &lt;br /&gt;
The called event must have been previously registered using &amp;lt;code&amp;gt;geb.on(...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
geb.on(&amp;quot;ON_LOGIN&amp;quot;, function(client) {&lt;br /&gt;
    geb.call(&amp;quot;GREET_PLAYER&amp;quot;, client);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
geb.on(&amp;quot;GREET_PLAYER&amp;quot;, function(client) {&lt;br /&gt;
    let helper = new (Java.type(&amp;quot;com.jftse.emulator.server.core.interaction.PlayerScriptableImpl&amp;quot;))(client);&lt;br /&gt;
    helper.sendChat(&amp;quot;System&amp;quot;, &amp;quot;Welcome!&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
* Use &amp;lt;code&amp;gt;state.get(...)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;state.set(...)&amp;lt;/code&amp;gt; to persist data per player, account, or globally&lt;br /&gt;
* Validate input: check &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;playerId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;room&amp;lt;/code&amp;gt;, etc. before acting&lt;br /&gt;
* Use &amp;lt;code&amp;gt;eventHandler.createRunnableEvent(...)&amp;lt;/code&amp;gt; to delay code execution&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let event = eventHandler.createRunnableEvent(function () {&lt;br /&gt;
    // delayed logic&lt;br /&gt;
}, 3000);&lt;br /&gt;
eventHandler.offer(event);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* You can access Java classes via &amp;lt;code&amp;gt;Java.type(&amp;quot;...&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Stick to one purpose per script — modularity helps with debugging&lt;br /&gt;
* Explore existing scripts and backend source to learn event arguments&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&lt;br /&gt;
Join us in &#039;&#039;&#039;#event-creators-club&#039;&#039;&#039; on Discord.  &lt;br /&gt;
You can share your scripts, get help, request missing events, or propose new scripting features.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Fixing_SQL_Import_Script_Errors&amp;diff=71</id>
		<title>Fixing SQL Import Script Errors</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Fixing_SQL_Import_Script_Errors&amp;diff=71"/>
		<updated>2025-02-26T11:41:34Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Fixing SQL Import Script Errors =  == Overview ==  When running the `import_sql.sh` script to import SQL files into the database, you might encounter errors related to missing `Guardian` and `BossGuardian` entries.    This happens because certain event maps reference Guardian entries that do not exist in the default SQL files provided by [https://github.com/sstokic-tgm/JFTSE/tree/master/scripts/sql JFTSE]. These missing definitions are a result of JFTSE-specific config...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Fixing SQL Import Script Errors =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
When running the `import_sql.sh` script to import SQL files into the database, you might encounter errors related to missing `Guardian` and `BossGuardian` entries.  &lt;br /&gt;
&lt;br /&gt;
This happens because certain event maps reference Guardian entries that do not exist in the default SQL files provided by [https://github.com/sstokic-tgm/JFTSE/tree/master/scripts/sql JFTSE]. These missing definitions are a result of JFTSE-specific configurations that differ from the original Fantasy Tennis setup.&lt;br /&gt;
&lt;br /&gt;
== How to Fix ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to resolve this issue:&lt;br /&gt;
&lt;br /&gt;
=== 1. Modifying SQL Files Before Import ===&lt;br /&gt;
&lt;br /&gt;
If the import fails due to missing Guardian entries, you can manually edit the affected SQL files. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps:&#039;&#039;&#039;&lt;br /&gt;
# Open the SQL file that failed during the import.&lt;br /&gt;
# Locate and remove any `INSERT` statements that reference missing Guardian or BossGuardian entries.&lt;br /&gt;
# Save the file and delete any partial entries from the database that were created before the failure.&lt;br /&gt;
# Re-run the `import_sql.sh` script to import the cleaned SQL files.&lt;br /&gt;
&lt;br /&gt;
This approach prevents invalid data from being inserted and ensures the script runs smoothly.&lt;br /&gt;
&lt;br /&gt;
=== 2. Adding Missing Entries Manually ===&lt;br /&gt;
&lt;br /&gt;
If you prefer to retain all Guardian entries referenced in the event maps, you can manually add the missing records to the database. Below are the required `INSERT` statements for Guardian and BossGuardian entries:&lt;br /&gt;
If you choose this method, make sure to restart the SQL import after executing these statements.&lt;br /&gt;
&lt;br /&gt;
==== Missing Guardian and BossGuardian entries ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- Additional Guardian entries for event maps&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(73, 1, 8, 1, 1, 165, 45, 110, 120, 26, 15000, 55, 50, &#039;No. 1&#039;, 200, 200, 6, 61, 0, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(74, 1, 8, 1, 1, 165, 45, 110, 120, 26, 15000, 55, 50, &#039;No. 2&#039;, 225, 225, 6, 62, 0, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(75, 1, 8, 1, 1, 165, 45, 110, 120, 26, 15000, 55, 50, &#039;No. 3&#039;, 250, 250, 6, 63, 0, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(76, 1, 8, 1, 1, 200, 75, 150, 105, 26, 24000, 500, 50, &#039;No. 4&#039;, 475, 600, 20, 64, 0, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(77, 1, 8, 1, 1, 200, 75, 150, 100, 26, 24000, 500, 50, &#039;No. 5&#039;, 500, 600, 20, 65, 0, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(78, 1, 8, 1, 1, 200, 75, 150, 100, 26, 24000, 500, 50, &#039;No. 6&#039;, 525, 600, 20, 66, 1, 9, 0, 1, 0);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(79, 1, 8, 1, 1, 165, 45, 110, 120, 10, 15000, 55, 46, &#039;Aquara&#039;, 275, 275, 6, 34, 0, 9, 0, 0, 1);&lt;br /&gt;
INSERT INTO fantasytennis.Guardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(80, 1, 8, 1, 1, 165, 45, 110, 120, 9, 15000, 55, 44, &#039;Moora&#039;, 325, 360, 6, 33, 0, 9, 0, 0, 1);&lt;br /&gt;
&lt;br /&gt;
-- Additional BossGuardian entries for event maps&lt;br /&gt;
INSERT INTO fantasytennis.BossGuardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(8, 1, 15, 1, 1, 165, 60, 150, 120, 23, 20000, 200, 60, &#039;Hera&#039;, 500, 375, 34, 3, 0, 9, 1, 1, 1);&lt;br /&gt;
INSERT INTO fantasytennis.BossGuardian (id, addDex, addSta, addStr, addWill, baseDex, baseSta, baseStr, baseWill, btItemID, hpBase, hpPer, `level`, name, rewardExp, rewardGold, rewardRankingPoint, guardIndex, earth, elementGrade, fire, water, wind) VALUES(9, 1, 15, 1, 1, 220, 80, 160, 120, 27, 24000, 500, 60, &#039;TB-255&#039;, 2000, 1500, 60, 6, 1, 9, 1, 0, 1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fix existing Guardian and BossGuardian entries ====&lt;br /&gt;
&lt;br /&gt;
Some existing Guardian and BossGuardian records might be missing important attributes like `rewardExp`, `rewardGold`, or `guardIndex`. These entries can be corrected with the following `UPDATE` statements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- Fix Guardian entries for rest since they miss rewardExp,rewardGold and guardIndex&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=10, baseSta=1, baseStr=10, baseWill=30, btItemID=1, hpBase=500, hpPer=1, `level`=10, name=&#039;Dokaro&#039;, rewardExp=11, rewardGold=16, rewardRankingPoint=0, guardIndex=1, earth=0, elementGrade=2, fire=0, water=0, wind=0 WHERE id=1;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=12, baseSta=1, baseStr=13, baseWill=32, btItemID=1, hpBase=550, hpPer=1, `level`=15, name=&#039;Penkaro&#039;, rewardExp=11, rewardGold=16, rewardRankingPoint=0, guardIndex=2, earth=0, elementGrade=2, fire=0, water=0, wind=0 WHERE id=2;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=14, baseSta=1, baseStr=16, baseWill=34, btItemID=1, hpBase=600, hpPer=1, `level`=20, name=&#039;Bekaro&#039;, rewardExp=12, rewardGold=17, rewardRankingPoint=0, guardIndex=3, earth=0, elementGrade=2, fire=0, water=0, wind=0 WHERE id=3;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=16, baseSta=1, baseStr=19, baseWill=36, btItemID=1, hpBase=650, hpPer=1, `level`=25, name=&#039;Hokaro&#039;, rewardExp=12, rewardGold=17, rewardRankingPoint=0, guardIndex=4, earth=0, elementGrade=2, fire=0, water=0, wind=0 WHERE id=4;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=18, baseSta=1, baseStr=22, baseWill=38, btItemID=1, hpBase=700, hpPer=1, `level`=30, name=&#039;Sikaro&#039;, rewardExp=12, rewardGold=18, rewardRankingPoint=0, guardIndex=5, earth=0, elementGrade=2, fire=0, water=0, wind=0 WHERE id=5;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=20, baseSta=1, baseStr=25, baseWill=40, btItemID=1, hpBase=750, hpPer=1, `level`=40, name=&#039;Ikaro&#039;, rewardExp=13, rewardGold=18, rewardRankingPoint=0, guardIndex=6, earth=1, elementGrade=2, fire=1, water=0, wind=0 WHERE id=6;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=5, addStr=1, addWill=1, baseDex=10, baseSta=1, baseStr=14, baseWill=35, btItemID=2, hpBase=650, hpPer=6, `level`=20, name=&#039;Doteko&#039;, rewardExp=14, rewardGold=19, rewardRankingPoint=0, guardIndex=7, earth=0, elementGrade=3, fire=0, water=0, wind=0 WHERE id=7;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=5, addStr=1, addWill=1, baseDex=12, baseSta=1, baseStr=17, baseWill=37, btItemID=2, hpBase=700, hpPer=6, `level`=25, name=&#039;Penteko&#039;, rewardExp=16, rewardGold=19, rewardRankingPoint=0, guardIndex=8, earth=0, elementGrade=3, fire=0, water=0, wind=0 WHERE id=8;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=5, addStr=1, addWill=1, baseDex=14, baseSta=1, baseStr=20, baseWill=39, btItemID=2, hpBase=750, hpPer=6, `level`=30, name=&#039;Beteko&#039;, rewardExp=16, rewardGold=21, rewardRankingPoint=0, guardIndex=9, earth=0, elementGrade=3, fire=0, water=0, wind=0 WHERE id=9;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=5, addStr=1, addWill=1, baseDex=16, baseSta=1, baseStr=23, baseWill=41, btItemID=2, hpBase=800, hpPer=6, `level`=35, name=&#039;Hoteko&#039;, rewardExp=16, rewardGold=21, rewardRankingPoint=0, guardIndex=10, earth=0, elementGrade=3, fire=0, water=0, wind=0 WHERE id=10;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=18, baseSta=1, baseStr=26, baseWill=43, btItemID=2, hpBase=850, hpPer=6, `level`=40, name=&#039;Siteko&#039;, rewardExp=18, rewardGold=22, rewardRankingPoint=0, guardIndex=11, earth=0, elementGrade=3, fire=0, water=0, wind=0 WHERE id=11;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=20, baseSta=1, baseStr=29, baseWill=45, btItemID=2, hpBase=900, hpPer=6, `level`=45, name=&#039;Eteko&#039;, rewardExp=19, rewardGold=22, rewardRankingPoint=0, guardIndex=12, earth=0, elementGrade=3, fire=1, water=0, wind=1 WHERE id=12;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=15, baseSta=1, baseStr=25, baseWill=40, btItemID=3, hpBase=800, hpPer=7, `level`=25, name=&#039;Doga&#039;, rewardExp=27, rewardGold=37, rewardRankingPoint=2, guardIndex=13, earth=0, elementGrade=4, fire=0, water=1, wind=0 WHERE id=13;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=17, baseSta=1, baseStr=30, baseWill=42, btItemID=3, hpBase=850, hpPer=7, `level`=30, name=&#039;Penga&#039;, rewardExp=27, rewardGold=39, rewardRankingPoint=2, guardIndex=14, earth=0, elementGrade=4, fire=0, water=1, wind=0 WHERE id=14;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=19, baseSta=1, baseStr=35, baseWill=44, btItemID=3, hpBase=900, hpPer=7, `level`=35, name=&#039;Bega&#039;, rewardExp=28, rewardGold=39, rewardRankingPoint=2, guardIndex=15, earth=0, elementGrade=4, fire=0, water=1, wind=0 WHERE id=15;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=21, baseSta=1, baseStr=40, baseWill=46, btItemID=3, hpBase=950, hpPer=7, `level`=40, name=&#039;Hoga&#039;, rewardExp=29, rewardGold=43, rewardRankingPoint=2, guardIndex=16, earth=0, elementGrade=4, fire=0, water=1, wind=0 WHERE id=16;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=23, baseSta=1, baseStr=45, baseWill=48, btItemID=3, hpBase=1000, hpPer=7, `level`=45, name=&#039;Siga&#039;, rewardExp=30, rewardGold=43, rewardRankingPoint=2, guardIndex=17, earth=0, elementGrade=4, fire=0, water=1, wind=0 WHERE id=17;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=6, addStr=1, addWill=1, baseDex=25, baseSta=1, baseStr=50, baseWill=50, btItemID=3, hpBase=1050, hpPer=7, `level`=50, name=&#039;Ega&#039;, rewardExp=31, rewardGold=45, rewardRankingPoint=2, guardIndex=18, earth=1, elementGrade=4, fire=0, water=1, wind=0 WHERE id=18;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=50, baseSta=5, baseStr=30, baseWill=45, btItemID=4, hpBase=1200, hpPer=30, `level`=40, name=&#039;Dogoliath&#039;, rewardExp=55, rewardGold=70, rewardRankingPoint=4, guardIndex=19, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=19;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=55, baseSta=5, baseStr=35, baseWill=48, btItemID=4, hpBase=1350, hpPer=30, `level`=42, name=&#039;Pengoliath&#039;, rewardExp=60, rewardGold=75, rewardRankingPoint=4, guardIndex=20, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=20;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=60, baseSta=5, baseStr=40, baseWill=51, btItemID=4, hpBase=1500, hpPer=30, `level`=44, name=&#039;Begoliath&#039;, rewardExp=65, rewardGold=80, rewardRankingPoint=4, guardIndex=21, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=21;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=65, baseSta=5, baseStr=45, baseWill=54, btItemID=4, hpBase=1650, hpPer=30, `level`=46, name=&#039;Hogoliath&#039;, rewardExp=70, rewardGold=85, rewardRankingPoint=4, guardIndex=22, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=22;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=70, baseSta=5, baseStr=50, baseWill=57, btItemID=19, hpBase=1800, hpPer=30, `level`=48, name=&#039;Sigoliath&#039;, rewardExp=75, rewardGold=90, rewardRankingPoint=4, guardIndex=23, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=23;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=75, baseSta=5, baseStr=55, baseWill=60, btItemID=19, hpBase=1950, hpPer=30, `level`=50, name=&#039;Egoliath&#039;, rewardExp=85, rewardGold=92, rewardRankingPoint=4, guardIndex=24, earth=1, elementGrade=5, fire=0, water=0, wind=1 WHERE id=24;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=55, baseSta=10, baseStr=30, baseWill=45, btItemID=5, hpBase=2150, hpPer=50, `level`=40, name=&#039;Doblood&#039;, rewardExp=60, rewardGold=70, rewardRankingPoint=5, guardIndex=25, earth=0, elementGrade=6, fire=1, water=0, wind=0 WHERE id=25;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=60, baseSta=10, baseStr=35, baseWill=48, btItemID=5, hpBase=2300, hpPer=50, `level`=42, name=&#039;Penblood&#039;, rewardExp=65, rewardGold=75, rewardRankingPoint=5, guardIndex=26, earth=0, elementGrade=6, fire=1, water=0, wind=0 WHERE id=26;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=65, baseSta=10, baseStr=40, baseWill=51, btItemID=5, hpBase=2450, hpPer=50, `level`=44, name=&#039;Beblood&#039;, rewardExp=70, rewardGold=80, rewardRankingPoint=5, guardIndex=27, earth=0, elementGrade=6, fire=1, water=0, wind=0 WHERE id=27;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=70, baseSta=10, baseStr=45, baseWill=54, btItemID=5, hpBase=2600, hpPer=50, `level`=46, name=&#039;Hoblood&#039;, rewardExp=75, rewardGold=85, rewardRankingPoint=5, guardIndex=28, earth=0, elementGrade=6, fire=1, water=0, wind=0 WHERE id=28;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=75, baseSta=10, baseStr=50, baseWill=57, btItemID=5, hpBase=2750, hpPer=50, `level`=48, name=&#039;Siblood&#039;, rewardExp=80, rewardGold=90, rewardRankingPoint=5, guardIndex=29, earth=0, elementGrade=6, fire=1, water=0, wind=0 WHERE id=29;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=80, baseSta=10, baseStr=55, baseWill=60, btItemID=5, hpBase=2900, hpPer=50, `level`=50, name=&#039;Iblood&#039;, rewardExp=85, rewardGold=95, rewardRankingPoint=5, guardIndex=30, earth=0, elementGrade=6, fire=1, water=0, wind=1 WHERE id=30;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=55, baseSta=10, baseStr=30, baseWill=45, btItemID=7, hpBase=2650, hpPer=55, `level`=40, name=&#039;Windra&#039;, rewardExp=60, rewardGold=75, rewardRankingPoint=6, guardIndex=31, earth=0, elementGrade=7, fire=0, water=0, wind=1 WHERE id=31;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=60, baseSta=10, baseStr=35, baseWill=48, btItemID=8, hpBase=2800, hpPer=55, `level`=42, name=&#039;Earthra&#039;, rewardExp=65, rewardGold=80, rewardRankingPoint=6, guardIndex=32, earth=0, elementGrade=7, fire=0, water=0, wind=1 WHERE id=32;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=65, baseSta=10, baseStr=40, baseWill=51, btItemID=9, hpBase=2950, hpPer=55, `level`=44, name=&#039;Moora&#039;, rewardExp=70, rewardGold=85, rewardRankingPoint=6, guardIndex=33, earth=0, elementGrade=7, fire=0, water=0, wind=1 WHERE id=33;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=70, baseSta=10, baseStr=45, baseWill=54, btItemID=10, hpBase=3100, hpPer=55, `level`=46, name=&#039;Aquara&#039;, rewardExp=75, rewardGold=90, rewardRankingPoint=6, guardIndex=34, earth=0, elementGrade=7, fire=0, water=0, wind=1 WHERE id=34;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=75, baseSta=10, baseStr=50, baseWill=57, btItemID=11, hpBase=3250, hpPer=55, `level`=48, name=&#039;Fyra&#039;, rewardExp=80, rewardGold=95, rewardRankingPoint=6, guardIndex=35, earth=0, elementGrade=7, fire=0, water=0, wind=1 WHERE id=35;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=80, baseSta=10, baseStr=55, baseWill=60, btItemID=12, hpBase=3400, hpPer=55, `level`=50, name=&#039;Thundera&#039;, rewardExp=85, rewardGold=100, rewardRankingPoint=6, guardIndex=36, earth=0, elementGrade=7, fire=1, water=0, wind=1 WHERE id=36;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=55, baseSta=10, baseStr=30, baseWill=45, btItemID=5, hpBase=4150, hpPer=60, `level`=45, name=&#039;DevilDokaro&#039;, rewardExp=80, rewardGold=85, rewardRankingPoint=3, guardIndex=37, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=37;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=60, baseSta=10, baseStr=35, baseWill=48, btItemID=5, hpBase=4300, hpPer=60, `level`=46, name=&#039;DevilPenkaro&#039;, rewardExp=85, rewardGold=90, rewardRankingPoint=3, guardIndex=38, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=38;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=65, baseSta=10, baseStr=40, baseWill=51, btItemID=5, hpBase=4450, hpPer=60, `level`=47, name=&#039;DevilBekaro&#039;, rewardExp=90, rewardGold=95, rewardRankingPoint=3, guardIndex=39, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=39;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=70, baseSta=10, baseStr=45, baseWill=54, btItemID=5, hpBase=4600, hpPer=60, `level`=48, name=&#039;DevilHokaro&#039;, rewardExp=95, rewardGold=100, rewardRankingPoint=3, guardIndex=40, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=40;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=75, baseSta=10, baseStr=50, baseWill=57, btItemID=5, hpBase=4750, hpPer=60, `level`=49, name=&#039;DevilSikaro&#039;, rewardExp=100, rewardGold=105, rewardRankingPoint=3, guardIndex=41, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=41;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=10, addStr=1, addWill=1, baseDex=80, baseSta=10, baseStr=55, baseWill=60, btItemID=5, hpBase=4900, hpPer=60, `level`=50, name=&#039;DevilIkaro&#039;, rewardExp=105, rewardGold=110, rewardRankingPoint=3, guardIndex=42, earth=0, elementGrade=8, fire=1, water=0, wind=1 WHERE id=42;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=55, baseSta=10, baseStr=30, baseWill=45, btItemID=13, hpBase=2650, hpPer=55, `level`=50, name=&#039;Dolizard&#039;, rewardExp=65, rewardGold=90, rewardRankingPoint=8, guardIndex=43, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=43;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=60, baseSta=10, baseStr=35, baseWill=48, btItemID=14, hpBase=2800, hpPer=55, `level`=50, name=&#039;Penlizard&#039;, rewardExp=65, rewardGold=95, rewardRankingPoint=8, guardIndex=44, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=44;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=65, baseSta=10, baseStr=40, baseWill=51, btItemID=15, hpBase=2950, hpPer=55, `level`=50, name=&#039;Belizard&#039;, rewardExp=70, rewardGold=100, rewardRankingPoint=8, guardIndex=45, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=45;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=70, baseSta=10, baseStr=45, baseWill=54, btItemID=16, hpBase=3100, hpPer=55, `level`=50, name=&#039;Holizard&#039;, rewardExp=70, rewardGold=105, rewardRankingPoint=8, guardIndex=46, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=46;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=75, baseSta=10, baseStr=50, baseWill=57, btItemID=17, hpBase=3250, hpPer=55, `level`=50, name=&#039;Silizard&#039;, rewardExp=80, rewardGold=110, rewardRankingPoint=8, guardIndex=47, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=47;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=80, baseSta=10, baseStr=55, baseWill=60, btItemID=18, hpBase=3400, hpPer=55, `level`=50, name=&#039;Elizard&#039;, rewardExp=90, rewardGold=120, rewardRankingPoint=8, guardIndex=48, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=48;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=50, baseSta=5, baseStr=30, baseWill=45, btItemID=21, hpBase=1200, hpPer=30, `level`=40, name=&#039;Dotossakan&#039;, rewardExp=55, rewardGold=65, rewardRankingPoint=4, guardIndex=49, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=49;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=55, baseSta=5, baseStr=35, baseWill=48, btItemID=21, hpBase=1350, hpPer=30, `level`=42, name=&#039;Pantossakan&#039;, rewardExp=60, rewardGold=65, rewardRankingPoint=4, guardIndex=50, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=50;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=60, baseSta=5, baseStr=40, baseWill=51, btItemID=21, hpBase=1500, hpPer=30, `level`=44, name=&#039;Betossakan&#039;, rewardExp=65, rewardGold=75, rewardRankingPoint=4, guardIndex=51, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=51;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=65, baseSta=5, baseStr=45, baseWill=54, btItemID=21, hpBase=1650, hpPer=30, `level`=46, name=&#039;Hotossakan&#039;, rewardExp=70, rewardGold=75, rewardRankingPoint=4, guardIndex=52, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=52;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=70, baseSta=5, baseStr=50, baseWill=57, btItemID=22, hpBase=1800, hpPer=30, `level`=48, name=&#039;Sitossakan&#039;, rewardExp=75, rewardGold=75, rewardRankingPoint=4, guardIndex=53, earth=1, elementGrade=5, fire=0, water=0, wind=0 WHERE id=53;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=7, addStr=1, addWill=1, baseDex=75, baseSta=5, baseStr=55, baseWill=60, btItemID=22, hpBase=1950, hpPer=30, `level`=50, name=&#039;Etoossakan&#039;, rewardExp=80, rewardGold=90, rewardRankingPoint=4, guardIndex=54, earth=1, elementGrade=5, fire=0, water=0, wind=1 WHERE id=54;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=14, baseSta=2, baseStr=16, baseWill=34, btItemID=1, hpBase=600, hpPer=1, `level`=20, name=&#039;Kuromaro&#039;, rewardExp=10, rewardGold=10, rewardRankingPoint=1, guardIndex=55, earth=1, elementGrade=2, fire=0, water=0, wind=0 WHERE id=55;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=16, baseSta=2, baseStr=19, baseWill=36, btItemID=1, hpBase=650, hpPer=1, `level`=25, name=&#039;Akamaro&#039;, rewardExp=12, rewardGold=10, rewardRankingPoint=1, guardIndex=56, earth=0, elementGrade=2, fire=1, water=0, wind=0 WHERE id=56;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=18, baseSta=2, baseStr=22, baseWill=38, btItemID=1, hpBase=700, hpPer=1, `level`=30, name=&#039;Aomaro&#039;, rewardExp=15, rewardGold=12, rewardRankingPoint=1, guardIndex=57, earth=0, elementGrade=2, fire=0, water=1, wind=0 WHERE id=57;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=20, baseSta=2, baseStr=25, baseWill=40, btItemID=1, hpBase=750, hpPer=1, `level`=35, name=&#039;Kokechamaro&#039;, rewardExp=18, rewardGold=15, rewardRankingPoint=1, guardIndex=58, earth=0, elementGrade=2, fire=0, water=0, wind=1 WHERE id=58;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=22, baseSta=2, baseStr=28, baseWill=42, btItemID=1, hpBase=800, hpPer=1, `level`=40, name=&#039;Chachamaro&#039;, rewardExp=20, rewardGold=18, rewardRankingPoint=1, guardIndex=59, earth=1, elementGrade=2, fire=1, water=0, wind=0 WHERE id=59;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=4, addStr=1, addWill=1, baseDex=24, baseSta=2, baseStr=31, baseWill=44, btItemID=1, hpBase=850, hpPer=1, `level`=50, name=&#039;Siromaro&#039;, rewardExp=35, rewardGold=20, rewardRankingPoint=1, guardIndex=60, earth=0, elementGrade=2, fire=0, water=1, wind=1 WHERE id=60;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=55, baseSta=10, baseStr=30, baseWill=45, btItemID=26, hpBase=2650, hpPer=55, `level`=50, name=&#039;No. 1&#039;, rewardExp=45, rewardGold=45, rewardRankingPoint=6, guardIndex=61, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=61;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=60, baseSta=10, baseStr=35, baseWill=48, btItemID=26, hpBase=2800, hpPer=55, `level`=50, name=&#039;No. 2&#039;, rewardExp=55, rewardGold=50, rewardRankingPoint=6, guardIndex=62, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=62;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=65, baseSta=10, baseStr=40, baseWill=51, btItemID=26, hpBase=2950, hpPer=55, `level`=50, name=&#039;No. 3&#039;, rewardExp=60, rewardGold=55, rewardRankingPoint=6, guardIndex=63, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=63;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=70, baseSta=10, baseStr=45, baseWill=54, btItemID=26, hpBase=3100, hpPer=55, `level`=50, name=&#039;No. 4&#039;, rewardExp=65, rewardGold=60, rewardRankingPoint=6, guardIndex=64, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=64;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=75, baseSta=10, baseStr=50, baseWill=57, btItemID=26, hpBase=3250, hpPer=55, `level`=50, name=&#039;No. 5&#039;, rewardExp=70, rewardGold=70, rewardRankingPoint=6, guardIndex=65, earth=0, elementGrade=9, fire=0, water=1, wind=0 WHERE id=65;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=8, addStr=1, addWill=1, baseDex=80, baseSta=10, baseStr=55, baseWill=60, btItemID=26, hpBase=3400, hpPer=55, `level`=50, name=&#039;No. 6&#039;, rewardExp=75, rewardGold=75, rewardRankingPoint=6, guardIndex=66, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=66;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=110, baseSta=25, baseStr=70, baseWill=88, btItemID=28, hpBase=4000, hpPer=850, `level`=50, name=&#039;Yeppeuni&#039;, rewardExp=150, rewardGold=120, rewardRankingPoint=7, guardIndex=67, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=67;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=115, baseSta=25, baseStr=72, baseWill=91, btItemID=28, hpBase=4100, hpPer=850, `level`=52, name=&#039;Gwiyeomi&#039;, rewardExp=155, rewardGold=125, rewardRankingPoint=7, guardIndex=68, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=68;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=120, baseSta=25, baseStr=74, baseWill=94, btItemID=28, hpBase=4200, hpPer=850, `level`=54, name=&#039;Ballari&#039;, rewardExp=160, rewardGold=130, rewardRankingPoint=7, guardIndex=69, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=69;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=125, baseSta=25, baseStr=76, baseWill=97, btItemID=28, hpBase=4300, hpPer=850, `level`=56, name=&#039;Sangkeumi&#039;, rewardExp=165, rewardGold=135, rewardRankingPoint=7, guardIndex=70, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=70;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=130, baseSta=25, baseStr=78, baseWill=100, btItemID=28, hpBase=4400, hpPer=850, `level`=58, name=&#039;Hwaljjagi&#039;, rewardExp=170, rewardGold=140, rewardRankingPoint=7, guardIndex=71, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=71;&lt;br /&gt;
UPDATE fantasytennis.Guardian SET addDex=1, addSta=11, addStr=1, addWill=1, baseDex=135, baseSta=25, baseStr=80, baseWill=103, btItemID=28, hpBase=4500, hpPer=850, `level`=60, name=&#039;Saechimi&#039;, rewardExp=175, rewardGold=145, rewardRankingPoint=7, guardIndex=72, earth=1, elementGrade=9, fire=0, water=1, wind=0 WHERE id=72;&lt;br /&gt;
&lt;br /&gt;
-- -- Fix BossGuardian entries for rest since they miss rewardExp,rewardGold and guardIndex&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=100, baseSta=45, baseStr=40, baseWill=90, btItemID=20, hpBase=5000, hpPer=150, `level`=60, name=&#039;Hell Blood&#039;, rewardExp=90, rewardGold=165, rewardRankingPoint=14, guardIndex=1, earth=1, elementGrade=9, fire=1, water=0, wind=1 WHERE id=1;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=100, baseSta=45, baseStr=40, baseWill=90, btItemID=20, hpBase=10000, hpPer=150, `level`=60, name=&#039;Hell Blood&#039;, rewardExp=480, rewardGold=450, rewardRankingPoint=44, guardIndex=2, earth=1, elementGrade=9, fire=1, water=0, wind=1 WHERE id=2;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=120, baseSta=35, baseStr=85, baseWill=95, btItemID=23, hpBase=7000, hpPer=200, `level`=60, name=&#039;Hera&#039;, rewardExp=200, rewardGold=180, rewardRankingPoint=14, guardIndex=3, earth=0, elementGrade=9, fire=1, water=1, wind=1 WHERE id=3;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=130, baseSta=25, baseStr=90, baseWill=100, btItemID=24, hpBase=9000, hpPer=250, `level`=60, name=&#039;Royal Lizard&#039;, rewardExp=220, rewardGold=270, rewardRankingPoint=14, guardIndex=4, earth=1, elementGrade=9, fire=0, water=1, wind=1 WHERE id=4;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=140, baseSta=15, baseStr=95, baseWill=105, btItemID=25, hpBase=11000, hpPer=300, `level`=60, name=&#039;TossakanBoss&#039;, rewardExp=240, rewardGold=285, rewardRankingPoint=10, guardIndex=5, earth=1, elementGrade=9, fire=1, water=1, wind=0 WHERE id=5;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=140, baseSta=10, baseStr=95, baseWill=105, btItemID=27, hpBase=13000, hpPer=300, `level`=60, name=&#039;TB-255&#039;, rewardExp=240, rewardGold=300, rewardRankingPoint=18, guardIndex=6, earth=1, elementGrade=9, fire=1, water=0, wind=1 WHERE id=6;&lt;br /&gt;
UPDATE fantasytennis.BossGuardian SET addDex=1, addSta=15, addStr=1, addWill=1, baseDex=160, baseSta=30, baseStr=105, baseWill=115, btItemID=29, hpBase=15000, hpPer=400, `level`=60, name=&#039;Dance King&#039;, rewardExp=280, rewardGold=300, rewardRankingPoint=10, guardIndex=7, earth=1, elementGrade=9, fire=1, water=1, wind=0 WHERE id=7;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cleaning Up the Database ===&lt;br /&gt;
&lt;br /&gt;
Before re-running the script, it&#039;s important to delete any invalid or partially inserted data left behind by previous failed attempts. You can do this with the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
DELETE FROM Config;&lt;br /&gt;
DELETE FROM K_Status;&lt;br /&gt;
DELETE FROM S_Maps;&lt;br /&gt;
DELETE FROM M_Scenarios;&lt;br /&gt;
DELETE FROM Map_2_Scenarios;&lt;br /&gt;
DELETE FROM Guardian_2_Maps;&lt;br /&gt;
DELETE FROM Skill_2_Guardians;&lt;br /&gt;
DELETE FROM S_Guardian_Multiplier;&lt;br /&gt;
DELETE FROM S_Relationship_Roles;&lt;br /&gt;
DELETE FROM S_Relationship_Types;&lt;br /&gt;
DELETE FROM S_Relationships;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Running the Import Script ===&lt;br /&gt;
&lt;br /&gt;
Once you’ve applied the necessary fixes, you can proceed with re-importing the SQL files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd &amp;lt;path-to-local-JFTSE-repo&amp;gt;/scripts&lt;br /&gt;
./import_sql.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related Issues ==&lt;br /&gt;
* [https://github.com/sstokic-tgm/JFTSE/issues/180 GitHub Issue #180]&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:Fixing]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Game_Lore&amp;diff=70</id>
		<title>Game Lore</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Game_Lore&amp;diff=70"/>
		<updated>2025-02-24T21:05:51Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;== Game Lore == The world of &amp;#039;&amp;#039;Fantasy Tennis&amp;#039;&amp;#039; is set in the mystical realm of &amp;#039;&amp;#039;&amp;#039;Fantasy Land&amp;#039;&amp;#039;&amp;#039;, where warriors, adventurers, and magical beings compete in battles that blend athletic skill with powerful magic. This land is rich with legends, and its many races and factions form alliances, rivalries, and struggles for survival.  == The Origins of Fantasy Land == Fantasy Land was shaped by divine forces, a realm born from the delicate balance between light and darkness...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Game Lore ==&lt;br /&gt;
The world of &#039;&#039;Fantasy Tennis&#039;&#039; is set in the mystical realm of &#039;&#039;&#039;Fantasy Land&#039;&#039;&#039;, where warriors, adventurers, and magical beings compete in battles that blend athletic skill with powerful magic. This land is rich with legends, and its many races and factions form alliances, rivalries, and struggles for survival.&lt;br /&gt;
&lt;br /&gt;
== The Origins of Fantasy Land ==&lt;br /&gt;
Fantasy Land was shaped by divine forces, a realm born from the delicate balance between light and darkness. Celestial beings once watched over this harmony, but over time, conflicts arose—some seeking power, others striving to preserve the balance.&lt;br /&gt;
&lt;br /&gt;
== The Great Conflict ==&lt;br /&gt;
A great war once raged between the guardians of Fantasy Land and rebellious forces that sought to seize control of its magic. Heroes emerged to defend the realm, wielding both weapons and enchanted abilities. These battles were no ordinary duels; they took place on the mystical courts of Fantasy Land, where champions clashed in matches that could determine the fate of entire realms.&lt;br /&gt;
&lt;br /&gt;
== The Ark Crystal ==&lt;br /&gt;
At the heart of Fantasy Land lies the &#039;&#039;&#039;Ark Crystal&#039;&#039;&#039;, a powerful source of magical energy that maintains the world&#039;s balance. It ensures that no single faction or force gains absolute dominance. However, in recent times, its energy has begun to fade, throwing the land into uncertainty. Strange events ripple across the realm, and both scholars and champions search for a way to restore its strength before it&#039;s too late.&lt;br /&gt;
&lt;br /&gt;
== The Goddess Hera and Her Wrath ==&lt;br /&gt;
Among the divine beings watching over Fantasy Land, the goddess &#039;&#039;&#039;Hera&#039;&#039;&#039; holds immense power. Once a guardian of order, she became disillusioned with mortals&#039; reckless use of magic. Her frustration turned into wrath, and over time, her influence became a force of both challenge and destruction.&lt;br /&gt;
&lt;br /&gt;
It is said that during the winter months, under the eerie glow of the &#039;&#039;&#039;Snow Moon&#039;&#039;&#039;, Hera’s magic summons formidable foes to test the champions of Fantasy Land. Many see these battles as divine trials, a way for Hera to judge the strength of those who walk her land. Others believe they serve as warnings of greater calamities to come.&lt;br /&gt;
&lt;br /&gt;
== Town Square and Its Role ==&lt;br /&gt;
At the heart of Fantasy Land lies &#039;&#039;&#039;Town Square&#039;&#039;&#039;, a gathering place for adventurers and champions. It is a sanctuary where players share knowledge, prepare for battles, and stay informed about the changing tides of the world. Notable figures, such as the wise &#039;&#039;&#039;Frostlin&#039;&#039;&#039; and a peculiar pelican scholar, offer guidance to those who seek it.&lt;br /&gt;
&lt;br /&gt;
== The Frozen Lakes Mystery ==&lt;br /&gt;
During a recent event, the lakes of Fantasy Land, once teeming with life, mysteriously froze over. Some believed this was caused by the Ark Crystal’s instability, while others suspected Hera’s growing influence. Though the ice has since melted, the phenomenon left many questions unanswered. A curious penguin scholar had taken up the task of investigating this strange occurrence, but whether the lakes will freeze again remains unknown.&lt;br /&gt;
&lt;br /&gt;
== The Pirate Merchant ==&lt;br /&gt;
A wandering pirate, often seen near a cart filled with rare goods, has been spotted in Town Square. His true intentions remain a mystery, but his knowledge of distant lands and his selection of unusual wares have drawn the attention of many travelers. Some suspect he holds secrets about the fading power of the Ark Crystal, though whether he will share them is another matter.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
Fantasy Land is ever changing, shaped by its inhabitants, celestial forces, and the ongoing struggle for balance. As the Ark Crystal weakens and ancient powers awaken, champions from across the world must rise to the challenge. Whether through strength, strategy, or sheer determination, they will decide the fate of this mystical realm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;The lore of &#039;&#039;Fantasy Tennis&#039;&#039; is shaped by both official sources and community driven storytelling. While some elements are drawn from the original game&#039;s world, others have evolved through the creativity and interpretations of players over time. As Fantasy Land continues to grow, its legends, myths, and mysteries remain ever changing, shaped by those who explore its depths.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Commands&amp;diff=69</id>
		<title>Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Commands&amp;diff=69"/>
		<updated>2025-02-24T20:32:36Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ingame Commands =&lt;br /&gt;
&lt;br /&gt;
This page provides a list of available ingame commands for &#039;&#039;&#039;Fantasy Tennis&#039;&#039;&#039; within &#039;&#039;&#039;JFTSE&#039;&#039;&#039;. Commands must be prefixed with a `-` to execute. Some commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== General Commands ==&lt;br /&gt;
These commands can be used by all players.&lt;br /&gt;
&lt;br /&gt;
=== 🎲 Random Mode ===&lt;br /&gt;
[[Guardian Random Mode|Random guardians]] will spawn instead of the default ones (boss remains the same).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-random&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔥 Hard Mode ===&lt;br /&gt;
Enables &#039;&#039;&#039;[[Guardian Hard Mode|Hard Mode]]&#039;&#039;&#039;, increasing enemy stats and spawning additional guardians.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-hard&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Gacha Opening ===&lt;br /&gt;
Opens gachas without animation for faster processing.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Gacha Name&amp;quot; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Western Coin&amp;quot; 50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Note:&amp;lt;/span&amp;gt;&#039;&#039;&#039; Some gachas contain &amp;quot;ll&amp;quot; (e.g., `&amp;quot;Rare Box ll&amp;quot;`), requiring a lowercase `L` in the command.&lt;br /&gt;
&lt;br /&gt;
=== 🏆 Arcade Mode ===&lt;br /&gt;
Enters &#039;&#039;&#039;Arcade Mode&#039;&#039;&#039;. WIP.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-arcade&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Pointback ===&lt;br /&gt;
Allows players to vote for resetting the last point in &#039;&#039;&#039;[[Basic Mode]]&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-pb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;Note:&#039;&#039;&#039; All players must vote using `-pb` before a new point is made.&lt;br /&gt;
&lt;br /&gt;
== GM Commands ==&lt;br /&gt;
These commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 🚫 Player Management ===&lt;br /&gt;
Banning, unbanning, and kicking players.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-ban &amp;lt;player&amp;gt;&lt;br /&gt;
-unban &amp;lt;player&amp;gt;&lt;br /&gt;
-serverKick &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 📝 Server Notice ===&lt;br /&gt;
Sets and broadcasts a &#039;&#039;&#039;server wide notice&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-sN &amp;lt;message&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Reset &amp;amp; Reload ===&lt;br /&gt;
Resets or reloads server data.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rsLogin &amp;lt;player&amp;gt;    # Resets login status&lt;br /&gt;
-reloadScripts       # Reloads all scripts&lt;br /&gt;
-event              # Event configuration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Item &amp;amp; Gift Commands ===&lt;br /&gt;
Used to grant items, experience, or gold to players.&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;another player&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-give &amp;lt;player&amp;gt; &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;yourself&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-get &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send a &#039;&#039;&#039;gift&#039;&#039;&#039; to another player:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-gift &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Help Command ==&lt;br /&gt;
Displays all commands and their description.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-help&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;Notes:&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
* Commands &#039;&#039;&#039;must always start with `-`&#039;&#039;&#039;.&lt;br /&gt;
* Some commands may have additional restrictions (e.g., requiring level 60).&lt;br /&gt;
* GM commands are &#039;&#039;&#039;restricted&#039;&#039;&#039; to authorized users.&lt;br /&gt;
&lt;br /&gt;
For further details, refer to the ingame chat.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=68</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=68"/>
		<updated>2025-02-24T20:30:36Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Map_2_Scenarios ===&lt;br /&gt;
Establishes the link between maps (`S_Maps`) and scenarios (`M_Scenarios`). Without defining mappings in this table, the scenario system will not function correctly.&lt;br /&gt;
&lt;br /&gt;
This table uses a many-to-many relationship, ensuring that:&lt;br /&gt;
* Each scenario can be assigned to multiple maps.&lt;br /&gt;
* Each map can be associated with multiple scenarios.&lt;br /&gt;
&lt;br /&gt;
The relationship is defined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Description&lt;br /&gt;
|-&lt;br /&gt;
| `scenario_id` || References `M_Scenarios.id`, linking the scenario.&lt;br /&gt;
|-&lt;br /&gt;
| `map_id` || References `S_Maps.id`, linking the map.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mapping structure allows flexibility, ensuring that game modes can be dynamically adjusted based on the assigned scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines connections between various entities within the game, enabling precise control over item drops, multipliers, and other gameplay mechanics. Relationships are established using two key fields:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;`id_f`&#039;&#039;&#039; (`id_from`): Represents the originating entity of the relationship, such as a Product or Multiplier.&lt;br /&gt;
* &#039;&#039;&#039;`id_t`&#039;&#039;&#039; (`id_to`): Represents the target entity of the relationship, such as a Guardian, Boss Guardian, or Map.&lt;br /&gt;
&lt;br /&gt;
When linking products specifically to guardians, the &#039;&#039;&#039;`productIndex`&#039;&#039;&#039; from the product definition is used for &#039;&#039;&#039;`id_f`&#039;&#039;&#039;, and the &#039;&#039;&#039;`guardian_2_maps.id`&#039;&#039;&#039; (not the direct Guardian or Boss Guardian ID) is used for &#039;&#039;&#039;`id_t`&#039;&#039;&#039;. Each relationship is further described by its type and role, defining how it influences gameplay.&lt;br /&gt;
&lt;br /&gt;
Relationships can be individually toggled on or off via the &#039;&#039;&#039;`status`&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
==== Advanced Item Drop Control (Role ID 1) ====&lt;br /&gt;
Additionally, enhanced item drop control is available specifically for the &#039;&#039;&#039;Item Drop&#039;&#039;&#039; role (role ID &#039;&#039;&#039;1&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
* Default item weight is &#039;&#039;&#039;20.0&#039;&#039;&#039; when no specific weight is provided.&lt;br /&gt;
* A fixed weight of &#039;&#039;&#039;15.0&#039;&#039;&#039; is used to determine scenarios where no item is awarded (displayed as an &amp;quot;X&amp;quot;).&lt;br /&gt;
* Drop exclusivity can be defined specifically for:&lt;br /&gt;
** &#039;&#039;&#039;`forHardMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Hard Mode]].&lt;br /&gt;
** &#039;&#039;&#039;`forRandomMode`&#039;&#039;&#039;: Drops exclusive to [[Guardian Random Mode]].&lt;br /&gt;
* The &#039;&#039;&#039;`levelReq`&#039;&#039;&#039; field, currently unused, is reserved for future use to restrict drops based on player levels in a planned progression system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quantity Determination for Item Drops:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Quantity Result&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; is set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; not set || Exact quantity from &#039;&#039;&#039;`qty`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; not set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| All quantity fields &#039;&#039;&#039;NULL&#039;&#039;&#039; || Defaults based on item type:&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039;: Min 1 / Max 3&lt;br /&gt;
* &#039;&#039;&#039;Quick&#039;&#039;&#039;: Min 5 / Max 100&lt;br /&gt;
* &#039;&#039;&#039;Parts &amp;amp; Others&#039;&#039;&#039;: Min 1 / Max 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; both set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines supported relationship types, describing what entities can be linked together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the supported roles that relationships can take, describing their in game functionality:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Notes &amp;amp; Additional Information ===&lt;br /&gt;
* The database schema is subject to updates as new mechanics and features are introduced.&lt;br /&gt;
* Some tables may have additional columns not explicitly documented if they are not required for core functionality.&lt;br /&gt;
* Unused fields, such as `levelReq` in `S_Relationships`, are placeholders for future game progression updates.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=67</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=67"/>
		<updated>2025-02-24T20:03:33Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Map_2_Scenarios ===&lt;br /&gt;
Establishes the link between maps (`S_Maps`) and scenarios (`M_Scenarios`). Without defining mappings in this table, the scenario system will not function correctly.&lt;br /&gt;
&lt;br /&gt;
This table uses a many-to-many relationship, ensuring that:&lt;br /&gt;
* Each scenario can be assigned to multiple maps.&lt;br /&gt;
* Each map can be associated with multiple scenarios.&lt;br /&gt;
&lt;br /&gt;
The relationship is defined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Description&lt;br /&gt;
|-&lt;br /&gt;
| `scenario_id` || References `M_Scenarios.id`, linking the scenario.&lt;br /&gt;
|-&lt;br /&gt;
| `map_id` || References `S_Maps.id`, linking the map.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mapping structure allows flexibility, ensuring that game modes can be dynamically adjusted based on the assigned scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines connections between various entities within the game, enabling precise control over item drops, multipliers, and other gameplay mechanics. Relationships are established using two key fields:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;`id_f`&#039;&#039;&#039; (`id_from`): Represents the originating entity of the relationship, such as a Product or Multiplier.&lt;br /&gt;
* &#039;&#039;&#039;`id_t`&#039;&#039;&#039; (`id_to`): Represents the target entity of the relationship, such as a Guardian, Boss Guardian, or Map.&lt;br /&gt;
&lt;br /&gt;
When linking products specifically to guardians, the &#039;&#039;&#039;`productIndex`&#039;&#039;&#039; from the product definition is used for &#039;&#039;&#039;`id_f`&#039;&#039;&#039;, and the &#039;&#039;&#039;`guardian_2_maps.id`&#039;&#039;&#039; (not the direct Guardian or Boss Guardian ID) is used for &#039;&#039;&#039;`id_t`&#039;&#039;&#039;. Each relationship is further described by its type and role, defining how it influences gameplay.&lt;br /&gt;
&lt;br /&gt;
Relationships can be individually toggled on or off via the &#039;&#039;&#039;`status`&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
==== Advanced Item Drop Control (Role ID 1) ====&lt;br /&gt;
Additionally, enhanced item drop control is available specifically for the &#039;&#039;&#039;Item Drop&#039;&#039;&#039; role (role ID &#039;&#039;&#039;1&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
* Default item weight is &#039;&#039;&#039;20.0&#039;&#039;&#039; when no specific weight is provided.&lt;br /&gt;
* A fixed weight of &#039;&#039;&#039;15.0&#039;&#039;&#039; is used to determine scenarios where no item is awarded (displayed as an &amp;quot;X&amp;quot;).&lt;br /&gt;
* Drop exclusivity can be defined specifically for:&lt;br /&gt;
** &#039;&#039;&#039;`forHardMode`&#039;&#039;&#039;: Drops exclusive to Guardian Hard Mode.&lt;br /&gt;
** &#039;&#039;&#039;`forRandomMode`&#039;&#039;&#039;: Drops exclusive to Guardian Random Mode.&lt;br /&gt;
* The &#039;&#039;&#039;`levelReq`&#039;&#039;&#039; field, currently unused, is reserved for future use to restrict drops based on player levels in a planned progression system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quantity Determination for Item Drops:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Quantity Result&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; is set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; not set || Exact quantity from &#039;&#039;&#039;`qty`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; not set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| All quantity fields &#039;&#039;&#039;NULL&#039;&#039;&#039; || Defaults based on item type:&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039;: Min 1 / Max 3&lt;br /&gt;
* &#039;&#039;&#039;Quick&#039;&#039;&#039;: Min 5 / Max 100&lt;br /&gt;
* &#039;&#039;&#039;Parts &amp;amp; Others&#039;&#039;&#039;: Min 1 / Max 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; both set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines supported relationship types, describing what entities can be linked together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the supported roles that relationships can take, describing their in game functionality:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Notes &amp;amp; Additional Information ===&lt;br /&gt;
* The database schema is subject to updates as new mechanics and features are introduced.&lt;br /&gt;
* Some tables may have additional columns not explicitly documented if they are not required for core functionality.&lt;br /&gt;
* Unused fields, such as `levelReq` in `S_Relationships`, are placeholders for future game progression updates.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=66</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=66"/>
		<updated>2025-02-24T19:57:41Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines connections between various entities within the game, enabling precise control over item drops, multipliers, and other gameplay mechanics. Relationships are established using two key fields:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;`id_f`&#039;&#039;&#039; (`id_from`): Represents the originating entity of the relationship, such as a Product or Multiplier.&lt;br /&gt;
* &#039;&#039;&#039;`id_t`&#039;&#039;&#039; (`id_to`): Represents the target entity of the relationship, such as a Guardian, Boss Guardian, or Map.&lt;br /&gt;
&lt;br /&gt;
When linking products specifically to guardians, the &#039;&#039;&#039;`productIndex`&#039;&#039;&#039; from the product definition is used for &#039;&#039;&#039;`id_f`&#039;&#039;&#039;, and the &#039;&#039;&#039;`guardian_2_maps.id`&#039;&#039;&#039; (not the direct Guardian or Boss Guardian ID) is used for &#039;&#039;&#039;`id_t`&#039;&#039;&#039;. Each relationship is further described by its type and role, defining how it influences gameplay.&lt;br /&gt;
&lt;br /&gt;
Relationships can be individually toggled on or off via the &#039;&#039;&#039;`status`&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
==== Advanced Item Drop Control (Role ID 1) ====&lt;br /&gt;
Additionally, enhanced item drop control is available specifically for the &#039;&#039;&#039;Item Drop&#039;&#039;&#039; role (role ID &#039;&#039;&#039;1&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
* Default item weight is &#039;&#039;&#039;20.0&#039;&#039;&#039; when no specific weight is provided.&lt;br /&gt;
* A fixed weight of &#039;&#039;&#039;15.0&#039;&#039;&#039; is used to determine scenarios where no item is awarded (displayed as an &amp;quot;X&amp;quot;).&lt;br /&gt;
* Drop exclusivity can be defined specifically for:&lt;br /&gt;
** &#039;&#039;&#039;`forHardMode`&#039;&#039;&#039;: Drops exclusive to Guardian Hard Mode.&lt;br /&gt;
** &#039;&#039;&#039;`forRandomMode`&#039;&#039;&#039;: Drops exclusive to Guardian Random Mode.&lt;br /&gt;
* The &#039;&#039;&#039;`levelReq`&#039;&#039;&#039; field, currently unused, is reserved for future use to restrict drops based on player levels in a planned progression system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quantity Determination for Item Drops:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Quantity Result&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; is set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; not set || Exact quantity from &#039;&#039;&#039;`qty`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; not set, &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| All quantity fields &#039;&#039;&#039;NULL&#039;&#039;&#039; || Defaults based on item type:&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039;: Min 1 / Max 3&lt;br /&gt;
* &#039;&#039;&#039;Quick&#039;&#039;&#039;: Min 5 / Max 100&lt;br /&gt;
* &#039;&#039;&#039;Parts &amp;amp; Others&#039;&#039;&#039;: Min 1 / Max 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;`qty`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMin`/`qtyMax`&#039;&#039;&#039; both set || Random quantity between &#039;&#039;&#039;`qtyMin`&#039;&#039;&#039; and &#039;&#039;&#039;`qtyMax`&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines supported relationship types, describing what entities can be linked together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the supported roles that relationships can take, describing their in game functionality:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Notes &amp;amp; Additional Information ===&lt;br /&gt;
* The database schema is subject to updates as new mechanics and features are introduced.&lt;br /&gt;
* Some tables may have additional columns not explicitly documented if they are not required for core functionality.&lt;br /&gt;
* Unused fields, such as `levelReq` in `S_Relationships`, are placeholders for future game progression updates.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=65</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=65"/>
		<updated>2025-02-24T19:45:07Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|200px|thumb|center|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
== Tables of Interest ==&lt;br /&gt;
Tables might worth looking into as they are important on setting up your own Fantasy Tennis Server Configuration inside the Database.&lt;br /&gt;
&lt;br /&gt;
=== Config ===&lt;br /&gt;
The `config` table is used to store various server wide settings that control gameplay mechanics, security settings, logging behavior, and feature toggles. Each configuration entry consists of:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; – The unique identifier of the config setting.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; – A short explanation of what the setting controls (may be null).&lt;br /&gt;
* &#039;&#039;&#039;value&#039;&#039;&#039; – The actual configured value.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; – The data type of the value (e.g., boolean, int, double, string).&lt;br /&gt;
&lt;br /&gt;
Administrators can modify these values to tweak server behavior, enable or disable features, and adjust game mechanics dynamically.&lt;br /&gt;
&lt;br /&gt;
Below is a list of currently supported configuration values along with their default settings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Type !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.enabled&#039;&#039;&#039; || boolean || false || Enables or disables the built-in anticheat (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;anticheat.port&#039;&#039;&#039; || int || 1337 || Port used for the anticheat system (JFTSE exclusive).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;dev.packets.handle&#039;&#039;&#039; || boolean || false || Handles developer/debug packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;packets.id.translate.enabled&#039;&#039;&#039; || boolean || true || Enables translation of packet IDs.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.all.enabled&#039;&#039;&#039; || boolean || true || Enables logging of all network packets.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;network.encryption.enabled&#039;&#039;&#039; || boolean || false || Enables network encryption for secure communication.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;password.encryption.enabled&#039;&#039;&#039; || boolean || false || Encrypts player passwords upon login.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;player.level.max&#039;&#039;&#039; || int || 60 || Maximum player level (JFTSE exclusive, levels above 65 require client modifications).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;command.room.mode.change.player.level&#039;&#039;&#039; || int || 60 || Minimum required level to change room mode via command.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.gold&#039;&#039;&#039; || int || 5 || Global gold bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.global.exp&#039;&#039;&#039; || int || 5 || Global experience bonus multiplier (Single Player).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.exp&#039;&#039;&#039; || double || 0.2 || Experience bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.bonus.wongame.gold&#039;&#039;&#039; || double || 0.2 || Gold bonus for winning a game (Basic &amp;amp; Battle).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logging.packets.console-output.enabled&#039;&#039;&#039; || boolean || true || Enables logging of packets in console output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;matchplay.guardian.hard.won.ranking-point.multiplier&#039;&#039;&#039; || double || 1.0 || Multiplier applied to ranking points in Guardian Hard mode.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;game.map.allow.snowmoon&#039;&#039;&#039; || boolean || false || Allows Snow Moon map in Guardian mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* Config values marked as &#039;&#039;&#039;JFTSE exclusive&#039;&#039;&#039; are unique to this server implementation and may not be available in other Fantasy Tennis servers.&lt;br /&gt;
* Those values represent the development chosen defaults and does not represent values set within the [https://jftse.com JFTSE] hosted server.&lt;br /&gt;
&lt;br /&gt;
=== M_Scenarios ===&lt;br /&gt;
Each game mode has multiple scenarios. A scenario marked as &amp;quot;default&amp;quot; is always selected first. If multiple scenarios are active (`status = 1`), the default scenario is prioritized. If multiple active scenarios are marked as default, the first one retrieved from the database is chosen.&lt;br /&gt;
&lt;br /&gt;
Scenario types:&lt;br /&gt;
* &#039;&#039;&#039;Guardian Normal (non Boss Battle)&#039;&#039;&#039; → `GUARDIAN`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian&#039;&#039;&#039; → `BOSS_BATTLE`&lt;br /&gt;
* &#039;&#039;&#039;Boss Guardian v2 (new mechanics defined through scripting)&#039;&#039;&#039; → `BOSS_BATTLE_V2`&lt;br /&gt;
&lt;br /&gt;
=== S_Maps ===&lt;br /&gt;
Defines all available maps and references client map id&#039;s.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! bossPlayTime !! breathTime !! description !! isBossStage !! map !! name !! playTime !! triggerBossTime !! useBreathTime&lt;br /&gt;
|-&lt;br /&gt;
| 1  || [NULL]  || 100  || [NULL]  || 0  || 0  || Rubycrab  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || [NULL]  || 100  || [NULL]  || 0  || 1  || Emerald Beach  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || 10  || 100  || [NULL]  || 0  || 2  || Twinkle Town  || 15  || 10  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || [NULL]  || 100  || [NULL]  || 0  || 3  || The Aeolos  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || [NULL]  || 100  || [NULL]  || 0  || 5  || Life Wood  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || 5  || 100  || [NULL]  || 1  || 4  || Snow Moon  || [NULL]  || 8  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || 5  || 100  || [NULL]  || 1  || 6  || Arena  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || 5  || 100  || [NULL]  || 1  || 7  || Monslava  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || 5  || 100  || [NULL]  || 1  || 8  || Monslava Blue  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || 5  || 100  || [NULL]  || 1  || 9  || Devaberg  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 11  || 5  || 100  || [NULL]  || 1  || 10  || Atlantis  || 8  || 4  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 12  || 5  || 100  || [NULL]  || 1  || 11  || Temple  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 13  || [NULL]  || 100  || [NULL]  || 0  || 12  || Room of Shadow  || [NULL]  || [NULL]  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 14  || 5  || 100  || [NULL]  || 1  || 13  || Machine City  || [NULL]  || 3  || 0&lt;br /&gt;
|-&lt;br /&gt;
| 15  || 5  || 100  || [NULL]  || 1  || 14  || Dance Time  || [NULL]  || 3  || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Guardian_2_Maps ===&lt;br /&gt;
Connects a guardian (or boss guardian) to a map with a specific scenario. Each scenario has a unique set of guardians available for matches.&lt;br /&gt;
&lt;br /&gt;
=== Skill_2_Guardians ===&lt;br /&gt;
Links skills to guardians. The connection is made through `Guardian_2_Maps`, associating skills with a guardian in a specific scenario and map. If no `guardian_2_maps` entry is set, it defaults to `btItem`, which is predefined for guardian types. `btItem` is shared among similar guardian types (e.g., Dokaro and related &amp;quot;ro&amp;quot; types).&lt;br /&gt;
&lt;br /&gt;
=== S_Guardian_Multipliers ===&lt;br /&gt;
Defines multipliers for Guardian Mode, applicable for gold or experience.&lt;br /&gt;
&lt;br /&gt;
These multipliers can be linked in the `S_Relationships` table.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! description !! multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 1  || default exp multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 2  || default gold multiplier  || 1.0&lt;br /&gt;
|-&lt;br /&gt;
| 3  || exp x3  || 3.0&lt;br /&gt;
|-&lt;br /&gt;
| 4  || exp x4  || 4.0&lt;br /&gt;
|-&lt;br /&gt;
| 5  || exp x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 6  || exp x6  || 6.0&lt;br /&gt;
|-&lt;br /&gt;
| 7  || exp x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 8  || gold x7  || 7.0&lt;br /&gt;
|-&lt;br /&gt;
| 9  || gold x5  || 5.0&lt;br /&gt;
|-&lt;br /&gt;
| 10  || gold x3  || 3.5&lt;br /&gt;
|-&lt;br /&gt;
| 11  || exp x3  || 3.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationships ===&lt;br /&gt;
Defines additional connections between entities.&lt;br /&gt;
* Uses:&lt;br /&gt;
** `id_f` (`id_from`) and `id_t` (`id_to`) to establish relationships.&lt;br /&gt;
** When linking products to guardians, `productIndex` is used for `id_f`, and `guardian_2_maps.id` for `id_t`.&lt;br /&gt;
** The `type` and `role` fields control drop behavior.&lt;br /&gt;
** Relationships can be toggled for in-game use using the `status` field.&lt;br /&gt;
** The `id_f` (`id_from`) corresponds to the first entity in the relationship (e.g., Product, Multiplier).&lt;br /&gt;
** The `id_t` (`id_to`) corresponds to the target entity (e.g., Guardian, Boss Guardian, Map).&lt;br /&gt;
** For Guardian/Boss Guardian relationships, `guardian_2_maps.id` is used instead of direct Guardian IDs.&lt;br /&gt;
** Each relationship type and role determines how the relationship functions in game.&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Types ===&lt;br /&gt;
Defines different types of relationships that can exist in the game currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Product to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Product to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Product to Map&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Multiplier to Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 5  || Multiplier to Boss Guardian&lt;br /&gt;
|-&lt;br /&gt;
| 6  || Multiplier to Map&lt;br /&gt;
|-&lt;br /&gt;
| 7  || Product to Map (Guardian Mode)&lt;br /&gt;
|-&lt;br /&gt;
| 8  || Product to Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== S_Relationship_Roles ===&lt;br /&gt;
Defines the role of each relationship in gameplay currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Item Drop&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Exp Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 3  || Gold Multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 4  || Item Sell Price&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== K_Status ===&lt;br /&gt;
Defines the different status types used in game.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! id !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 1  || Active&lt;br /&gt;
|-&lt;br /&gt;
| 2  || Inactive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Commands&amp;diff=64</id>
		<title>Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Commands&amp;diff=64"/>
		<updated>2025-02-24T18:31:01Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Ingame Commands =  This page provides a list of available ingame commands for &amp;#039;&amp;#039;&amp;#039;Fantasy Tennis&amp;#039;&amp;#039;&amp;#039; within &amp;#039;&amp;#039;&amp;#039;JFTSE&amp;#039;&amp;#039;&amp;#039;. Commands must be prefixed with a `-` to execute. Some commands are &amp;#039;&amp;#039;&amp;#039;restricted to Game Masters (GMs)&amp;#039;&amp;#039;&amp;#039;.  == General Commands == These commands can be used by all players.  === 🎲 Random Mode === Random guardians will spawn instead of the default ones (boss remains the same). &amp;lt;pre&amp;gt; -random &amp;lt;/pre&amp;gt;  === 🔥 Hard Mode === Enables &amp;#039;&amp;#039;&amp;#039;Hard Mode&amp;#039;&amp;#039;&amp;#039;, inc...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ingame Commands =&lt;br /&gt;
&lt;br /&gt;
This page provides a list of available ingame commands for &#039;&#039;&#039;Fantasy Tennis&#039;&#039;&#039; within &#039;&#039;&#039;JFTSE&#039;&#039;&#039;. Commands must be prefixed with a `-` to execute. Some commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== General Commands ==&lt;br /&gt;
These commands can be used by all players.&lt;br /&gt;
&lt;br /&gt;
=== 🎲 Random Mode ===&lt;br /&gt;
Random guardians will spawn instead of the default ones (boss remains the same).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-random&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔥 Hard Mode ===&lt;br /&gt;
Enables &#039;&#039;&#039;Hard Mode&#039;&#039;&#039;, increasing enemy stats and spawning additional guardians.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-hard&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Gacha Opening ===&lt;br /&gt;
Opens gachas without animation for faster processing.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Gacha Name&amp;quot; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-og &amp;quot;Western Coin&amp;quot; 50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Note:&amp;lt;/span&amp;gt;&#039;&#039;&#039; Some gachas contain &amp;quot;ll&amp;quot; (e.g., `&amp;quot;Rare Box ll&amp;quot;`), requiring a lowercase `L` in the command.&lt;br /&gt;
&lt;br /&gt;
=== 🏆 Arcade Mode ===&lt;br /&gt;
Enters &#039;&#039;&#039;Arcade Mode&#039;&#039;&#039;. WIP.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-arcade&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Pointback ===&lt;br /&gt;
Allows players to vote for resetting the last point in &#039;&#039;&#039;[[Basic Mode]]&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-pb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
➡ &#039;&#039;&#039;Note:&#039;&#039;&#039; All players must vote using `-pb` before a new point is made.&lt;br /&gt;
&lt;br /&gt;
== GM Commands ==&lt;br /&gt;
These commands are &#039;&#039;&#039;restricted to Game Masters (GMs)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 🚫 Player Management ===&lt;br /&gt;
Banning, unbanning, and kicking players.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-ban &amp;lt;player&amp;gt;&lt;br /&gt;
-unban &amp;lt;player&amp;gt;&lt;br /&gt;
-serverKick &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 📝 Server Notice ===&lt;br /&gt;
Sets and broadcasts a &#039;&#039;&#039;server wide notice&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-sN &amp;lt;message&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🔄 Reset &amp;amp; Reload ===&lt;br /&gt;
Resets or reloads server data.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-rsLogin &amp;lt;player&amp;gt;    # Resets login status&lt;br /&gt;
-reloadScripts       # Reloads all scripts&lt;br /&gt;
-event              # Event configuration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🎁 Item &amp;amp; Gift Commands ===&lt;br /&gt;
Used to grant items, experience, or gold to players.&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;another player&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-give &amp;lt;player&amp;gt; &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give items to &#039;&#039;&#039;yourself&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-get &amp;lt;item&amp;gt; &amp;lt;amount&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send a &#039;&#039;&#039;gift&#039;&#039;&#039; to another player:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-gift &amp;lt;player&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Help Command ==&lt;br /&gt;
Displays all commands and their description.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-help&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;Notes:&#039;&#039;&#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
* Commands &#039;&#039;&#039;must always start with `-`&#039;&#039;&#039;.&lt;br /&gt;
* Some commands may have additional restrictions (e.g., requiring level 60).&lt;br /&gt;
* GM commands are &#039;&#039;&#039;restricted&#039;&#039;&#039; to authorized users.&lt;br /&gt;
&lt;br /&gt;
For further details, refer to the ingame chat.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=63</id>
		<title>Guides &amp; Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=63"/>
		<updated>2025-02-24T18:03:37Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Undo revision&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 📖 Guides &amp;amp; Tutorials ==&lt;br /&gt;
Here you can find various guides and tutorials.&lt;br /&gt;
&lt;br /&gt;
=== 📜 Available Guides ===&lt;br /&gt;
&#039;&#039;This list is automatically generated. To add a guide, create a new page and categorize it under Guides.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dpl&amp;gt;&lt;br /&gt;
category=Guides&lt;br /&gt;
ordermethod=title&lt;br /&gt;
order=ascending&lt;br /&gt;
namespace=Main&lt;br /&gt;
mode=unordered&lt;br /&gt;
format=list&lt;br /&gt;
linkstoresult=true&lt;br /&gt;
noresultsheader=❌ No guides found. Be the first to add one!&lt;br /&gt;
&amp;lt;/dpl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🛠 Contributing ==&lt;br /&gt;
* &#039;&#039;&#039;Want to add a guide?&#039;&#039;&#039; Create a new page and add &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Guides]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at the bottom.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=62</id>
		<title>Guides &amp; Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=62"/>
		<updated>2025-02-24T18:02:27Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here you can find various guides and tutorials.&lt;br /&gt;
&lt;br /&gt;
=== 📜 Available Guides ===&lt;br /&gt;
&#039;&#039;This list is automatically generated. To add a guide, create a new page and categorize it under Guides.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dpl&amp;gt;&lt;br /&gt;
category=Guides&lt;br /&gt;
ordermethod=title&lt;br /&gt;
order=ascending&lt;br /&gt;
namespace=Main&lt;br /&gt;
mode=unordered&lt;br /&gt;
format=list&lt;br /&gt;
linkstoresult=true&lt;br /&gt;
noresultsheader=❌ No guides found. Be the first to add one!&lt;br /&gt;
&amp;lt;/dpl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🛠 Contributing ==&lt;br /&gt;
* &#039;&#039;&#039;Want to add a guide?&#039;&#039;&#039; Create a new page and add &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Guides]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at the bottom.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=61</id>
		<title>JFTSE Wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=61"/>
		<updated>2025-02-19T18:28:31Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= JFTSE Wiki =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-size: 16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Please [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account to edit and contribute.&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Wiki is a community driven knowledge base for everything related to &#039;&#039;&#039;JFTSE and Fantasy Tennis&#039;&#039;&#039;. Here you will find guides, tutorials, tips, tricks, and information about gameplay mechanics, server configurations and much more.&lt;br /&gt;
&lt;br /&gt;
This Wiki should be considered a place where community members can create new informative webpages that cover specific topics, &lt;br /&gt;
and where fellow community members can contribute to and improve existing pages.&lt;br /&gt;
&lt;br /&gt;
We strongly believe in the idea that this Wiki should be a free and open method of overlaying information to everyone. Therefore, our stance is that everyone should be able to contribute to this Wiki, as long as the information is accurate and relevant. As a guest, you are free to access and read all the information the Wiki has to offer. As a community member, you are free to contribute to the Wiki by creating new pages, editing existing pages, and discussing the content of the Wiki with other community members as long as you conform to the [[JFTSE Wiki:Community Rules|Community Rules]].&lt;br /&gt;
&lt;br /&gt;
= 📚 Usage And Information =&lt;br /&gt;
=== Information ===&lt;br /&gt;
* [[About_JFTSE|About JFTSE]]&lt;br /&gt;
* [[About_Fantasy_Tennis|About Fantasy Tennis]]&lt;br /&gt;
* [[JFTSE Wiki:Community Rules|Community Rules]]&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
&amp;lt;strong&amp;gt;Only registered JFTSE users can edit pages.&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
To contribute, [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account and help expand the knowledge base!&amp;lt;br&amp;gt;&lt;br /&gt;
Please read and follow the [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] before contributing.&lt;br /&gt;
&lt;br /&gt;
= 🛠 Getting Started =&lt;br /&gt;
* [[Game Lore]] - Dive into the world of Fantasy Tennis.&lt;br /&gt;
* [[Game Installation Guide]] - Step-by-step guide on installing the game.&lt;br /&gt;
* [[Beginner&#039;s Guide]] - Basics of gameplay, controls and UI.&lt;br /&gt;
* [[Gameplay Mechanics]] - Strategies, combos and in-depth gameplay mechanics.&lt;br /&gt;
* [[Troubleshooting|Troubleshooting &amp;amp; Fixes]] - Solutions for common issues.&lt;br /&gt;
&lt;br /&gt;
= 📖 Game Information =&lt;br /&gt;
* [[Characters]] - Information about the characters in Fantasy Tennis.&lt;br /&gt;
* [[Items]] - List of items and their effects.&lt;br /&gt;
* [[Skills]] - List of skills and their effects.&lt;br /&gt;
* [[Maps]] - Learn about the different maps in Fantasy Tennis.&lt;br /&gt;
* [[Game Modes]] - Information about the different game modes.&lt;br /&gt;
* [[Guides &amp;amp; Tutorials]] - Learn tips and tricks from experienced players.&lt;br /&gt;
&lt;br /&gt;
= 📜 Server Information =&lt;br /&gt;
* [[Database Schema &amp;amp; Cheatsheet]] - Database Schema used for Fantasy Tennis &amp;amp; Cheatsheet.&lt;br /&gt;
* [[Server Configuration]] - Information about server configuration.&lt;br /&gt;
&lt;br /&gt;
= 🔗 Useful Links =&lt;br /&gt;
* [https://jftse.com/ JFTSE Website]&lt;br /&gt;
* [https://discord.gg/MwamzbMTMy Discord]&lt;br /&gt;
* [[Special:RecentChanges|Recent Changes]]&lt;br /&gt;
* [[Special:AllPages|All Pages]]&lt;br /&gt;
* [[Special:Random|Random Page]]&lt;br /&gt;
* [[Special:Categories|Categories]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Category:Server&amp;diff=60</id>
		<title>Category:Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Category:Server&amp;diff=60"/>
		<updated>2025-02-19T18:26:57Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=59</id>
		<title>Database Schema &amp; Cheatsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Database_Schema_%26_Cheatsheet&amp;diff=59"/>
		<updated>2025-02-19T18:26:44Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= Database Schema &amp;amp; Cheatsheet = This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.  == Schema == Database Schema  Category:Server&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Database Schema &amp;amp; Cheatsheet =&lt;br /&gt;
This page provides an overview of the database structure used in Fantasy Tennis, showing the key tables, their columns, and relationships. The schema diagram below visually represents how different entities connect within the system.&lt;br /&gt;
&lt;br /&gt;
== Schema ==&lt;br /&gt;
[[File:Db-entities.svg|frameless|600px|left|alt=Database Schema|Database Schema]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=File:Db-entities.svg&amp;diff=58</id>
		<title>File:Db-entities.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=File:Db-entities.svg&amp;diff=58"/>
		<updated>2025-02-19T18:09:16Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki:Community_Rules&amp;diff=57</id>
		<title>JFTSE Wiki:Community Rules</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki:Community_Rules&amp;diff=57"/>
		<updated>2025-02-19T14:49:22Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Protected &amp;quot;JFTSE Wiki:Community Rules&amp;quot; ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= 📜 JFTSE Wiki Community Rules =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;! This community driven resource exists to provide accurate and well structured information about &#039;&#039;&#039;JFTSE&#039;&#039;&#039;, &#039;&#039;&#039;Fantasy Tennis&#039;&#039;&#039;, and related topics. To ensure a &#039;&#039;&#039;productive and respectful environment&#039;&#039;&#039;, all contributors must adhere to the following &#039;&#039;&#039;community rules&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
By editing or interacting with this wiki, you agree to follow these guidelines. If you violate these rules, your access may be &#039;&#039;&#039;restricted or revoked&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 🎯 General Guidelines ==&lt;br /&gt;
* &#039;&#039;&#039;Be Respectful&#039;&#039;&#039; – Treat others with courtesy. No harassment, personal attacks, or hate speech.&lt;br /&gt;
* &#039;&#039;&#039;Stay On-Topic&#039;&#039;&#039; – Content should be &#039;&#039;&#039;relevant&#039;&#039;&#039; to Fantasy Tennis, the JFTSE project, or related technical discussions.&lt;br /&gt;
* &#039;&#039;&#039;No Vandalism&#039;&#039;&#039; – Do not deliberately edit pages with misleading, false, or offensive content.&lt;br /&gt;
* &#039;&#039;&#039;Follow Editing Standards&#039;&#039;&#039; – Articles should be &#039;&#039;&#039;clear, structured, and well written&#039;&#039;&#039;. If unsure, refer to [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]].&lt;br /&gt;
* &#039;&#039;&#039;Use Reliable Information&#039;&#039;&#039; – Do not spread misinformation, speculation, or unverified claims.&lt;br /&gt;
&lt;br /&gt;
== 🚫 Prohibited Content ==&lt;br /&gt;
The following &#039;&#039;&#039;types of content&#039;&#039;&#039; are strictly &#039;&#039;&#039;forbidden&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;NSFW/Adult Content&#039;&#039;&#039; – No pornography, gore, or extreme violence.&lt;br /&gt;
* &#039;&#039;&#039;Hate Speech &amp;amp; Discrimination&#039;&#039;&#039; – No racism, sexism, homophobia, or any form of discrimination.&lt;br /&gt;
* &#039;&#039;&#039;Illegal Activities&#039;&#039;&#039; – No piracy or promotion of illegal exploits. Technical discussions regarding game files, reverse engineering for educational purposes, or modifications intended to improve gameplay are permitted, provided they do not encourage or facilitate cheating or unauthorized exploitation.&lt;br /&gt;
* &#039;&#039;&#039;Personal Information&#039;&#039;&#039; – Do not share private data (emails, addresses, passwords, etc.).&lt;br /&gt;
* &#039;&#039;&#039;Plagiarism &amp;amp; Copyright Violations&#039;&#039;&#039; – Use &#039;&#039;&#039;only freely available or properly credited material&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 🖊 Editing &amp;amp; Contribution Rules ==&lt;br /&gt;
* &#039;&#039;&#039;Constructive Edits Only&#039;&#039;&#039; – Make meaningful contributions. &#039;&#039;&#039;Do not spam or insert irrelevant content&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;Follow Formatting Standards&#039;&#039;&#039; – See [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] for formatting best practices.&lt;br /&gt;
* &#039;&#039;&#039;Use English&#039;&#039;&#039; – The official language of the wiki is &#039;&#039;&#039;English&#039;&#039;&#039; for consistency.&lt;br /&gt;
* &#039;&#039;&#039;Do Not Advertise&#039;&#039;&#039; – No self promotion, external advertisements, or linking to unrelated projects.&lt;br /&gt;
&lt;br /&gt;
== 🔨 Enforcement &amp;amp; Moderation ==&lt;br /&gt;
The JFTSE Wiki moderation team reserves the right to &#039;&#039;&#039;warn, restrict, or ban users&#039;&#039;&#039; who repeatedly &#039;&#039;&#039;violate these rules&#039;&#039;&#039;. Actions may include:&lt;br /&gt;
* &#039;&#039;&#039;Warnings&#039;&#039;&#039; – Minor infractions result in a notice.&lt;br /&gt;
* &#039;&#039;&#039;Temporary Bans&#039;&#039;&#039; – Severe or repeated offenses may lead to a temporary suspension.&lt;br /&gt;
* &#039;&#039;&#039;Permanent Bans&#039;&#039;&#039; – Accounts engaging in &#039;&#039;&#039;serious abuse&#039;&#039;&#039; (vandalism, hate speech, illegal content) may be &#039;&#039;&#039;permanently banned&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 📄 Related Policies ==&lt;br /&gt;
For further details on your rights and responsibilities, refer to:&lt;br /&gt;
* [[JFTSE Wiki:Privacy_policy|Privacy Policy]] – How your data is handled.&lt;br /&gt;
* [https://jftse.com/legal?policy=terms JFTSE Terms of Service] – General platform-wide rules.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By participating in the JFTSE Wiki, you acknowledge and agree to &#039;&#039;&#039;abide by these rules&#039;&#039;&#039;. Help us maintain a &#039;&#039;&#039;useful and welcoming&#039;&#039;&#039; resource for the community!&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki:Community_Rules&amp;diff=56</id>
		<title>JFTSE Wiki:Community Rules</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki:Community_Rules&amp;diff=56"/>
		<updated>2025-02-19T14:43:19Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: Created page with &amp;quot;= 📜 JFTSE Wiki Community Rules =  Welcome to the &amp;#039;&amp;#039;&amp;#039;JFTSE Wiki&amp;#039;&amp;#039;&amp;#039;! This community driven resource exists to provide accurate and well structured information about &amp;#039;&amp;#039;&amp;#039;JFTSE&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;Fantasy Tennis&amp;#039;&amp;#039;&amp;#039;, and related topics. To ensure a &amp;#039;&amp;#039;&amp;#039;productive and respectful environment&amp;#039;&amp;#039;&amp;#039;, all contributors must adhere to the following &amp;#039;&amp;#039;&amp;#039;community rules&amp;#039;&amp;#039;&amp;#039;.  By editing or interacting with this wiki, you agree to follow these guidelines. If you violate these rules, your access may be...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= 📜 JFTSE Wiki Community Rules =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;! This community driven resource exists to provide accurate and well structured information about &#039;&#039;&#039;JFTSE&#039;&#039;&#039;, &#039;&#039;&#039;Fantasy Tennis&#039;&#039;&#039;, and related topics. To ensure a &#039;&#039;&#039;productive and respectful environment&#039;&#039;&#039;, all contributors must adhere to the following &#039;&#039;&#039;community rules&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
By editing or interacting with this wiki, you agree to follow these guidelines. If you violate these rules, your access may be &#039;&#039;&#039;restricted or revoked&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 🎯 General Guidelines ==&lt;br /&gt;
* &#039;&#039;&#039;Be Respectful&#039;&#039;&#039; – Treat others with courtesy. No harassment, personal attacks, or hate speech.&lt;br /&gt;
* &#039;&#039;&#039;Stay On-Topic&#039;&#039;&#039; – Content should be &#039;&#039;&#039;relevant&#039;&#039;&#039; to Fantasy Tennis, the JFTSE project, or related technical discussions.&lt;br /&gt;
* &#039;&#039;&#039;No Vandalism&#039;&#039;&#039; – Do not deliberately edit pages with misleading, false, or offensive content.&lt;br /&gt;
* &#039;&#039;&#039;Follow Editing Standards&#039;&#039;&#039; – Articles should be &#039;&#039;&#039;clear, structured, and well written&#039;&#039;&#039;. If unsure, refer to [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]].&lt;br /&gt;
* &#039;&#039;&#039;Use Reliable Information&#039;&#039;&#039; – Do not spread misinformation, speculation, or unverified claims.&lt;br /&gt;
&lt;br /&gt;
== 🚫 Prohibited Content ==&lt;br /&gt;
The following &#039;&#039;&#039;types of content&#039;&#039;&#039; are strictly &#039;&#039;&#039;forbidden&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;NSFW/Adult Content&#039;&#039;&#039; – No pornography, gore, or extreme violence.&lt;br /&gt;
* &#039;&#039;&#039;Hate Speech &amp;amp; Discrimination&#039;&#039;&#039; – No racism, sexism, homophobia, or any form of discrimination.&lt;br /&gt;
* &#039;&#039;&#039;Illegal Activities&#039;&#039;&#039; – No piracy or promotion of illegal exploits. Technical discussions regarding game files, reverse engineering for educational purposes, or modifications intended to improve gameplay are permitted, provided they do not encourage or facilitate cheating or unauthorized exploitation.&lt;br /&gt;
* &#039;&#039;&#039;Personal Information&#039;&#039;&#039; – Do not share private data (emails, addresses, passwords, etc.).&lt;br /&gt;
* &#039;&#039;&#039;Plagiarism &amp;amp; Copyright Violations&#039;&#039;&#039; – Use &#039;&#039;&#039;only freely available or properly credited material&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 🖊 Editing &amp;amp; Contribution Rules ==&lt;br /&gt;
* &#039;&#039;&#039;Constructive Edits Only&#039;&#039;&#039; – Make meaningful contributions. &#039;&#039;&#039;Do not spam or insert irrelevant content&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;Follow Formatting Standards&#039;&#039;&#039; – See [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] for formatting best practices.&lt;br /&gt;
* &#039;&#039;&#039;Use English&#039;&#039;&#039; – The official language of the wiki is &#039;&#039;&#039;English&#039;&#039;&#039; for consistency.&lt;br /&gt;
* &#039;&#039;&#039;Do Not Advertise&#039;&#039;&#039; – No self promotion, external advertisements, or linking to unrelated projects.&lt;br /&gt;
&lt;br /&gt;
== 🔨 Enforcement &amp;amp; Moderation ==&lt;br /&gt;
The JFTSE Wiki moderation team reserves the right to &#039;&#039;&#039;warn, restrict, or ban users&#039;&#039;&#039; who repeatedly &#039;&#039;&#039;violate these rules&#039;&#039;&#039;. Actions may include:&lt;br /&gt;
* &#039;&#039;&#039;Warnings&#039;&#039;&#039; – Minor infractions result in a notice.&lt;br /&gt;
* &#039;&#039;&#039;Temporary Bans&#039;&#039;&#039; – Severe or repeated offenses may lead to a temporary suspension.&lt;br /&gt;
* &#039;&#039;&#039;Permanent Bans&#039;&#039;&#039; – Accounts engaging in &#039;&#039;&#039;serious abuse&#039;&#039;&#039; (vandalism, hate speech, illegal content) may be &#039;&#039;&#039;permanently banned&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== 📄 Related Policies ==&lt;br /&gt;
For further details on your rights and responsibilities, refer to:&lt;br /&gt;
* [[JFTSE Wiki:Privacy_policy|Privacy Policy]] – How your data is handled.&lt;br /&gt;
* [https://jftse.com/legal?policy=terms JFTSE Terms of Service] – General platform-wide rules.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-----------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By participating in the JFTSE Wiki, you acknowledge and agree to &#039;&#039;&#039;abide by these rules&#039;&#039;&#039;. Help us maintain a &#039;&#039;&#039;useful and welcoming&#039;&#039;&#039; resource for the community!&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=55</id>
		<title>Guides &amp; Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=55"/>
		<updated>2025-02-19T13:57:59Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 📖 Guides &amp;amp; Tutorials ==&lt;br /&gt;
Here you can find various guides and tutorials.&lt;br /&gt;
&lt;br /&gt;
=== 📜 Available Guides ===&lt;br /&gt;
&#039;&#039;This list is automatically generated. To add a guide, create a new page and categorize it under Guides.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dpl&amp;gt;&lt;br /&gt;
category=Guides&lt;br /&gt;
ordermethod=title&lt;br /&gt;
order=ascending&lt;br /&gt;
namespace=Main&lt;br /&gt;
mode=unordered&lt;br /&gt;
format=list&lt;br /&gt;
linkstoresult=true&lt;br /&gt;
noresultsheader=❌ No guides found. Be the first to add one!&lt;br /&gt;
&amp;lt;/dpl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🛠 Contributing ==&lt;br /&gt;
* &#039;&#039;&#039;Want to add a guide?&#039;&#039;&#039; Create a new page and add &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Guides]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at the bottom.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=54</id>
		<title>Guides &amp; Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=Guides_%26_Tutorials&amp;diff=54"/>
		<updated>2025-02-19T13:55:28Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 📖 Guides &amp;amp; Tutorials ==&lt;br /&gt;
Here you can find various guides and tutorials.&lt;br /&gt;
&lt;br /&gt;
=== 📜 Available Guides ===&lt;br /&gt;
&#039;&#039;This list is automatically generated. To add a guide, create a new page and categorize it under Guides.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dpl&amp;gt;&lt;br /&gt;
category=Guides&lt;br /&gt;
ordermethod=title&lt;br /&gt;
order=ascending&lt;br /&gt;
namespace=Main&lt;br /&gt;
mode=unordered&lt;br /&gt;
noresultsheader=❌ No guides found. Be the first to add one!&lt;br /&gt;
&amp;lt;/dpl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🛠 Contributing ==&lt;br /&gt;
* &#039;&#039;&#039;Want to add a guide?&#039;&#039;&#039; Create a new page and add &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Guides]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at the bottom.&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
	<entry>
		<id>https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=53</id>
		<title>JFTSE Wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.jftse.com/index.php?title=JFTSE_Wiki&amp;diff=53"/>
		<updated>2025-02-19T13:44:55Z</updated>

		<summary type="html">&lt;p&gt;XxharCs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= JFTSE Wiki =&lt;br /&gt;
&lt;br /&gt;
Welcome to the &#039;&#039;&#039;JFTSE Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-size: 16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Please [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account to edit and contribute.&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Wiki is a community driven knowledge base for everything related to &#039;&#039;&#039;JFTSE and Fantasy Tennis&#039;&#039;&#039;. Here you will find guides, tutorials, tips, tricks, and information about gameplay mechanics, server configurations and much more.&lt;br /&gt;
&lt;br /&gt;
This Wiki should be considered a place where community members can create new informative webpages that cover specific topics, &lt;br /&gt;
and where fellow community members can contribute to and improve existing pages.&lt;br /&gt;
&lt;br /&gt;
We strongly believe in the idea that this Wiki should be a free and open method of overlaying information to everyone. Therefore, our stance is that everyone should be able to contribute to this Wiki, as long as the information is accurate and relevant. As a guest, you are free to access and read all the information the Wiki has to offer. As a community member, you are free to contribute to the Wiki by creating new pages, editing existing pages, and discussing the content of the Wiki with other community members as long as you conform to the [[JFTSE Wiki:Community Rules|Community Rules]].&lt;br /&gt;
&lt;br /&gt;
= 📚 Usage And Information =&lt;br /&gt;
=== Information ===&lt;br /&gt;
* [[About_JFTSE|About JFTSE]]&lt;br /&gt;
* [[About_Fantasy_Tennis|About Fantasy Tennis]]&lt;br /&gt;
* [[JFTSE Wiki:Community Rules|Community Rules]]&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
&amp;lt;strong&amp;gt;Only registered JFTSE users can edit pages.&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
To contribute, [https://wiki.jftse.com/index.php?title=Special:UserLogin Log In] with your JFTSE account and help expand the knowledge base!&amp;lt;br&amp;gt;&lt;br /&gt;
Please read and follow the [[JFTSE Wiki:Wiki Guidelines|Wiki Guidelines]] before contributing.&lt;br /&gt;
&lt;br /&gt;
= 🛠 Getting Started =&lt;br /&gt;
* [[Game Lore]] - Dive into the world of Fantasy Tennis.&lt;br /&gt;
* [[Game Installation Guide]] - Step-by-step guide on installing the game.&lt;br /&gt;
* [[Beginner&#039;s Guide]] - Basics of gameplay, controls and UI.&lt;br /&gt;
* [[Gameplay Mechanics]] - Strategies, combos and in-depth gameplay mechanics.&lt;br /&gt;
* [[Troubleshooting|Troubleshooting &amp;amp; Fixes]] - Solutions for common issues.&lt;br /&gt;
&lt;br /&gt;
= 📖 Game Information =&lt;br /&gt;
* [[Characters]] - Information about the characters in Fantasy Tennis.&lt;br /&gt;
* [[Items]] - List of items and their effects.&lt;br /&gt;
* [[Skills]] - List of skills and their effects.&lt;br /&gt;
* [[Maps]] - Learn about the different maps in Fantasy Tennis.&lt;br /&gt;
* [[Game Modes]] - Information about the different game modes.&lt;br /&gt;
* [[Guides &amp;amp; Tutorials]] - Learn tips and tricks from experienced players.&lt;br /&gt;
&lt;br /&gt;
= 📜 Server Information =&lt;br /&gt;
* [[Server Configuration]] - Information about server configuration.&lt;br /&gt;
&lt;br /&gt;
= 🔗 Useful Links =&lt;br /&gt;
* [https://jftse.com/ JFTSE Website]&lt;br /&gt;
* [https://discord.gg/MwamzbMTMy Discord]&lt;br /&gt;
* [[Special:RecentChanges|Recent Changes]]&lt;br /&gt;
* [[Special:AllPages|All Pages]]&lt;br /&gt;
* [[Special:Random|Random Page]]&lt;br /&gt;
* [[Special:Categories|Categories]]&lt;/div&gt;</summary>
		<author><name>XxharCs</name></author>
	</entry>
</feed>