Introducing Rachinations, a game execution engine and Ruby-based DSL that can be used to test out game designs and evaluate hypotheses and analyze gameplay. It is an implementation of Dr. J. Dormans' Machinations framework for game design.
2. Complexidade
● Atenção da ciência em geral
○ Muito grande ou muito pequeno (muita atenção)
○ Tamanho médio (menos atenção)
● Ciência tinha foco em reducionismo (até meados do séc 20)
○ Depois, estudos multidisciplinares foram surgindo
● Sistemas complexos
○ Emergência, auto-organização, ordem espontânea
3. Dinâmica de sistemas
● Uma forma de modelar sistemas complexos
● Introduzida por J. Forrester, década de 50
● O sistema é modelado em termos de estoques e fluxos
4. Jogos
● São sistemas complexos
● São regidos por uma mecânica interna
● Não é simples prever como um jogo irá se comportar
○ Muitas variáveis
○ Vários níveis na análise (tática, estratégia, etc)
○ Relacionamentos nem sempre fáceis de identificar
○ Jogabilidade (gameplay)
■ Quão divertido um jogo é
■ Como definir e medir?
5. Modelando jogos
● Máquinas de estado finito
● Redes de Petri
● Diagramas de jogos
○ Ralph Koster (2005)
○ Stéphane Bura (2006)
○ Diagramas UML (vários autores)
○ Machinations (2008)
6. Machinations
● Busca modelar a economia interna de um jogo
○ Ou seja, o fluxo de recursos que se movem durante um jogo
Ex.: Banco imobiliário
7. Machinations é legal mas
● É baseado em linguagem visual
○ Difícil de escalar
● Difícil de criar abstrações para subir o nível
● Implementação em Flash
○ Dificulta extensão
8. Ruby
● Linguagem de programação dinâmica.
● Foco no usuário, não na máquina.
● Liberal, dinamicamente tipada, boa para metaprogramação, totalmente
orientada a objetos (até tipos primitivos), grande comunidade.
● Exemplos:
"ice is nice" .length # => 11
"Nice Day Isn't It?" .downcase.split("").uniq.sort.join # => " '?acdeinsty"
[1, 'hi', 3.14].each {|item| puts item } # imprime: 1 'hi' 3.14
[1,3,5].reduce(10) {|sum, element | sum + element} # => 19
9. Rachinations = Ruby+Machinations
● A ideia foi implementar o Machinations em uma linguagem de
programação textual (não visual).
● O usuário poderia “escrever” um diagrama em formato texto e “executá-
lo”, debugar, obter métricas, testar hipóteses e usar todo o ferrramental já
disponível para código.
● Seria mais fácil construir abstrações de mais alto nível sobre as primitivas
originais do Machinations (nós, arestas, etc), bem como patterns.
● Criar uma DSL para interfacear com o usuário leigo (não-programador).
12. Rachinations v1: Esquema geral
● Usuário chama o método run!
● Este método, por sua vez, chama o método run_round! até que se
esgotem os turnos ou alguma condição de parada seja satisfeita
● O método run_round! executa os seguintes passos:
● Para cada nó no diagrama, fazer:
○ Este nó está habilitado? (enabled?)
○ Este nó deve ser gatilhado? (é automático ou inicial?)
○ Se sim, chame o método trigger! neste nó
■ O método trigger! fará todo o trabalho
13. Rachinations v1: limitações
● Rachinations é muito verboso.
● Muita escrita para descrever um diagrama Machinations relativamente
simples.
● Difícil para não programadores.
● Dificilmente seria adotado por muitos usuários.
14. Rachinations: DSL
● Mais enxuta e fácil de usar
● Só foi possível fazer isso por causa da flexibilidade da linguagem Ruby
● Muita metaprogramação
● Tentar fazer algo que “just works”
○ Funcione logo “de cara”
○ Sem surpresas
○ Defaults razoáveis
15. Rachinations: Internas da DSL
● Crio um método diagram que recebe um bloco de código como
parâmetro
○ Este método instancia um diagrama e executa o bloco de código
recebido no escopo do diagrama criado.
● Usando metaprogramação, reabro a classe Diagram em tempo de
execução e adiciono métodos mais curtos, mais livres e mais espertos.
○ Ex.: se o parâmetro :push_all foi passado ao método pool, eu
posso deduzir que isto é um modo de execução do nó, não preciso
exigir que o usuário passe mode: :push_all explicitamente.
16. Rachinations v2: Exemplo lado a lado
Usando a DSL Sem DSL (equivalente) Diagrama Machinations
equivalente
d = Diagram.new 'ainda simples'
d.add_node! Source, {
:name => 's1',
:activation => :automatic
}
d.add_node! Pool, {
:name => 'p1',
:initial_value => 0
}
d.add_node! Pool, {
:name => 'p2',
:initial_value => 0,
:activation => :automatic
}
d.add_edge! Edge, {
:name => 'e1',
:from => 's1',
:to => 'p1'
}
d.add_edge! Edge, {
:name => 'e2',
:from => 'p1',
:to => 'p2'
}
diagram 'ainda simples' do
source 's1'
pool 'p1'
pool 'p2', :automatic
edge from: 's1', to: 'p1'
edge from: 'p1', to: 'p2'
end
17. Rachinations v2: Exemplos completos
require 'rachinations'
d=diagram 'exemplo_2' do
source 's1'
pool 'p1'
converter 'c1', :automatic
pool 'p2'
pool 'p3'
edge from: 's1', to: 'p1'
edge from: 'p1', to: 'c1'
edge from: 'c1', to: 'p2'
edge from: 'c1', to: 'p3'
end
d.run 10
Diagrama Machinations
equivalente
18. Rachinations v2: Exemplos completos
require 'rachinations'
d=diagram 'exemplo_3' do
source 's1'
pool 'p1'
edge from: 's1', to: 'p1'
stop expr{ p1.resource_count > 5 }
end
d.run
Diagrama Machinations
equivalente
uma expressão que, quando
é satisfeita, para a execução
do diagrama
19. Trabalhos futuros
● Usabilidade da DSL
○ Sem quebrar BC, de preferência
● Meios de compartilhar diagramas
○ Talvez um site onde você escreve um diagrama e o executa de forma
online, sem precisar baixar e instalar o Rachinations na sua máquina
■ Diminuir a barreira de entrada de usuários
● Meios de criar abstrações customizadas e usá-las como se fossem primitivas
● Quer ajudar?
20. Lições aprendidas
● Testar de mais é tão ruim quanto testar de menos
○ Código “quebradiço” (brittle)
● Design top-down e bottom-up
○ Escrever seu código como se as partes já estivessem prontas
○ Top-down facilita pensar sobre e escrever algoritmos complexos
● Diagramas de sequência para ajudar a pensar uma estratégia