SlideShare a Scribd company logo
1 of 142
Download to read offline
We#will#begin#shortly...
Stay%Awhile%And%Fiddle%With%Your%
Smartphone
By#Jamie#Winsor
The$Story
Building(And(Suppor.ng
Online&Experiences
Architec(ng,,Planning,,and,Implemen(ng,is,40%,of,an,
Engineer's,job
The$other$60%$is$team$building$and$communica6on.
So#ware(doesn't(solve(problems.(
People(do.
Disclaimer
"Be$er"&Within&Context
The$Problem
How$Do$We
• Stay&development&focused
• Transi6on&from&single&player&to&massively&mul6player&online&
games
• Build&a&posi6ve&rela6onship&with&our&publishers
• Develop&and&maintain&a&strong&company&culture
Develop'Your'Company,'Not'Just'
Your'So6ware
Hire%Engineers,%Not%Programmers
Don't&Be&Afraid&To&Contract&Work&
Out
Never%Higher%A%Maybe
Interview)For
• IQ$%$intelligence
• EQ$%$emo0onal$intelligence
• Personality
Develop'Smart
Be#Pragma)c#And#Iterate
Leverage'Open'Source
Use$The$Right$Tools$And$Pa2erns
Building(A(Distributed(System?
Team%Language%Evalua-on
What%technology%should%we%adopt?
• C/C++
• C#&mono
• Python
• Ruby
• Erlang
Game%engineers%are%generally%experienced%in%
C2like%languages
OTP
A"Framework"For"Building"Distributed"Systems
Would&You&Build&Your&Own&Web&Framework?
Or#Your#Own#Game#Engine?
You$Could$But...
Some%Of%Us%Have%Shit%To%Do
Erlang/OTP+Saves+Time
A"Lot"Of"Time
Erlang/OTP+Network+Programming+Perks
• Easily(encode(and(decode(binary(message
• Monitor(/(subscribe(to(open(sockets
• "Free"(internal(rou:ng(of(messages
• A(sane(threading(model
• Crash?Resistant
Erlang'isn't'very'approachable
—"Concerned"Engineer
Elixir&Has&The&Same&Core&Concepts
• Processes(and(Mailboxes
• Supervision(Trees
• Pa6ern(Matching
• Tail(Recursion
Started'Using'Elixir'at'0.9.0
We#Asked#Ourselves,#"Is#This#A#Risk?"
Solid&Two)Way&Interoperability
Elixir&Calling&Erlang
:erlang.now()
Erlang'Calling'Elixir
defmodule Time do
def now do
:erlang.now()
end
end
'Elixir.Time':now().
Syntax'Doesn't'Ma.er
(Except(It(Does)
Elixir's(Syntax(Makes
Erlang's)Ecosystem)More)
Approachable
For$Your$Colleagues
Have%Compassion
Dev$Tooling
Mix
• Build'Tool
• Create/Compile/Test'projects
• Dependency'management
$ mix new hello_world
$ cd hello_world
$ mix deps.get
Hex
How$Are$We$Gonna$Run$This?
Live%In%The%Cloud
• On$demand$test$environments
• Expand$or$contract$your$live$cluster
DevOps
Make%opera)ons%every%engineer's%responsibility
• Protect(your(culture
• Control(your(live(service
• Don't(become(beholden(to(a(service(organiza:on(with(a(
monopoly
Operate'without'the'extra'headcount
No#Opera)ons?
Who$Will$Build$Our$Machines?
Terraform
• Abstrac)on,for,Cloud,providers
• Allows,you,to,describe,network/server,resources,in,code
• Security,Groups
• VPCs,,Subnets
• Virtual,Instances
• And,more
Who$Will$Configure$Our$Machines?
Chef
• Configura*on+Management+Tool
• Allows+you+to+describe+node+resources+in+code
• Files
• Directories
• Services
Terraform(to(provision(your(nodes
Chef%to%bootstrap%your%nodes
No#Such#Thing#As#DevOps#Team
Every&server&engineer&needs&to&understand&Elixir,&OTP,&Chef,&and&
the&automa:on&tooling&to&leverage&the&cloud.
Foster'Adop+on
For$Your$Technology$Choices
• Make&on)ramps&for&your&teammates
• Create&a&safe&to&fail&environment
• Create&and&evangelize&pa9erns&and&standardiza:ons.&Allow&for&
collabora:on.&(Illusion&of&choice?)
Code%Reviews
• Assist&with&learning
• Keep&a&posi2ve&tone&in&your&code&reviews.&Stay&away&from&an&
authorata2ve&tone&(I&love&you&but&I&push&you&in&the&dirt)
• Generic&praise&is&not&enough
• Avoid&syntax/style&discussions
Architec(ng+The+Service
Three%Components%of%An%Online%Game
• Game&Client
• Game&Server(s)
• Service&Pla4orm
Game%Client
• Executable+on+your+device+(game.app,+game.exe,+etc)
• Draws+images+at+30++fps
• Sends+and+receives+data+to+game+server
Game%Server(s)
• Simulate*the*game
• Nego/ates*with*clients
• Communicate*with*pla6orm
Pla$orm
• Game&agnos+c
• Highly&available
• Game&experience&s+tching
• Provides&services&to&games
• Auth,&Chat,&Presence,&Leaderboards,&Guilds,&Player&Profile,&and&
more
Tubes
(Pla%orm)
Q.#Where#to#start?
A.#With#only#exactly#what#you#need.
Iden%fy(A('Proving'(Feature
Presence'Updates'From'One'Player'
To'Another
Set$Expecta*ons$With$Your$
Publisher
And$Help$Inform$Milestones
Building(The(Main(Players
Protocol,(Route,(Lobby,(and(Chat
The$Suppor*ng$Cast
Spawn,'Match,'and'Versioner
Protocol'Layer
• TCP
• Binary+messages
Undead&Server&Message&Anatomy
• 32$96'bit'message'envelope
• Message'ID'with'a'fixed'max'length
• Variable'size'body'with'a'fixed'max'length
Message&Evelope
3"Parts"("32"Bits"each
• Header'Info
• Rou.ng'Info'(op.onal)
• Transac.on'Info'(op.onal)
Header&Info
• Rou%ng(Info((1(bit)
• Transac%on(Info((1(bit)
• Reserved((4(bits)
• Message(ID(Length((6(bits)
• Body(Length((20(bits)
Header&Binary
<<header_field::size(32)>> = <<has_routing::size(1),
has_txn::size(1),
reserved::size(4),
byte_size(message_id)::size(6),
byte_size(body)::size(20)>>
Binary'Pa)ern'Matching
Is#More#Intui,ve#Than#Bit#Shi3ing
Routed'Messages
Rou$ng'Info'(op$onal)
• Route'Hash'(22'bits)
• Protocol'ID'(10'bits)
Rou$ng'Binary
<<routing_field::size(32)>> = <<route_hash::size(22),
protocol_id::size(10)>>
Non$Transac*onal,Versus,
Transac*onal,Messages
Transac'ons
• Complete)when)client)receives)a)message)with)the)transac4on)
complete)flag)set
• Client)automa4cally)4mes8out)long)running)transac4ons
• Client)can)receive)a)transac4on)extension)message)to)avoid)
4meout
• Client)can)receive)a)par4al)message)to)build)a)complete)response
Transac'on)Info)(op'onal)
• Is$Response$(1$bit)
• Is$Par3al$(1$bit)
• Transac3on$ID$(30$bits)
Transac'on)Binary
<<txn_field::size(32)>> = <<txn_response::size(1),
txn_partial::size(1),
txn_id::size(30)>>
Make%It%Easy%To
Define%And%Handle%New%Messages
Protocol'Message'Defini1on
defmodule TUProtocol.Chat do
use TUProtocol.Behaviour, protocol_id: 1
protocol_message "WhisperSend" do
field :sender_id, :integer
field :receiver_name, :string
field :receiver_tag, :integer
field :content, :string
end
# ... other definitions
end
Elixir&Macros
Used%macros%to%make%it%easy%to%define%a%new%protocol%and%protocol%
message
Lobby%Server
• Provides*a*persistent*connec0on*for*clients
• Nego0ates*with*"core"*pla8orm*services
• Auth,*Chat,*Presence
• Communicates*with*pla8orm*to*get*a*connec0on*to*a*suitable*
game*server
• Mul0@tenant*service
• Connects*as*client*to*Route
Route&Server
• Ranch'Listener
• Peek'at'message'envelop'and'route'message'accordingly
• Tag'messages'with'route'acceptor'pid
• Disconnects'misbehaving'clients
• Rate'limit
• Hanging'/'Par?al'connec?on'flooding
Listener
defmodule Route.Listener do
alias Route.Config
def start do
:ranch.start_listener(__MODULE__, Config.acceptors,
:ranch_tcp, [port: Config.port], Route.ConnHandler, [])
end
end
Ranch&Documenta-on:
h"p://ninenines.eu/docs/en/ranch/HEAD/guide/introduc7on/
Establishing+Connec0ons
Client'To'Lobby
1. Client)connects)to)versioner
2. Versioner)1>)Match)for)the)loca7on)of)an)appropriate)Lobby
a.)Match)1>)Spawn)to)create)an)appropriate)Lobby)server)if)not)
exis7ng
b.)Versioner)caches)response
3. Versioner)1>)Client)with)Lobby's)address
4. Client)connects)to)Lobby
Client'To'Game
1. Lobby'(>'Match'with'a'game'join'request
2. Match'(>'Spawner'if'appropriate'game'server'is'not'running'for'
game'type'and'version
3. Match'(>'Lobby'with'address'of'game'server'and'reservaAon'
token
4. Lobby'(>'Client'with'address'of'game'server'and'reservaAon'
token
5. Client'connects'to'game'server'with'reservaAon'token
Lobby%&%Game%+>%Route
Explore(Login(&(Whisper(To(Chat
Rou$ng'The'Message
%ChatMsg.Login{protocol_id: 1,
message_id: "Login",
acceptor: route_acceptor_pid,
account_id: id,
account_name: "reset",
account_tag: 1984} = message
• Send&to&any&known&Chat&server
• handle_message/1&matching&%ChatMsg.Login{}&will&
handle&message
Message&Dispatcher
defmodule Chat.Dispatcher do
alias Protocol.Chat.Message, as: ChatMsg
use Net.Dispatcher
def handle_message(%ChatMsg.Login{} = request) do
case Chat.User.login(request) do
:ok ->
{:reply, NetError.success}
{:error, :banned} ->
{:reply, NetError.banned("ch:login:1")}
end
end
# ... other handle_message/1 clauses
end
The$Net.Dispatcher$Behaviour
• Re$usable*behaviour
• Simply:*use Net.Dispatcher
• Creates*a*registered*Erlang*process
• Implement*handle_message/1*callbacks*matching*protocol*
messages
• Quickly*dispatches*to*worker*processes*to*run*matching*
handle_message/1*callback
def handle_message(%ChatMsg.Login{} = request) do
case Chat.User.login(request) do
:ok ->
{:reply, NetError.success} # <--- NetError
{:error, :banned} ->
{:reply, NetError.banned("ch:login:1")} # <--- NetError
end
end
NetError
• Actually)kind)of)named)poorly...)Should)be)NetResponse?
• Special)type)of)Protocol)Message
• Contains)two)parts
• Code)A)Unique)error)code)to)Undead)servers
• Message)A)Unique)error)string)to)help)idenEfy)source)of)issue
Login&(And&Subscribe)
def init([user, %ChatMsg.Login{} = txn]) do
{:ok, feed} = Chat.PresenceFeed.start_link
account = %Account{id: user.id, name: user.name, tag: user.tag}
state = %{login_txn: txn, socket: txn.acceptor, account: account, presence_feed: feed}
{:ok, state, 0}
end
def handle_info(:timeout, %{login_txn: %ChatMsg.Login{} = request, account: account} = state) do
complete_login_txn(request, account)
{:noreply, %{state | login_txn: nil}, 0}
end
def handle_info(:timeout, %{socket: socket, account: account, entity: entity} = state) do
monitor_ref = Process.monitor(socket)
Enum.each friends(account), fn(%{account_id: receiver}) ->
broadcast_online(receiver, {account, self})
end
{:noreply, %{state | monitor_ref: monitor_ref, active_sockets: [{socket, monitor_ref}]}}
end
Lose%Connec)on%To%Lobby?
def handle_info({:DOWN, ref, _, _, _}, %{monitor_ref: ref} = state) do
{:stop, :normal, state}
end
def terminate(_, %{presence_feed: feed}) do
PresenceFeed.update(feed, @offline)
:ok
end
Presence
• Add$PresenceFeed$to$user$process
• A0empt$broadcast$when$coming$online
• Users$receiving$broadcast$subscribe$to$your$presencefeed
• You$subscribe$to$users$subscribing$to$your$presencefeed
• Handlers$are$removed$if$user$process$is$shutdown
• User$process$is$shutdown$if
• Primary$connec?on$is$terminated
Sending'A'Presence'No/fica/on
defmodule Protocol.Route do
import Protocol.Serializer, only: [encode!: 2]
def client_send(message, handler) when is_map(message) and is_pid(handler) do
encoded = encode!(message, routing: false)
case message do
%{time_start: start, txn_response: 1, txn_partial: 0} ->
GenServer.cast(handler, {:send, {:reply, encoded, start}})
_ ->
GenServer.cast(handler, {:send, {:message, encoded}})
end
end
end
Forwarding*A*Presence*No1fica1on
defmodule Route.ConnHandler do
# ....
def handle_cast({:send, message}, %{wait_timeout: wait, last_heard: heard} = state) do
case message do
{:reply, data, nil} ->
send_data(data, state)
{:reply, data, start} ->
time_end = :timer.now_diff(:os.timestamp, start)
Route.Metrics.report("tu_route.transaction_response_ms", (time_end / 1_000))
send_data(data, state)
{:message, data} ->
send_data(data, state)
end
new_timeout = wait - (Time.tick_count - heard)
{:noreply, state, :erlang.max(0, new_timeout)}
end
end
Distribu(ng+Tubes
Sharding
• Pre%shard*data*into*X*buckets
• Buckets*are*PostgreSQL*schemas
• Elixir*applica>ons*service*shards*(buckets)
• Broadcast*the*shards*to*route*servers
Internally)Rou-ng)Messages
• Route'messages'to'applica0on'servicing'desired'shard
• Hide'complexity'from'engineers
• Make'it'look'like'Elixir/Erlang
• Send'Erlang'messages'to'Net.Dispatchers
• One'process'(dispatch'worker)'per'request
Tubes&Net
defmodule Net do
@spec call(atom, integer | binary, atom, atom, list)
def call(protocol, route_key, module, function, arguments) do
# ...
end
@spec cast(atom, integer | binary, atom, atom, list)
def cast(protocol, route_key, module, function, arguments) do
# ...
end
end
defmodule Chat.User do
alias Protocol.Chat.Message, as: ChatMsg
def whisper(sender_id, receiver_id, body) do
Net.cast(Protocol.Chat, receiver_id,
__MODULE__, :rpc_whisper, [receiver_id, sender_id, body])
end
def rpc_whisper(receiver, sender, body) do
case lookup(receiver) do
{:ok, acceptor} ->
msg = %ChatMsg{receiver: receiver, sender: sender, body: body}
client_send(acceptor, msg)
_ -> :ok
end
end
end
Determinis)c+Rou)ng
We#Know#What#Shard#The#Message#Goes#To
Embedded&Shard&/&Create&Date&In&En11es
CREATE SEQUENCE next_id_seq;
CREATE OR REPLACE FUNCTION next_id(OUT result bigint) AS $$
DECLARE
our_epoch bigint := 1409266191000;
seq_id bigint;
now_millis bigint;
shard_id int := 1;
BEGIN
SELECT nextval('next_id_seq') % 1024 INTO seq_id;
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
result := (now_millis - our_epoch) << 23;
result := result | (seq_id << 13);
result := result | (shard_id);
END;
h"p://instagram.
engineering.tumblr.com/post/
10853187575/sharding.ids.at.
instagram
Extract'Shard'ID
def extract(id) when is_integer(id) do
extract(<<id::size(64)>>)
end
def extract(<<_::size(51), shard_id::size(13)>>) do
shard_id
end
Randomly)Determinis0c)Rou0ng
We#Don't#Know#What#Shard#The#Message#
Goes#To,#But#It#Will#Always#Go#There
Hash/Mod)Shard)Value
defmodule Tubes.Shard do
use Bitwise
@divisor 128
def hash(value) when is_binary(value) do
String.downcase(value) |> Fnv1a.hash
end
def mod(value) when is_integer(value) do
(value &&& (@divisor - 1))
end
end
defmodule Fnv1a do
use Bitwise
@offset 2166136261
@prime 16777619
def hash(term) when is_binary(term) do
_hash(@offset, 0, term)
end
def hash(term) do
:erlang.term_to_binary(term) |> hash
end
defp _hash(hash, byte_offset, bin) when byte_size(bin) == byte_offset, do: hash
defp _hash(hash, byte_offset, bin) do
<<_::size(byte_offset)-binary, octet::size(8), _::binary>> = bin
xord = hash ^^^ octet
hash = rem((xord * @prime), (2 <<< 31))
_hash(hash, byte_offset + 1, bin)
end
end
FNV$1a'Hashing
h"p://www.isthe.com/chongo/tech/comp/fnv
h"p://programmers.stackexchange.com/ques5ons/49550/which<
hashing<algorithm<is<best<for<uniqueness<and<speed
Shard&Directory
• Net%func*ons%hash/mod%route%key%for%shard%ID
• Peek%in%ShardDirectory%to%iden*fy%Erlang%node%servicing%shard%&%
protocol%combina*on'
Discovery
Automa'cally+Discover+And+Connect+To+Erlang+
Nodes
github.com/undeadlabs/discovery
Discovery*Breakdown
• Poller'('Discover'nodes'running'an'OTP'applica6on
• PollerEvent'('Callbacks'to'run'when'poller'finds'something
• Handler'('Behavior,'callbacks'to'run'when'poller'event'is'fired
• Heartbeat'('Broadcast'availability
Chat%Supervisor%init/1%Snippet
children = [
worker(Discovery.Poller, ["tu_route", [
{Discovery.Handler.NodeConnect, [
{Tubes.RouteConnector, [:tu_chat, Chat.Repo.shard_ids]}
]}
]], id: Poller.Route),
worker(Discovery.Heartbeat, [@heartbeat_check, Config.heartbeat_ttl])
]
supervise(children, strategy: :one_for_one)
RouteConnector
• When&connec)on&is&made
• Register&serviced&shards&with&Route&server's&shard&directory
• Retry&registra)on&on&failure
Discovery,+Thanks+to+Erlang
Will$automa*cally$re/connect$nodes$which$
become$disconnected
Game%Servers
Instanced)And)Distributed
World&Server
• "Town"
• Quest,hub
• Player,interac6on
• Chat
• Store
Combat'Server
• Player(vs(Player
• Player(vs(AI
Other&Services
Admin
• Powered(by
• Phoenix,(Ecto,(Ember.js
• Administra9ve(console(for(game(masters
• Gi?(items
• Kick/Ban(players
Catalogue
• Provides*a*catalogue*of*purchaseable*items*with
• Price*"8er"
• Friendly*name
• Internal*item*ID
• Automa8cally*download/transforms*store*data*output*from*build*
server
Fulfillment
• Mediates)purchasing)from)client)to
• Steam/iOS/Android/Kindle)AppStore
• All)transac:ons)are)idempotent
• Delivers)goods)to)user's)mailbox
Mail
• Asynchronous+message+storage
• A1achment+support+to+deliver+goods+to+players
• Used+for
• Gi:ing+and+purchasing
• Sending+messages/items+between+players
No#fy
• Push&no)fica)on&mediator
• Send&push&no)fica)ons&to&devices
• Supports&X&number&of&push&no)fica)on&services
Vault
• Completely*game*agnos/c
• Player*Data*persistence*layer
• Storage*for
• Character*data
• Inventory*Data
• Shared*storage*for*guilds
All#Services#Exposed#Through#Same#
API
Fun$Addi(onal$Problems$Solved
• Building)OTP)Releases)For)Elixir)Apps
• Account)Name)+)Tag
• (Brutally))Hacking)in)schema)support)into)Ecto
• Game)agnosDc)item)fulfillment
What's'Next?
• Automa(c*shard*migra(on
• Expanding*and*contrac(ng
• Automa(c*shard*re6balancing
• Addi(onal*PvP/E6Sports*features
• Guilds/Community*features
• Always*improving*performance
Jamie&Winsor
@resetexistence
github.com/reset
Over%me!
Monitoring(Your(App
• Wombat(Erlang(Solu0ons
• Metrics(6(Instrumental
• Log(Collec0on(6(Sumologic

More Related Content

What's hot

OOUG: Oracle transaction locking
OOUG: Oracle transaction lockingOOUG: Oracle transaction locking
OOUG: Oracle transaction locking
Kyle Hailey
 
Transparent Data Encryption in PostgreSQL and Integration with Key Management...
Transparent Data Encryption in PostgreSQL and Integration with Key Management...Transparent Data Encryption in PostgreSQL and Integration with Key Management...
Transparent Data Encryption in PostgreSQL and Integration with Key Management...
Masahiko Sawada
 

What's hot (20)

Data Driven Game development
Data Driven Game developmentData Driven Game development
Data Driven Game development
 
OOUG: Oracle transaction locking
OOUG: Oracle transaction lockingOOUG: Oracle transaction locking
OOUG: Oracle transaction locking
 
Oracle GoldenGate FAQ
Oracle GoldenGate FAQOracle GoldenGate FAQ
Oracle GoldenGate FAQ
 
Smart monitoring how does oracle rac manage resource, state ukoug19
Smart monitoring how does oracle rac manage resource, state ukoug19Smart monitoring how does oracle rac manage resource, state ukoug19
Smart monitoring how does oracle rac manage resource, state ukoug19
 
Oracle 12c and its pluggable databases
Oracle 12c and its pluggable databasesOracle 12c and its pluggable databases
Oracle 12c and its pluggable databases
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기
 
A deep dive about VIP,HAIP, and SCAN
A deep dive about VIP,HAIP, and SCAN A deep dive about VIP,HAIP, and SCAN
A deep dive about VIP,HAIP, and SCAN
 
Transparent Data Encryption in PostgreSQL and Integration with Key Management...
Transparent Data Encryption in PostgreSQL and Integration with Key Management...Transparent Data Encryption in PostgreSQL and Integration with Key Management...
Transparent Data Encryption in PostgreSQL and Integration with Key Management...
 
MyRocks introduction and production deployment
MyRocks introduction and production deploymentMyRocks introduction and production deployment
MyRocks introduction and production deployment
 
SQLite3
SQLite3SQLite3
SQLite3
 
Exadata X8M-2 KVM仮想化ベストプラクティス
Exadata X8M-2 KVM仮想化ベストプラクティスExadata X8M-2 KVM仮想化ベストプラクティス
Exadata X8M-2 KVM仮想化ベストプラクティス
 
Treinamento Data Guard
Treinamento Data GuardTreinamento Data Guard
Treinamento Data Guard
 
Weighted Blended Order Independent Transparency
Weighted Blended Order Independent TransparencyWeighted Blended Order Independent Transparency
Weighted Blended Order Independent Transparency
 
20220331_DSSA_MigrationToYugabyteDB
20220331_DSSA_MigrationToYugabyteDB20220331_DSSA_MigrationToYugabyteDB
20220331_DSSA_MigrationToYugabyteDB
 
MyRocks Deep Dive
MyRocks Deep DiveMyRocks Deep Dive
MyRocks Deep Dive
 
게임 디자이너와 게임 서버
게임 디자이너와 게임 서버게임 디자이너와 게임 서버
게임 디자이너와 게임 서버
 
Future Directions for Compute-for-Graphics
Future Directions for Compute-for-GraphicsFuture Directions for Compute-for-Graphics
Future Directions for Compute-for-Graphics
 
Practical SPU Programming in God of War III
Practical SPU Programming in God of War IIIPractical SPU Programming in God of War III
Practical SPU Programming in God of War III
 
[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기
 
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
 

Similar to Building And Releasing A Massively Multiplayer Online Game

Components are the Future of the Web: It’s Going To Be Okay
Components are the Future of the Web: It’s Going To Be OkayComponents are the Future of the Web: It’s Going To Be Okay
Components are the Future of the Web: It’s Going To Be Okay
FITC
 
Community Panels: Pandora's Box or Panacea
Community Panels: Pandora's Box or PanaceaCommunity Panels: Pandora's Box or Panacea
Community Panels: Pandora's Box or Panacea
vcuniversity
 
E-Primer Your Business Online
E-Primer Your Business OnlineE-Primer Your Business Online
E-Primer Your Business Online
guestfc9d8a
 

Similar to Building And Releasing A Massively Multiplayer Online Game (20)

Building And Releasing an Online Game From Nothing With NoOps - ChefConf 2015
Building And Releasing an Online Game From Nothing With NoOps - ChefConf 2015Building And Releasing an Online Game From Nothing With NoOps - ChefConf 2015
Building And Releasing an Online Game From Nothing With NoOps - ChefConf 2015
 
Stay Awhile And Fiddle With Your Smartphone
Stay Awhile And Fiddle With Your SmartphoneStay Awhile And Fiddle With Your Smartphone
Stay Awhile And Fiddle With Your Smartphone
 
Components are the Future of the Web: It’s Going To Be Okay
Components are the Future of the Web: It’s Going To Be OkayComponents are the Future of the Web: It’s Going To Be Okay
Components are the Future of the Web: It’s Going To Be Okay
 
07 samyagan
07 samyagan07 samyagan
07 samyagan
 
sam presso
sam pressosam presso
sam presso
 
Delve Prototyping In The Wild
Delve Prototyping In The WildDelve Prototyping In The Wild
Delve Prototyping In The Wild
 
What Problem Is Your Startup Solving?
What Problem Is Your Startup Solving?What Problem Is Your Startup Solving?
What Problem Is Your Startup Solving?
 
Community Panels: Pandora's Box or Panacea
Community Panels: Pandora's Box or PanaceaCommunity Panels: Pandora's Box or Panacea
Community Panels: Pandora's Box or Panacea
 
Digital Business Strategy Workshop
Digital Business Strategy Workshop Digital Business Strategy Workshop
Digital Business Strategy Workshop
 
JaanSi Solutions & Services profile (v1.0)
JaanSi Solutions & Services profile (v1.0)JaanSi Solutions & Services profile (v1.0)
JaanSi Solutions & Services profile (v1.0)
 
Eastside incubator - Startup in Seattle
Eastside incubator - Startup in SeattleEastside incubator - Startup in Seattle
Eastside incubator - Startup in Seattle
 
E-Primer Your Business Online
E-Primer Your Business OnlineE-Primer Your Business Online
E-Primer Your Business Online
 
How to become hacker
How to become hackerHow to become hacker
How to become hacker
 
Profiling for Grown-Ups
Profiling for Grown-UpsProfiling for Grown-Ups
Profiling for Grown-Ups
 
Innate In House Design
Innate In House DesignInnate In House Design
Innate In House Design
 
Frontend First Design & Development
Frontend First Design & DevelopmentFrontend First Design & Development
Frontend First Design & Development
 
The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016
 
Green Light for the Apps with Calaba.sh - DroidCon Paris 2014
Green Light for the Apps with Calaba.sh - DroidCon Paris 2014Green Light for the Apps with Calaba.sh - DroidCon Paris 2014
Green Light for the Apps with Calaba.sh - DroidCon Paris 2014
 
The Future of Progressive Web Apps - View Source conference, Berlin 2016
The Future of Progressive Web Apps - View Source conference, Berlin 2016The Future of Progressive Web Apps - View Source conference, Berlin 2016
The Future of Progressive Web Apps - View Source conference, Berlin 2016
 
Teaching the Principles of Computer Science to Primary-Aged Children
Teaching the Principles of Computer Science to Primary-Aged ChildrenTeaching the Principles of Computer Science to Primary-Aged Children
Teaching the Principles of Computer Science to Primary-Aged Children
 

Recently uploaded

VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
MsecMca
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
amitlee9823
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
dharasingh5698
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 

Recently uploaded (20)

VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 
Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Bhosari ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready For ...
Bhosari ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready For ...Bhosari ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready For ...
Bhosari ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready For ...
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna Municipality
 

Building And Releasing A Massively Multiplayer Online Game