bloxfa.st
Docs

Get started

Configuration

The config files, what each one controls, and the IDs to fill in before launch.

Most of what you'll change lives in these seven files, plus the DEMO flag. Each system page covers its own settings in detail; this page is the map.

File Controls
src/shared/Config.ts Currencies, products, gamepasses, multiplier sources, rebirth, event multipliers, boosts, items, variants, inventory, the index, group, friend and invite rewards, daily and playtime rewards, onboarding steps, leaderboard, admins, audio, DataStore names, trading
src/shared/EggsConfig.ts EGGS
src/shared/WheelConfig.ts WHEEL
src/shared/QuestsConfig.ts QUEST_BOARDS, ACHIEVEMENTS
src/shared/SeasonConfig.ts SEASON_PASS, SEASONS
src/server/CodesConfig.ts CODES
src/client/Theme.ts Every color, font, size and animation timing in the UI

DEMO at the end of Config.ts turns the demo hub on or off: DEMO = { enabled: true }. Set enabled to false for a game that doesn't want the hub, or delete the demo folders (see Project layout).

Everything under src/shared/ is replicated, so players can read it. Promo codes are in src/server/CodesConfig.ts for that reason.

IDs of 0 mean "not set up yet"

Product, pass, badge and group IDs all start at 0. An entry with ID 0 is hidden in the UI and ignored by the server, so the game runs before you've made anything on the Creator Dashboard. From the top of Config.ts:

/**
 * IDs come from the Creator Dashboard (create.roblox.com > your experience >
 * Monetization). An ID of 0 means "not set up yet": that product or pass is
 * hidden in the shop and ignored by the server.

The define helper

Most config tables are written with define<T>(), which checks each entry against one shape and keeps the table's own keys as a type:

export function define<D>() {
	return <K extends string>(entries: Record<K, D>): Record<K, D> => entries;
}

export const CURRENCIES = define<CurrencyDefinition>()({
	coins: { name: "Coins", startingAmount: 100, soldForRobux: true },
	gems: { name: "Gems", startingAmount: 0, soldForRobux: false },
});

export type CurrencyKey = keyof typeof CURRENCIES;

So after you add tokens to CURRENCIES, "tokens" is a valid CurrencyKey everywhere, and a typo like "token" is a compile error.

Checks at startup

Some config mistakes stop the server at startup with an error message:

  • Eggs.ts errors on an unknown item, an item listed twice in one egg, an egg with no openCounts, or an egg whose only entries are once-only.
  • Wheel.ts errors on a prize that gives nothing, a wheel with no prize weight above 0, and, once a spin product ID is set, a prize that gives a currency without soldForRobux.
  • Season.ts errors when a premium reward gives a currency without soldForRobux.

TypeScript catches the rest. For example, every key in PRODUCTS needs an entry in PRODUCT_GRANTS in server/Purchases.ts, or the build fails.

Before launch

Work through this list on the Creator Dashboard (create.roblox.com > your experience > Monetization), pasting each ID into config:

  1. One developer product per entry in PRODUCTS (Pile of Coins, Chest of Coins, Starter Pack). Paste each into its id.
  2. One pass per entry in GAMEPASSES (2x Coins, VIP, +2 Equips). Paste into id.
  3. For each pass you want to be giftable, one more developer product priced like the pass. Paste into giftProductId.
  4. To sell a boost, a developer product for it, pasted into its productId in BOOSTS.
  5. Egg opens and wheel spins: the products entries in EggsConfig.ts and WheelConfig.ts.
  6. Season premium and tier skips: premiumProductId and tierSkipProductId in SeasonConfig.ts.
  7. Your group ID in GROUP.id, if you have a group.
  8. Your Roblox user ID in ADMIN_USER_IDS, so admin commands work in live servers.
  9. Badge IDs in achievement tiers (badgeId), if you want badges.
  10. Sound asset IDs in AUDIO (musicId, clickSoundId, coinSoundId).

Then decide which currencies are sold for Robux and set soldForRobux to match. That one flag decides which eggs count as paid random items, which ones restricted regions can open, and what can be traded where. See Currencies and Eggs and odds.

DataStore names

DATA in Config.ts names the stores:

export const DATA = {
	/**
	 * DataStore name for player data. Changing it gives everyone fresh data,
	 * so only do that before launch. To change the shape of saved data later,
	 * add a migration in src/server/data/Schema.ts instead.
	 */
	storeName: "PlayerData_v1",
	/** Passes gifted to each player, kept apart so a gift can reach someone in another server. */
	giftStoreName: "GiftedPasses_v1",
	/** Invite rewards waiting for each inviter. */
	referralStoreName: "Referrals_v1",

After launch, leave storeName alone. Changing it starts every player over. To change what's saved, add a migration (see Player data).