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

Браузерная игра с VR в 2k17 на Python

Браузерная игра с VR в 2k17 на Python

Александр Хаёров (Odin Ingram Micro) @ Moscow Python Meetup 51
"Я расскажу откуда взялась идея сделать браузерную игру, и что из этого получилось, как все технически устроено: от картинки в браузере до архитектуры, бекенда и базы данных. Вы узнаете, как это — сделать браузерную 3D-игру в 2017 году, какие трудности вас будут подстерегать, и при чем тут VR.
Доклад раскроет технические детали того, как устроена игра, что используется из веб-технологий, как хранятся данные, какую нагрузку пользователей выдерживает и где размещается".
Видео: http://www.moscowpython.ru/meetup/51/python-browser-game-vr/

Avatar for Moscow Python Meetup

Moscow Python Meetup PRO

December 21, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Who Are Indie Game Developers? 97% men Source: somewhere from

    the Internet Indie is a shortform of "independent"
  2. Who Are Indie Game Developers? 97% men 60% singles Source:

    somewhere from the Internet Indie is a shortform of "independent"
  3. Who Are Indie Game Developers? 97% men 60% singles 1-3

    months/game Source: somewhere from the Internet Indie is a shortform of "independent"
  4. Who We Are and the Great Team of Engineers Alex

    Khaerov a Unit Manager at Ingram Micro Cloud
  5. Who We Are and the Great Team of Engineers @themaxbelov

    @ToxicWar @weglov @spukst3r Alex Khaerov a Unit Manager at Ingram Micro Cloud
  6. Who We Are @themaxbelov @ToxicWar @weglov and the Great Team

    of voxel jedis, optimisation masters, gurus of the 3d, lords of the big data @spukst3r Alex Khaerov a Unit Manager at Ingram Micro Cloud
  7. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min a social experiment by Reddit
  8. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min 72 hours of fun a social experiment by Reddit
  9. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min 72 hours of fun a social experiment by Reddit
  10. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min 72 hours of fun a social experiment by Reddit
  11. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min 72 hours of fun > 1M players a social experiment by Reddit
  12. /r/Place 1,000 x 1,000 px canvas pixel * user per

    5 min 72 hours of fun > 1M players a social experiment by Reddit 90K simultaneously
  13. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech Features multi-player and networked The Game
  14. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech Features Concessions multi-player and networked The Game
  15. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Features Concessions multi-player and networked The Game
  16. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Browser Features Concessions multi-player and networked The Game
  17. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Browser voxel “block-style” objects Features Concessions multi-player and networked The Game
  18. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Browser voxel “block-style” objects Features Concessions multi-player and networked The Game
  19. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Browser voxel “block-style” objects Features Concessions multi-player and networked The Game
  20. multi-player 2D computer graphics 2D 3D computer graphics hyped tech

    hyped Virtual Reality tech client-based Browser voxel “block-style” objects Features Concessions world size 1000x1000x200 multi-player and networked The Game
  21. Active Passive + Robust to de-sync + Easy to understand

    + More efficient - Fragile Replication Problem
  22. Active Passive + Robust to de-sync + Easy to understand

    + More efficient - Fragile + Easier to secure Replication Problem
  23. Active Passive + Robust to de-sync + Easy to understand

    + More efficient - Fragile - Single point of failure + Easier to secure Replication Problem
  24. Active Passive + Robust to de-sync + Easy to understand

    + More efficient - Fragile - Single point of failure + Easier to secure ✔ Replication Problem
  25. “flat array” octree + read/write = const - slower than

    flat - memory = L^3 + lean Data Structure
  26. “flat array” octree pages/chunks + read/write = const - slower

    than flat - memory = L^3 + lean Data Structure
  27. “flat array” octree pages/chunks + read/write = const + lazily

    initialized - slower than flat - memory = L^3 + lean Data Structure
  28. “flat array” octree pages/chunks + read/write = const + lazily

    initialized - slower than flat - memory = L^3 + lean - more complicated Data Structure
  29. “flat array” octree + Read/Write = const + lazily initialized

    - slower than flat - Memory = L^3 + lean - more complicated Data Structure pages/chunks
  30. “flat array” octree + Read/Write = const + lazily initialized

    - slower than flat - Memory = L^3 + lean - more complicated Data Structure pages/chunks ✔
  31. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object
  32. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() }
  33. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() }
  34. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() }
  35. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } r
  36. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) r
  37. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) set(x, y, z) r
  38. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) set(x, y, z) r
  39. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) set(x, y, z) r
  40. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend updated() (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) set(x, y, z) r
  41. Protocol 1 2 3 … N 32 32 game-frontend mongoDB

    > data (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object (3) ObjectId() { 7 fields } Object (4) ObjectId() { 7 fields } Object (5) ObjectId() { 7 fields } Object (6) ObjectId() { 7 fields } Object (7) ObjectId() { 7 fields } Object (8) ObjectId() { 7 fields } Object game-backend updated() (1) ObjectId() { 7 fields } Object (2) ObjectId() { 7 fields } Object userActivity() “{Username} joined the game” String { "_id" : ObjectId(), "x" : 435, "y" : 377, "z" : 0, “color" : "#5b8c9c", "name" : null, "updated" : ISODate() } get(x, y, z, r) set(x, y, z) r
  42. Game-backend Python 3.6 + aiohttp uvloop implemented in Cython and

    uses libuv motor full-featured, non-blocking MongoDB driver for Python
  43. Game-backend Python 3.6 + aiohttp uvloop implemented in Cython and

    uses libuv motor full-featured, non-blocking MongoDB driver for Python gunicorn Python WSGI HTTP Server for UNIX
  44. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers
  45. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z)
  46. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks
  47. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks AABB: Bounding volume
  48. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks AABB: Bounding volume A 3D model with its bounding box drawn in dashed lines.
  49. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks AABB: Bounding volume
  50. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting AABB: Bounding volume
  51. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting AABB: Bounding volume Ray Casting
  52. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting AABB: Bounding volume
  53. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting AABB: Bounding volume Textures
  54. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting AABB: Bounding volume player with controls Textures
  55. Game-frontend Native JavaScript and WebGL? Native JavaScript and WebGL? Voxel.js

    an open source voxel game building toolkit for modern web browsers a-la minecraft world (X, Y, Z) voxels (blocks) / chunks Ray casting game events (tick/setBlock/collision/renderChunk) AABB: Bounding volume player with controls Textures
  56. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  57. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  58. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  59. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  60. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  61. Game-frontend voxel.js your code three.js WebGL Browser Hardware OpenGL Driver

    Display Mngt System Creating the scene var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); }
  62. Oculus Rift - too numerous wires + resolution and refresh

    rate + it’s true VR + very comfortable
  63. Oculus Rift - no SDK for macOS/Linux - too numerous

    wires + resolution and refresh rate + it’s true VR + very comfortable
  64. Oculus Rift - no SDK for macOS/Linux - NVIDIA GTX

    970 / AMD 290 + - too numerous wires + resolution and refresh rate + it’s true VR + very comfortable
  65. A-Frame virtual reality framework works on Vive, Rift, Daydream, GearVR,

    desktop based on top of HTML <html> <head> <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> </head> <body> <a-scene> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane> <a-sky color="#ECECEC"></a-sky> </a-scene> </body> </html>
  66. A-Frame virtual reality framework works on Vive, Rift, Daydream, GearVR,

    desktop based on top of HTML <html> <head> <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> </head> <body> <a-scene> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane> <a-sky color="#ECECEC"></a-sky> </a-scene> </body> </html>
  67. Optimizations Use Mesher FPS ↑ Enable compression for WebSocket (RFC

    7692) Traffic ↓ (5MB -> 1.8MB) Pre-process voxel models Voxels count ↓ (-78%)