Complete Character Bazaar System (Server + Client + Website) for Crystal Server (TFS 1.x), OTClient Redemption & MyAAC
Hello everyone,
I am releasing a complete, production-ready Character Bazaar system. This is a fully functional system containing database tables, server-side validation, client UI integrated into the Store, website auction listing, bid handling with transferable coins, login blocking, and automated auction finalization.
Engine & Platform Bases:
What this system does:
Package tree
The attached zip contains:
Prerequisites & Requirements
To install and use this package, you will need:
Please note: Since many Open Tibia servers use custom codebases, you might need to adapt some function names for coins, player login hooks, or Store layouts to match your specific version.
Important concept
The Character Bazaar has three parts:
1. Server
2. Client
3. Website
Do not install only one part. If you install only the client, nothing real will
happen. If you install only the website, auctions will not be created from the
game. If you install only the server, players have no clean UI.
Database
Copy:
to your server migrations folder.
Example:
If your server already has migration 64, rename it to your next number, for
example:
The migration creates:
Database tables explained like simple words
This is the main auction table. One row means one character auction.
This is the bid history. Every bid creates one row.
This is the operational history. It stores things like created, bid, cancelled,
expired and finished.
Server Lua installation
Copy:
to:
Copy:
to:
Then open:
Inside the player login function, add:
Server constants
Inside
Meaning:
C++ server installation
Lua creates auctions, but C++ controls login and character list.
Please refer to the C++ installation section inside the package's README.md file. It explains in detail the three files you need to patch:
1. Hide auctioned characters from the account character list (
2. Add
3. Block direct login attempts with a clear warning message (
You must do three things:
1. Hide auctioned characters from the character list.
2. Add
3. Block direct login attempts with a clear message.
The direct login message is:
Why is this needed?
Because a player could still try to enter the character directly after the
auction exists. The server must be the authority. Never trust only the client.
Client installation
Copy:
to:
Copy:
to:
Open:
Make sure
Open:
Add a button somewhere in your Store top area:
Open:
Add:
When your Store parses coin balance, call:
When Store/game ends, close Bazaar:
When Store terminates:
More detailed client instructions and UI anchors placement guides are inside the package's README.md file.
Website installation
Copy:
to:
Copy:
to:
Then create a menu entry in MyAAC admin panel pointing to:
If you prefer SQL, check:
After installing, your page should be:
Fast Integration & AI-Assisted Merging Guide (For Quick Setup)
To speed up the integration process and prevent manual compilation or merge errors, we have documented a fast-setup workflow. You can apply the changes manually or use any advanced LLM (such as Claude or ChatGPT) to merge the code blocks into your custom files automatically.
Option 1: Manual Directory Setup
1. Copy Files:
- Open the attached zip file.
- Drag and drop the files from the
,
, and
folders into your server, client, and website directories respectively (match the folder names exactly).
2. Run Database Query:
- You can import the SQL structure manually by copying
to your server's
folder (it will execute automatically on startup). Alternatively, open your database tool (like phpMyAdmin or HeidiSQL), select your game database, click the "SQL" tab, and run the schema query.
3. Website Menu Setup:
- Go to your MyAAC admin panel, click on Menu, and add a new button pointing to
. Or execute the SQL code inside
in your database.
---
Option 2: Automated Merge using AI/LLMs
If you want to save time and ensure correct syntax when merging C++ or Lua patches, you can feed these pre-configured prompts directly to an AI assistant.
Prompt 1: For LUA edits (e.g., login.lua)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
Prompt 2: For C++ edits (e.g., protocolgame.cpp or account_repository_db.cpp)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
Prompt 3: For OTClient modifications (e.g., game_store.lua)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
---
How the complete flow works
Step by step:
1. Player logs into the game.
2. Player opens Store.
3. Player opens Character Bazaar.
4. Client asks server for requirements using Extended Opcode 207.
5. Server validates the character.
6. Client shows rules.
7. Player chooses price, date, highlighted items and sale arguments.
8. Player confirms.
9. Server charges auction fee from transferable coins.
10. Server creates the auction row in database.
11. Server kicks/logs out the character.
12. Character disappears from character list.
13. Website lists the auction.
14. Another account bids.
15. Website holds highest bidder transferable coins.
16. If another bid happens, previous bidder is refunded.
17. When auction expires, server finalizes.
18. Character account_id changes to the winner account.
19. Seller receives payout minus commission.
20. Winner can login the bought character.
Auction status values
Security notes
Do not trust the client.
The client only asks for auction creation. The server must validate:
The included server file already validates the most important checks.
Known placeholders
Some checks are included as placeholders because not every Crystal fork has the
same systems:
If your server has those systems, replace the placeholder
validation.
Testing checklist
Please check the Verifying & Testing section inside the README.md for a detailed step-by-step test workflow to validate the creation, database entries, C++ logic locks, web bids, and finalization.
Short version:
1. Start server.
2. Check database tables exist.
3. Login a test character.
4. Open Store -> Character Bazaar.
5. Create auction.
6. Confirm character is kicked.
7. Confirm character is hidden from character list.
8. Try direct login and confirm the Bazaar login error appears.
9. Open website page.
10. Bid from another account.
11. Confirm previous bidder refund works.
12. Let auction expire.
13. Confirm character transfers to winner.
14. Confirm seller gets paid.
Common problems
Problem: button opens nothing
Check if
Problem: Extended Opcode does nothing
Check if both client and server use the same opcode:
Check if login registers:
Problem: site page is blank
Check if your MyAAC template path is correct:
Check PHP errors.
Problem: auctioned character still appears in character list
You did not apply the C++
Problem: auctioned character can still login
You did not apply the C++
Problem: coin balance is wrong
Your fork probably uses different names for normal/transferable coins. Adapt
only the coin helper functions. Do not change the auction tables.
Final note
This is a base made for real use, not just a visual system. Still, every OT
server has custom code, so read the included install guides and adapt carefully.
Files are included in the attached zip.
Hello everyone,
I am releasing a complete, production-ready Character Bazaar system. This is a fully functional system containing database tables, server-side validation, client UI integrated into the Store, website auction listing, bid handling with transferable coins, login blocking, and automated auction finalization.
Engine & Platform Bases:
- Server Engine: Crystal Server (based on The Forgotten Server 1.4+ / TFS 1.x)
- Client Engine: OTClient Redemption (by Mehah) (using Extended Opcodes)
- Website Engine: MyAAC (version 1.8.x) (with Twig template system)
What this system does:
- Allows players to create a character auction from inside the client Store module.
- Validates if the character is eligible to be auctioned.
- Charges a configurable auction fee in transferable coins.
- Automatically kicks and removes the character from the game after creation.
- Hides auctioned characters from the account character list.
- Blocks direct login attempts on auctioned characters.
- Displays a clear login error if a player attempts to enter an auctioned character.
- Lists all active and finished auctions on the website.
- Allows players from other accounts to bid using transferable coins.
- Refunds the previous highest bidder immediately when outbid.
- Automatically transfers the character ownership to the winner's account once the auction ends.
- Pays the seller their coins, minus a configurable commission fee.
- Stores detailed bid and auction histories in the database.
Package tree
The attached zip contains:
Code:
character_bazaar/
README.md
client/
modules/game_store/classes/bazaar.lua
modules/game_store/style/bazaar.otui
server/
data/libs/systems/character_bazaar_json.lua
data/migrations/64_character_bazaar.lua
data/scripts/creaturescripts/others/character_bazaar.lua
site/
system/pages/character-bazaar.php
system/templates/character-bazaar.html.twig
sql/myaac_menu.sql
Prerequisites & Requirements
To install and use this package, you will need:
- A game server based on Crystal Server (or a recent fork of The Forgotten Server 1.x) with Extended Opcode support.
- A database with standard
accountsandplayerstables, plus support for Transferable Coins. - OTClient Redemption (by Mehah) with a working Store module.
- MyAAC (version 1.8.x) or any compatible web server layout using PHP and Twig template engines.
Please note: Since many Open Tibia servers use custom codebases, you might need to adapt some function names for coins, player login hooks, or Store layouts to match your specific version.
Important concept
The Character Bazaar has three parts:
1. Server
2. Client
3. Website
Do not install only one part. If you install only the client, nothing real will
happen. If you install only the website, auctions will not be created from the
game. If you install only the server, players have no clean UI.
Database
Copy:
Code:
server/data/migrations/64_character_bazaar.lua
to your server migrations folder.
Example:
Code:
data/migrations/64.lua
If your server already has migration 64, rename it to your next number, for
example:
Code:
data/migrations/65.lua
The migration creates:
Code:
character_auctions
character_auction_bids
character_auction_history
Database tables explained like simple words
character_auctionsThis is the main auction table. One row means one character auction.
character_auction_bidsThis is the bid history. Every bid creates one row.
character_auction_historyThis is the operational history. It stores things like created, bid, cancelled,
expired and finished.
Server Lua installation
Copy:
Code:
server/data/libs/systems/character_bazaar_json.lua
to:
Code:
data/libs/systems/character_bazaar_json.lua
Copy:
Code:
server/data/scripts/creaturescripts/others/character_bazaar.lua
to:
Code:
data/scripts/creaturescripts/others/character_bazaar.lua
Then open:
Code:
data/scripts/creaturescripts/player/login.lua
Inside the player login function, add:
LUA:
player:registerEvent("CharacterBazaarExtendedOpcode")
Server constants
Inside
character_bazaar.lua you can configure:
LUA:
local BAZAAR_OPCODE = 207
local MIN_LEVEL = 50
local MIN_DURATION = 24 * 60 * 60
local MAX_DURATION = 7 * 24 * 60 * 60
local MIN_PRICE = 100
local AUCTION_FEE = 50
local COMMISSION_PERCENT = 10
Meaning:
BAZAAR_OPCODE: Extended Opcode used by client and server.MIN_LEVEL: minimum level to auction a character.MIN_DURATION: minimum auction duration in seconds.MAX_DURATION: maximum auction duration in seconds.MIN_PRICE: minimum starting price.AUCTION_FEE: fee paid to create an auction.COMMISSION_PERCENT: commission removed from seller payout.
C++ server installation
Lua creates auctions, but C++ controls login and character list.
Please refer to the C++ installation section inside the package's README.md file. It explains in detail the three files you need to patch:
1. Hide auctioned characters from the account character list (
account_repository_db.cpp).2. Add
IOLoginData::isPlayerOnActiveCharacterAuction(...) (iologindata.cpp/iologindata.hpp).3. Block direct login attempts with a clear warning message (
protocolgame.cpp).You must do three things:
1. Hide auctioned characters from the character list.
2. Add
IOLoginData::isPlayerOnActiveCharacterAuction(...).3. Block direct login attempts with a clear message.
The direct login message is:
Code:
This character is currently listed on the Character Bazaar and cannot enter the game until the auction finishes or is cancelled.
Why is this needed?
Because a player could still try to enter the character directly after the
auction exists. The server must be the authority. Never trust only the client.
Client installation
Copy:
Code:
client/modules/game_store/classes/bazaar.lua
to:
Code:
modules/game_store/classes/bazaar.lua
Copy:
Code:
client/modules/game_store/style/bazaar.otui
to:
Code:
modules/game_store/style/bazaar.otui
Open:
Code:
modules/game_store/game_store.otmod
Make sure
classes/bazaar loads before game_store:
Code:
scripts: [ classes/bazaar, game_store ]
Open:
Code:
modules/game_store/game_store.otui
Add a button somewhere in your Store top area:
Code:
Button
id: auctionCharacter
anchors.top: transferPoints.top
!tooltip: tr('Setup an auction to sell your current character.')
anchors.left: transferPoints.right
margin-left: 5
icon-align: center
icon-source: images/icon-trade
size: 64 20
@onClick: modules.game_store.openBaazarWindow()
Open:
Code:
modules/game_store/game_store.lua
Add:
LUA:
function openBazaar()
if syncStoreCoinLabelsFromPlayer then
syncStoreCoinLabelsFromPlayer()
end
Bazaar:open()
end
function openBaazarWindow()
openBazaar()
end
When your Store parses coin balance, call:
LUA:
if Bazaar and Bazaar.updateCoins then
Bazaar:updateCoins()
end
When Store/game ends, close Bazaar:
LUA:
if Bazaar then
Bazaar:close()
end
When Store terminates:
LUA:
if Bazaar then
Bazaar:terminate()
end
More detailed client instructions and UI anchors placement guides are inside the package's README.md file.
Website installation
Copy:
Code:
site/system/pages/character-bazaar.php
to:
Code:
system/pages/character-bazaar.php
Copy:
Code:
site/system/templates/character-bazaar.html.twig
to:
Code:
system/templates/character-bazaar.html.twig
Then create a menu entry in MyAAC admin panel pointing to:
Code:
character-bazaar
If you prefer SQL, check:
Code:
site/sql/myaac_menu.sql
After installing, your page should be:
Code:
https://yourdomain.com/character-bazaar
Fast Integration & AI-Assisted Merging Guide (For Quick Setup)
To speed up the integration process and prevent manual compilation or merge errors, we have documented a fast-setup workflow. You can apply the changes manually or use any advanced LLM (such as Claude or ChatGPT) to merge the code blocks into your custom files automatically.
Option 1: Manual Directory Setup
1. Copy Files:
- Open the attached zip file.
- Drag and drop the files from the
Code:
client
Code:
server
Code:
site
2. Run Database Query:
- You can import the SQL structure manually by copying
Code:
64_character_bazaar.lua
Code:
data/migrations/
3. Website Menu Setup:
- Go to your MyAAC admin panel, click on Menu, and add a new button pointing to
Code:
character-bazaar
Code:
site/sql/myaac_menu.sql
---
Option 2: Automated Merge using AI/LLMs
If you want to save time and ensure correct syntax when merging C++ or Lua patches, you can feed these pre-configured prompts directly to an AI assistant.
Prompt 1: For LUA edits (e.g., login.lua)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
Prompt 2: For C++ edits (e.g., protocolgame.cpp or account_repository_db.cpp)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
Prompt 3: For OTClient modifications (e.g., game_store.lua)
Copy the text below, paste it into ChatGPT/Claude, and replace the brackets with your code:
---
How the complete flow works
Step by step:
1. Player logs into the game.
2. Player opens Store.
3. Player opens Character Bazaar.
4. Client asks server for requirements using Extended Opcode 207.
5. Server validates the character.
6. Client shows rules.
7. Player chooses price, date, highlighted items and sale arguments.
8. Player confirms.
9. Server charges auction fee from transferable coins.
10. Server creates the auction row in database.
11. Server kicks/logs out the character.
12. Character disappears from character list.
13. Website lists the auction.
14. Another account bids.
15. Website holds highest bidder transferable coins.
16. If another bid happens, previous bidder is refunded.
17. When auction expires, server finalizes.
18. Character account_id changes to the winner account.
19. Seller receives payout minus commission.
20. Winner can login the bought character.
Auction status values
Code:
1 = active
2 = finished
3 = cancelled
Security notes
Do not trust the client.
The client only asks for auction creation. The server must validate:
- level;
- protection zone;
- guild;
- skull;
- house ownership;
- market offers;
- transferable coins;
- existing active auctions;
- staff characters;
- marriage if your server uses marriage.
The included server file already validates the most important checks.
Known placeholders
Some checks are included as placeholders because not every Crystal fork has the
same systems:
- two-factor authentication;
- open warning/punishment;
- sponsored streamer;
- allowed item whitelist.
If your server has those systems, replace the placeholder
true with your realvalidation.
Testing checklist
Please check the Verifying & Testing section inside the README.md for a detailed step-by-step test workflow to validate the creation, database entries, C++ logic locks, web bids, and finalization.
Short version:
1. Start server.
2. Check database tables exist.
3. Login a test character.
4. Open Store -> Character Bazaar.
5. Create auction.
6. Confirm character is kicked.
7. Confirm character is hidden from character list.
8. Try direct login and confirm the Bazaar login error appears.
9. Open website page.
10. Bid from another account.
11. Confirm previous bidder refund works.
12. Let auction expire.
13. Confirm character transfers to winner.
14. Confirm seller gets paid.
Common problems
Problem: button opens nothing
Check if
classes/bazaar is loaded before game_store.Problem: Extended Opcode does nothing
Check if both client and server use the same opcode:
Code:
207
Check if login registers:
LUA:
player:registerEvent("CharacterBazaarExtendedOpcode")
Problem: site page is blank
Check if your MyAAC template path is correct:
Code:
system/templates/character-bazaar.html.twig
Check PHP errors.
Problem: auctioned character still appears in character list
You did not apply the C++
loadAccountPlayers filter.Problem: auctioned character can still login
You did not apply the C++
ProtocolGame::login check.Problem: coin balance is wrong
Your fork probably uses different names for normal/transferable coins. Adapt
only the coin helper functions. Do not change the auction tables.
Final note
This is a base made for real use, not just a visual system. Still, every OT
server has custom code, so read the included install guides and adapt carefully.
Files are included in the attached zip.