Make your game, step by step
This guide follows GamCity, the first creator game on GAMPEON: a fixed city in the middle, block land around it where players dig and build, a market that buys ore and sells building blocks. GamCity is built only with the tools every creator has. It has no special access and no code of its own inside the game. Where a step is not possible yet, this page says so.
| Step | Where | Status |
|---|---|---|
| 1. Decide what GAMPEON does and what you write | ||
| 2. Create your project | Portal | Preview |
| 3. Lay out the server folder | Your computer | Preview |
| 4. Write the resource | Your editor | Preview |
| 5. Test without the game | gampeon-server |
Preview |
| 6. Run a game server | Test servers | Preview internal only |
| 7. Register the server and link it | Portal | Preview |
| 8. Publish the project page | Portal | Preview |
| 9. Players join | Launcher | Planned |
| 10. Your own models, maps and characters | Game packages | Preview maps, local tests only |
1. Decide what GAMPEON does and what you write
Section titled “1. Decide what GAMPEON does and what you write”GAMPEON runs the world. Your scripts decide the game.
| GAMPEON does | You write |
|---|---|
| Characters, movement, camera, network | What players own: inventory, money, levels |
| The block world: terrain from a seed, dig and build controls, hotbar, saving changed blocks | What digging gives and what players may place |
| Checks against cheating: reach, speed, protected zones | Prices, recipes, rules, rewards |
| Chat, web interfaces, join check | Your windows, menus and messages |
Rules belong in server scripts. Client scripts show things and send what the player wants; the server checks it again. See Scripting overview.
Your game does not ship C++ code. If you need something GAMPEON does not have yet, tell us. Missing features are built into GAMPEON for every creator, not as an exception for one game. The block world started that way, for GamCity.
2. Create your project
Section titled “2. Create your project”- Open GAMPEON Create, the creator site, and sign in with your GAMPEON account (the closed test needs an invitation).
- Choose New project.
- Pick the slug (GamCity uses
gamcity; it cannot be changed later), a title, the genre (sandbox) and the status (development).
The project stays a draft that only you see until you publish it in step 8. See Studios and projects.
3. Lay out the server folder
Section titled “3. Lay out the server folder”A game server reads one folder: server.cfg and resources/. The same folder works in gampeon-server and on the game server.
server-data/ server.cfg resources/ [gamcity]/ a folder in [brackets] only groups resources gamcity/ fxmanifest.lua shared/config.lua prices, recipes, the city zone server/main.lua block world, inventory, market, saving client/main.lua hotbar and window html/index.html market and workshop window data/ the server saves players heresv_hostname "GamCity"sv_maxclients 32sets tags "sandbox, building, city"sets locale "en-US"
# Local tests: no join check. Remove this line once the server is registered (step 7).set sv_requireJoinToken false
ensure chatensure gamcityKeep the folder in Git if you like, but never commit a server key. Step 7 explains where the key goes.
4. Write the resource
Section titled “4. Write the resource”Install the editor setup first. Your editor then knows every GAMPEON function and marks typos.
Manifest
Section titled “Manifest”fx_version 'cerulean'game 'gampeon'
name 'gamcity'version '0.1.0'
shared_script 'shared/config.lua'server_script 'server/main.lua'client_script 'client/main.lua'
ui_page 'html/index.html'One config for server and client
Section titled “One config for server and client”Prices and recipes live in a shared script. The server uses them to decide, the window uses them to show, and there is only one copy.
Config = {}Config.world = { seed = 20261106, save = 'gamcity' }Config.city = { minX = -48, minY = -48, maxX = 48, maxY = 48, groundZ = 8 }Config.drops = { turf = 'soil', copper_vein = 'copper_ore', iron_vein = 'iron_ore' }Config.items = { stone = { label = 'Stone', block = 'stone', sell = 1, buy = 2 }, copper_ore = { label = 'Copper ore', sell = 12, buy = 0 }, -- …}Server: the world and what digging gives
Section titled “Server: the world and what digging gives”EnableBlockWorld({ seed = Config.world.seed, save = Config.world.save, -- changed blocks survive restarts zones = { Config.city }, -- the city: flat, nobody digs or builds there})
AddEventHandler('blockBreak', function(x, y, z, block) local p = getPlayer(source) local item = Config.drops[block] or block if not Config.items[item] then return end if count(p, item) >= Config.maxStack then CancelEvent() -- the block stays, the bag is full return end add(p, item, 1) send(source) -- TriggerClientEvent('gamcity:state', …)end)
AddEventHandler('blockPlace', function(x, y, z, block) local p = getPlayer(source) if count(p, block) < 1 then CancelEvent() -- placing needs the block in the bag return end add(p, block, -1) send(source)end)GAMPEON has already checked reach, speed, zones and free space before these events arrive. You only decide the game.
Server: a market that cannot be cheated
Section titled “Server: a market that cannot be cheated”The window sends what the player clicked. The server checks everything again: where the player stands, the amount, the money.
RegisterNetEvent('gamcity:action', function(action, item, amount) local src = source if type(item) ~= 'string' then return end local c = GetEntityCoords(GetPlayerPed(src)) if not Config.InCity(c.x, c.y) then return notify(src, 'The market is in the city.') end if action == 'sell' then sell(src, item, amount) elseif action == 'buy' then buy(src, item, amount) endend)Client: hotbar and window
Section titled “Client: hotbar and window”RegisterNetEvent('gamcity:state', function(state) local slots = {} for _, item in ipairs(Config.hotbar) do local n = state.inv[item] or 0 if n > 0 and #slots < 9 then slots[#slots + 1] = { block = Config.items[item].block, count = n } end end SetBlockHotbar(slots) SendNUIMessage({ type = 'state', inv = state.inv, cash = state.cash })end)
RegisterCommand('shop', function() open = not open SendNUIMessage({ type = open and 'open' or 'close' }) SetNuiFocus(open, open) SetBlockControlsEnabled(not open) -- no digging while the window is openend, false)The window itself is a normal web page that calls back with fetch. See Web interfaces.
Save what players own
Section titled “Save what players own”The block world saves blocks. Inventories and money are yours to save. GamCity writes one JSON file with SaveResourceFile every 30 seconds and when the resource stops. For more players, use the database.
5. Test without the game
Section titled “5. Test without the game”gampeon-server runs your server folder without Unreal, with fake players that dig, build, click in your window and type commands. Write a test file next to server.cfg:
exec server.cfggp_fakeplayer client Testergp_fakeplayer waitclient 1 gamcity chatgp_fakeplayer move 1 0.5 0.5 9 0gp_fakeplayer break 1 0 0 8gp_fakeplayer move 1 100.5 100.5 20 0gp_fakeplayer break 1gp_wait 200gp_fakeplayer command 1 invgp_fakeplayer nui 1 gamcity ready {}gp_fakeplayer command 1 citygp_fakeplayer event 1 gamcity:action ["buy", "planks", 3]gp_wait 500quitgp_block 100 100 0 prints the surface height there, so you know where to put the fake player. Without coordinates, break digs the block below the player’s eyes.
gampeon-server --data ./server-data --no-stdin +exec test.cfgThe output, shortened:
[blocks] player 1 break at 0 0 8 refused: protected zone[blocks] player 1 broke turf at 100 100 19[client 1/blocks] hotbar: soil x1[client 1/chatbox] GamCity: $50 | Soil 1[client 1/chatbox] GamCity: Taxi to the city: $15.[client 1/chatbox] GamCity: Bought 3 Planks for $12.- Digging in the city is refused before your script is even asked.
- Digging turf in the block land puts soil into the bag, and the hotbar shows it.
- The window gets prices and recipes from
ready, the taxi costs money, and buying works in the city. - Start the server again: the bag is still there, because the script saved it.
gampeon-serverkeeps changed blocks only while it runs; the game server saves them withsave.
Run the file after every change. It takes a few seconds and needs no graphics card.
6. Run a game server
Section titled “6. Run a game server”The game server uses the same server-data folder as gampeon-server. Players connect over UDP, so the game port (for example 7790) must be open in the firewall. Client scripts and your web interface download to every player automatically when they join; see Client scripts.
7. Register the server and link it
Section titled “7. Register the server and link it”-
In GAMPEON Create, open Servers, fill in Register a server and name it (
GamCity EU #1). -
Copy the server ID and the key. The key is shown only once.
-
On the machine that runs the server, put both into
server.cfgand removeset sv_requireJoinToken false:server.cfg set gampeon_server_id "<id>"set gampeon_server_key "<key>"Only that copy of
server.cfgcontains the key. Never put it into Git, a marketplace upload or a chat. -
Link the server to your project. Its players then count on the project page.
Details in Register a server.
8. Publish the project page
Section titled “8. Publish the project page”Add a tagline, an about text with at least 100 characters, screenshots and tags, then publish under Manage. You can turn it back into a draft at any time. See Draft and published.
9. Players join
Section titled “9. Players join”Players will find your server in the server browser of the GAMPEON launcher and on your project page. The launcher signs them in and gives the game a join ticket; your server checks it, so nobody can pretend to be someone else.
10. Your own models, maps and characters
Section titled “10. Your own models, maps and characters”Today, a game has the built-in block world, five simple object models and simple player figures. Your own Unreal content, for example a city, characters, weapons or cars, needs private game packages.
Game packages are in preview. GamCity uses one for its city:
- You build your content in your own Unreal project as a content-only plugin and cook it with the creator kit. No code: rules stay in Lua. See Bring your own map.
- You upload the cooked package to your project. Only servers linked to that project load it, and only their players get it: the launcher downloads it when they press Play. It is never on the marketplace, cannot be downloaded in the portal, and other creators’ resources cannot use it. See Upload your game package.
- Later, your scripts use models from the package by name, for example
CreateObject('gamcity/palm_tree_01', …).
This is the place for assets you bought for your own game, such as store packs licensed for use in your product but not for passing on to others. Those assets never go on the marketplace or into a public repository. Read Third-party assets, and check that your license allows a game on GAMPEON: some store licenses have extra rules for platforms with user-generated content. If you are not sure, ask the seller in writing before you publish.
What is not there yet
Section titled “What is not there yet”- Your own block types with your own colors or textures.
- Vehicles and weapons in the game API.
- Models from game packages for
CreateObject, and the check for Blueprint logic in uploaded packages. - The launcher download, game servers on your own machine and test servers on demand.
- Payments for creators.
Your checklist
Section titled “Your checklist”- Project created as a draft.
- Server folder with
server.cfgand your resource. - Rules in server scripts, client scripts only show and ask.
- A
test.cfgthatgampeon-serverruns without errors. - Server registered, key only in the server’s
server.cfg, join check on. - Server linked to the project, project page published.