Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Game backend development

Avatar for ymori ymori
March 14, 2018

Game backend development

Avatar for ymori

ymori

March 14, 2018

More Decks by ymori

Other Decks in Technology

Transcript

  1. Topics to cover: - Basic components of game backend -

    How to scale backend - Protection against cheats
  2. Game feature that require backend - Saving progress - Leaderboard

    - Chat - In game social graph - Features that uses in game social graph (Guild, Trading) - etc..
  3. What tech stack to use? - All we need is

    CRUD against *centralized* server - Create - Read - Update - Delete
  4. What tech stack to use? - HTTP(S) - Pro: -

    Huge library base - Huge infrastructure support - PKI built in (=Secure) - Con: - Well know (= easy to hack)
  5. What tech stack to use? - TCP - Pro: -

    Highly customizable - Con: - Potentially insecure
  6. What tech stack to use? - UDP - Pro: -

    Highly customizable - Faster than TCP - Con: - No data ordering - No data correction
  7. And beyond.. Example of dividing game backend features: - Authentication

    - Inventory (Shop / Currency / Items) - Social feature (Including Leaderboard) - Push notification - Chat
  8. Designer: Hey, don’t you think team vs team would be

    fun? Like 100 players vs 100 players
  9. ???

  10. Backend related cheats - Repeat requests - Concurrent request -

    Modified request - Validation by simulation
  11. Repeat requests - sample code app.post(‘/mission_end’, function (req, res) {

    const missionId = req.missionId; // NO VALIDATION! RewardService.grantMissionClearReward(missionId); res.send(‘ok’) });
  12. Repeat requests Users peek the requests by using PC proxy

    Well known products: - Charles proxy - Burp proxy
  13. Repeat requests - sample code app.post(‘/mission_end’, function (req, res) {

    const missionId = req.missionId; // NO VALIDATION! RewardService.grantMissionClearReward(missionId); res.send(‘ok’) });
  14. Repeat requests - FIXED! app.post(‘/mission_end’, function (req, res) { const

    missionId = req.missionId; If (MissionService.missionRewardLeft(missionId)) { RewardService.grantMissionClearReward(missionId); MissionService.setMissionRewardFlag(missionId); } res.send(‘ok’) });
  15. Concurrent request app.post(‘/mission_end’, function (req, res) { const missionId =

    req.missionId; If (MissionService.missionRewardLeft(missionId)) { RewardService.grantMissionClearReward(missionId); MissionService.setMissionRewardFlag(missionId); } res.send(‘ok’) });
  16. app.post(‘/mission_end’, function (req, res) { const missionId = req.missionId; If

    (MissionService.missionRewardLeft(missionId)) { RewardService.grantMissionClearReward(missionId); MissionService.setMissionRewardFlag(missionId); } res.send(‘ok’) }); Concurrent request 5ISPXNVMUJQMFSFRVFTUTCFGPSFqBHHFUT NPEJpFE
  17. Concurrent request - FIXED! app.post(‘/mission_end’, function (req, res) { const

    missionId = req.missionId; const userId = req.session.userId; const lockId = DataBaseService.lock(userId); If (MissionService.missionRewardLeft(missionId)) { RewardService.grantMissionClearReward(missionId); MissionService.setMissionRewardFlag(missionId); } DataBaseService.unlock(lockId); res.send(‘ok’) });
  18. Modified request - app.post(‘/mission_end’, function (req, res) { const missionId

    = req.missionId; const score = req.missionScore; const userId = req.session.userId; const lockId = DataBaseService.lock(userId); RewardService.grantScoreBasedReward(userId, missionId, score); DataBaseService.unlock(lockId); res.send(‘ok’) });
  19. Modified request - FIXED! app.post(‘/mission_end’, function (req, res) { const

    missionId = req.missionId; const score = req.missionScore; if (sha256(`${score}_${SERVER_SECRET}`) !== req.signature) { return res.send(“Request tampered!”) } const userId = req.session.userId; const lockId = DataBaseService.lock(userId); RewardService.grantScoreBasedReward(userId, missionId, score); DataBaseService.unlock(lockId); res.send(‘ok’) });
  20. Validation by simulation app.post(‘/mission_end’, function (req, res) { const missionId

    = req.missionId; const playInputSequence = req.playInputSequence; const simscore = Simulation.simulateGamePlay(playInputSequence); if (simscore != score) { return res.send(“Request tampered!”) } const userId = req.session.userId; const lockId = DataBaseService.lock(userId); RewardService.grantScoreBasedReward(userId, missionId, score); DataBaseService.unlock(lockId); res.send(‘ok’) });
  21. Pros: - Really strong against cheat Cons: - Really hard

    to implement. Really. Validation by simulation