Game Factory
Single Instance Lock
By design, Shrimp Farm allows only one game instance per program on mainnet.
This is enforced through a LockState account that prevents multiple initializations.
When test_env is false, the first successful initialize call locks the program forever.
Subsequent initialize attempts will fail with CustomErrors::InitLocked.
Show the lock mechanism
pub fn initialize(
ctx: Context<Initialize>,
dev1: Pubkey,
dev2: Pubkey,
dev3: Pubkey,
premarket_end: u64,
cooldown: u64,
test_env: bool,
) -> Result<()> {
// ... other setup ...
// For mainnet deploy, prevent multiple initializes
require!(!ctx.accounts.lock_state.locked, CustomErrors::InitLocked);
if !test_env {
ctx.accounts.lock_state.locked = true;
}
// ... rest of initialization ...
Ok(())
}
Why Not Multi-Instance?
The authority-based architecture would technically support multiple game instances.
Users could deploy their own games, collect fees, and run parallel competitions.
We chose single-instance for several reasons:
Reduced scope - Multi-instance adds complexity to deployment and management
Cleaner API - Our event indexing doesn't get polluted with events from other instances
Focus - Single game means we can optimize the experience without worrying about variants
Control - We maintain authority over game parameters and economic balance
Authority-Only Functions
The locked authority key controls several admin functions:
Development Functions (test env only):
set_market- Manually adjust market state for testingend_premarket- Force pre-market period to end early
Live Functions:
testnet_bonus- Toggle 1% bonus for specific accounts during testing phasesset_collection- Set the NFT collection address (called once at deployment)
Show authority verification
#[derive(Accounts)]
pub struct BuyAccounts<'info> {
#[account(mut)]
pub player: Signer<'info>,
/// CHECK: Custom check
#[account(address = game_state.authority)]
pub authority: AccountInfo<'info>,
#[account(
mut,
seeds = [GameState::SEED, authority.key().as_ref()],
bump
)]
pub game_state: Box<Account<'info, GameState>>,
// ... other accounts ...
}
Future Possibilities
While we implemented single-instance, the architecture supports expansion.
A future version could remove the lock and allow:
- User-created game instances with custom parameters
- Fee collection for instance creators
The authority-based derivation makes this technically straightforward.