ilham60b-ship-it/SA-MP-SSI
A realistic stock market system for SA-MP Roleplay where prices are driven by real player activity instead of random values.
README.md
SSI — Industrial Sector Investment System
An industrial investment exchange system for SA-MP Roleplay servers, written in Pawn with MySQL storage. Unlike traditional fictional stock market systems, SSI derives sector prices from the server's actual economic activity rather than random fluctuations.
Players can purchase SSI units from the server's industrial sectors (jobs), hold them as long-term investments, earn automatic dividends generated from each sector's profits, and sell their units at any time using the /exchange command.
Why SSI?
On most Roleplay servers, stock market systems exist only as decorative features—their prices fluctuate randomly and have no connection to player activity. SSI was designed to solve this problem by making every sector's value directly reflect what is happening in the server's economy.
- Sectors with more active workers generally increase in value.
- Sectors with higher production output and transaction volume become more valuable.
- Heavy selling pressure causes prices to fall, while stronger buying demand pushes prices upward.
In other words, investing in SSI means investing in the performance of the server's economy. The more active a sector becomes, the more valuable it can be.
Features
- 12 industrial sectors, based on the jobs actively played on the server (Taxi, Mechanic, Lumberjack, Trucker, Farmer, Miner, Fisherman, Forklift, Bus Driver, Sweeper, Courier, and Trashmaster).
- Dynamic market pricing, automatically recalculated at fixed intervals using four key factors: active workers, production output, transaction value, and SSI market supply/demand. Price changes are capped each cycle to prevent excessive volatility.
- Automatic dividend distribution, allowing all investors to receive periodic payouts based on each sector's actual profit. Offline players still receive their dividends automatically the next time they log in.
- Brokerage fees and transaction taxes, where brokerage fees reward players working as brokers while transaction taxes permanently remove money from circulation, helping stabilize the server economy.
- Complete portfolio management, including current prices, price history, dividend history, transaction history, and real-time profit/loss tracking.
- Built-in anti-exploit protection, including buy/sell cooldowns, maximum purchase limits, and sector suspension support.
- Lightweight integration with the existing job system, requiring only a single hook (
SSI_ReportActivity) without modifying existing job logic.
Project Structure
Modules/
└── Jobs/
├── SSI.pwn # Entry point, includes all SSI modules
└── SSI/
├── Header.inc # Enums, constants, defines, and variables
├── Function.inc # Price engine, buy/sell logic, dividends, database functions
├── Command.inc # Commands (/exchange, /ssiportfolio, /ssihistory, /brokerduty)
├── Dialog.inc # All dialog interfaces
└── Timer.inc # Automatic price and dividend scheduler
ssi_schema.sql # Database schema (5 tables + 12 sector seed data)
How It Works
-
Whenever a player completes a job and receives payment, the job calls:
SSI_ReportActivity(playerid, sectorid, productionAmount, transactionValue); -
The system accumulates this activity for each sector throughout the current update interval.
-
Every update cycle (10 minutes by default), SSI recalculates each sector's price using:
- Number of active workers
- Production output
- Transaction value
- SSI buy/sell demand
-
After the calculation is complete, all activity counters are reset for the next cycle.
-
A configurable percentage of each sector's transaction value is added to that sector's profit pool.
-
At the dividend interval (1 hour by default), the accumulated profit pool is distributed proportionally to every player who owns units in that sector.
Installation
-
Import
ssi_schema.sqlinto your server's MySQL database. -
Configure
ref_worker_count,ref_production_units,ref_transaction_value, as well as each sector's starting price and minimum/maximum price limits inside thessi_sectorstable to match your server's economy. -
Include
./Modules/Jobs/SSI.pwninmain.pwn(replacing the oldBroker.pwn) before any job modules that callSSI_ReportActivity(). -
Inside
OnGameModeInit, initialize the system:SSI_LoadSectors(); SSI_InitTimers(); -
After player data has finished loading, call:
SSI_LoadPlayerPortfolio(playerid);Also reset runtime data in:
OnPlayerConnect() { SSI_ResetPlayerRuntime(playerid); } -
Add a single
SSI_ReportActivity()hook wherever a job rewards a player (see theSSI HOOKcomments in the provided job examples).
Coding Guidelines
Some things to keep in mind if you plan to extend or modify this system:
- Single source of truth. All economy-related constants (fees, taxes, pricing formula weights, update intervals, and price change limits) are centralized in
Header.incusing#define. Avoid hardcoding values inside functions—add new definitions instead so the system remains easy to balance and maintain. - Never modify sector prices directly. Price changes must only be handled through
SSI_UpdateSectorPrices(). If you need a special event (such as an RP event affecting a sector), add it as another component of the pricing formula instead of assigningSSIData[id][ssiPrice] = ...elsewhere in the code. - All transactions must go through
SSI_Buy()andSSI_Sell(). These are the only functions responsible for validating cooldowns, unit limits, and transaction history. Never create shortcuts that modifypSSIUnitsfrom other commands or scripts. - Job hooks are strictly one-way.
SSI_ReportActivity()only receives activity data and never calls job-related functions in return. If you want SSI prices to influence job salaries or rewards, treat it as a separate design decision and carefully evaluate any circular dependencies before implementing it. - Always build MySQL queries using
mysql_format()and placeholders. Never concatenate SQL strings manually. This keeps the codebase consistent with the existing gamemode architecture and prevents SQL injection vulnerabilities from player input. - Maintain numeric precision consistently. Use
Floatfor per-unit prices andintfor total transaction values. This matches howpMoneyandpBankMoneyare stored while minimizing floating-point precision errors. - Reset activity counters only at the end of
SSI_UpdateSectorPrices(). Counters should never be reset elsewhere, ensuring that price calculations always match the information presented to players.
Roadmap
- Administrator commands to manually suspend or resume individual sectors.
- Historical price charts using data from
ssi_price_history(ideal for a web dashboard). - Global in-game notifications whenever a sector experiences significant price movement during an update cycle.
economygamemodeopen-mpsa-mpsampserver-samp
Esta página é montada com o que o GitHub publica sobre o repositório. O samp.directory não hospeda o código. Avisar de um problema com esta página