Este modelo exclusivo do UEFN contém um jogo pequeno ao estilo de fábrica que apresenta tanto persistência e progressão off-line.
Os tutoriais dentro do modelo requerem conhecimento básico do Unreal Editor para Fortnite (UEFN) e a capacidade de abrir um arquivo Verse. Não há outros requisitos. O próprio modelo fornece as instruções do tutorial.
Boas-vindas à Fábrica de Brinquedos do Papai noel, um modelo da LEGO® que se concentra na retenção do jogador por meio de loops de jogo envolventes, usando:
- Persistência: salvamento de dados do jogador entre as sessões de jogo.
- Progressão off-line: a fábrica continua produzindo jogos mesmo quando o jogador não está no jogo, desde que haja espaço no contêiner da fábrica enquanto a floresta de bengalas doces continua crescendo com ou sem jogadores.
Com ambos combinados, você também pode criar mecânicas diárias que incentivam os jogadores a continuar retornando à sua ilha. Use este modelo para aprender a implementar essas mecânicas na sua própria ilha de fim de ano!
O modelo contém três tutoriais curtos.
- Iniciante: mostra como alterar o tempo de crescimento da floresta de bengalas doces em Verse.
- Intermediário: orienta ao longo da edição de uma variável em Verse.
- Avançado: permite modificar e adicionar ao código Verse.
Cada tutorial dentro do projeto mostra como usar Verse para alcançar a mecânica usada.
O modelo é dividido em três partes:
-
Jogar: comece jogando por 5 a 10 minutos para ter uma ideia de como ele funciona.
-
Criar: em seguida, você criará três modificações, seguindo os desafios do tutorial.
-
Explorar: por fim, você pode explorar por conta própria, separar todo o código documentado para ver como ele funciona e, em seguida, criar seu próprio jogo para as noites de fim de ano!
Reproduza
- No UEFN, carregue o modelo. Você o encontrará com os outros modelos da LEGO. Comece a jogar.
-
No jogo, para acompanhar a missão, vá até Sir Pawlar, que explicará o que fazer.
(w:600)
- Siga as instruções no jogo.
- Em algum momento, o tutorial solicitará que você encerre o jogo. Pressione Esc e depois End Game.
- Espere 2 minutos.
-
Depois dos 2 minutos, pressione Esc novamente e depois Start Game.
Isso pode parecer uma coisa estranho de pedir, mas demonstra um ponto muito importante. Neste jogo, as coisas continuam acontecendo enquanto você não está jogando! A fábrica continua produzindo, e a floresta de bengalas doces continua crescendo.
Essas são as mecânicas principais que podem incentivar os jogadores a voltar ao jogo para coletar ou coletar plantações que cresceram, ou recursos que foram produzidos ao longo do tempo.
-
Ao voltar ao jogo, você pode ver o que foi produzido enquanto você não estava no jogo:
(w:600)
Isso é feito no factory_manager.verse . Ele mede quanto tempo se passou enquanto o jogador estava fora de casa usando dados persistentes e o dispositivo Relógio em Tempo Real. Em seguida, calcula quanto a fábrica produziria durante esse tempo.
-
Depois de produzir a segunda compilação da fábrica, você receberá uma mensagem para voltar ao UEFN.
(w:400)
Seu primeiro tutorial foi concluído! Hora de avançar para os desafios criativos.
Criar
Hora da diversão! Você tem três desafios esperando.
Localize o primeiro, Freshman Flapjan. Ele está esperando por você em um dos três quadrados amarelos.
Desafio para iniciantes: modificar o tempo de recrescimento das bengalas doces
O primeiro desafio é simples. Ele mostrará o quanto você pode mudar o jogo apenas ajustando alguns valores — nesse caso, o tempo de ressurgimento dos campos de bengala doce.
- Ao lado de FlapJacket, você verá o dispositivo Bengala Doce criado com Verse.
- Selecione-o e verifique se também tem o painel Details selecionado.
-
Ajuste o parâmetro CandyCaneRegrowthTime – faça testes e veja como isso afeta a jogabilidade.
Desafio intermediário: modificar valores de atualização
O segundo desafio levará para o próprio código do Verse.
Novamente, você verá o quanto é possível mudar o ritmo e a sensação do jogo apenas ajustando os valores para atualizar sua fábrica.
-
Abra o arquivo upgrade_config.verse do Explorador do Verse.
-
Você pode ver todos os valores para atualização dos vários elementos da fábrica. O primeiro lote de valores é para as esteiras da fábrica. Existem quatro esteiras na fábrica, então a tabela de valores contém quatro colunas. Cada linha da tabela corresponde ao preço do aprimoramento de uma esteira para esse nível.
~~~(verse) # Este arquivo contém os dados usados para configurar a fábrica no jogo. # Isso inclui valores de atualização, níveis máximos, velocidades de produção, capacidades de armazenamento e muito mais. # Ele também contém funções para obter todos esses dados.
using { /Verse.org/Simulation } usando { persistência }
# Bluebberchops: "Parece que este é o lugar para modificar os valores de atualização das esteiras." # "Vamos torná-las mais baratas!"
# Define o preço de atualização por nível para cada esteira da fábrica. FactoryBeltPrices: [][]int = # Cada coluna é uma esteira. 0 1 2 3 # Cada linha é um nível. array{ array{ 5, 25, 500, 5000}, array{ 25, 125, 2500, 25000}, array{ 100, 500, 10000, 100000}, array{ 200, 1000, 20000, 200000}, array{ 300, 1500, 30000, 300000}, array{ 400, 2000, 40000, 400000}, array{ 500, 2500, 50000, 500000}, array{ 750, 3750, 75000, 750000}, array{ 1000, 5000, 100000, 1000000}, array{ 1500, 7500, 150000, 1500000}, array{ 2000, 10000, 200000, 2000000}, array{ 2500, 12500, 250000, 2500000}, array{ 3000, 15000, 300000, 3000000}, array{ 4000, 20000, 400000, 4000000}, array{ 5000, 25000, 500000, 5000000}} ~~~
- Siga o aviso de Bluebberchops e reduza o preço do aprimoramento das esteiras. Você também pode experimentar aumentar o preço para diminuir o ritmo do jogo.
-
Quando estiver pronto, crie o código Verse e envie as alterações de Verse para testá-las.
[]
Para obter mais informações sobre o que você está fazendo nesta etapa, consulte Modifique e execute seu primeiro programa em Verse.
- Observe que sempre que você enviar alterações na sessão, o progresso da fábrica será redefinido.
Desafio para especialista: O presente diário
O terceiro e último desafio exige que você trabalhe no presente diário ao lado do professor Flopkin.
(w:600)
Para fazer isso, você precisará adicionar alguns dados persistentes extras para armazenar quando o presente foi aberto pela última vez. Você também precisará corrigir a lógica no dispositivo de autoria do Presente Diário em Verse.
Consulte https://dev.epicgames.com/documentation/en-us/uefn/using-persistable-data-in-verse para obter mais informações sobre como trabalhar com dados persistentes em Verse.
Se precisar de uma ajuda para superar esse desafio, dê uma olhada no dispositivo Presente Diário abaixo!
-
Abra o arquivo player_info.verse do Explorador do Verse.
-
Procure os comentários do Professor Flopkins na parte superior do arquivo.
Adicione um campo de matriz "date_and_time" à classe "player_info" para armazenar a última vez que o presente foi aberto. Certifique-se também de que o valor do campo está definido no construtor "MakePlayerInfo".
~~~(verse) # Este arquivo define player_info, a coleção de informações persistentes armazenadas para cada jogador. # Também contém funções para criar, atualizar e retornar informações sobre um jogador.
using { /Verse.org/Simulation } usando { Config } using { Time }
# Mapeia cada jogador para suas informações persistentes. var PlayerInfoMap:weak_map(player, player_info) = map{}
# Isso rastreia todas as informações persistentes para um jogador. player_info := class
: # A versão das informações atuais do jogador. Version:int = 0
# Últimos tempos de coleta de todas as canas-doce. CandyCaneHarvestTimes:[]date_and_time = array{date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{} , data_and_time{}, data_and_time{}, data_and_time{}}
# A quantidade de ouro que o jogador possui. Gold:int = 0
# O estado da fábrica. FábricaBeltInfos:[]factory_belt_info = array{factory_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}} FábricaMouldInfos:[]factory_mould_info = array{factory_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}} FactoryWrapperInfos:[]factory_wrapper_info = array{factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}} FactoryStorageInfo:factory_storage_info = factory_storage_info{}
# A ordem atual. OrderNumber:int = 0 OrderInfo:order_info = order_info{}
# professor Flopins: "Hmm, devemos armazenar a data e a hora." # "Talvez possamos usar algo parecido com a linha 18?"
# Cria uma nova player_info com os mesmos valores da player_info anterior. MakePlayerInfo
-
Corrija as funções para obter e configurar o campo recém-adicionado. Dessa vez, procure os comentários do Professor Flopins na parte inferior do arquivo.
Preencha as linhas que faltam para fazer com que as funções se comportem corretamente. Você pode ver algumas das outras funções no arquivo para se inspirar.
~~~(verse) # Este arquivo define player_info, a coleção de informações persistentes armazenadas para cada jogador. # Também contém funções para criar, atualizar e retornar informações sobre um jogador.
using { /Verse.org/Simulation } usando { Config } using { Time }
# Mapeia cada jogador para suas informações persistentes. var PlayerInfoMap:weak_map(player, player_info) = map{}
# Isso rastreia todas as informações persistentes para um jogador. player_info := class
: # A versão das informações atuais do jogador. Version:int = 0
# Últimos tempos de coleta de todas as canas-doce. CandyCaneHarvestTimes:[]date_and_time = array{date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{} , data_and_time{}, data_and_time{}, data_and_time{}}
# A quantidade de ouro que o jogador possui. Gold:int = 0
# O estado da fábrica. FábricaBeltInfos:[]factory_belt_info = array{factory_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}} FábricaMouldInfos:[]factory_mould_info = array{factory_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}} FactoryWrapperInfos:[]factory_wrapper_info = array{factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}} FactoryStorageInfo:factory_storage_info = factory_storage_info{}
# A ordem atual. OrderNumber:int = 0 OrderInfo:order_info = order_info{}
# professor Flopins: "Hmm, devemos armazenar a data e a hora." # "Talvez possamos usar algo parecido com a linha 18?"
# Cria uma nova player_info com os mesmos valores da player_info anterior. MakePlayerInfo
-
Com a nova funcionalidade para dados persistentes pronta, abra o arquivo daily_gift.verse para mudar a lógica que faz com que o presente apareça apenas uma vez ao dia.
-
Você verá que estão faltando duas peças essenciais:
- Armazenar a hora atual em que o presente foi aberto e
- Verificar se a data foi revertida desde que o presente foi aberto pela última vez.
Siga os comentários do professor e adicione o código que está faltando.
~~~(verse) # Quando o presente for aberto (coletado), dê ouro ao jogador selecionado. OnHarvesting(Agent:agent):void= # Ocultar presente. set Opened = true PropManipulator.HideProps()
# Mostrar efeito. spawn: ShowGiftEffect()
Reproduzir áudio. GiftOpenAudioPlayer.Play()
# Dê ao jogador um pouco de ouro e o tempo de abertura da loja. if: SelectedPlayer := MaybeSelectedPlayer? GrantGold[SelectedPlayer, Gold]
# Professor Flopkins: "Parece que falta o código para armazenar o horário de abertura!" # "Primeiro, devemos obter a data e a hora atuais." # "Procure uma dica na função IsDateRolledOver sobre como fazer isso."
# Professor Flopins: "E, então, devemos armazenar esse tempo nos dados persistentes do jogador." # "Vi uma função para fazer isso na parte inferior de player_info.verse."
then: # Atualize a IU de todos os jogadores. UIManager.UpdateAllPriceUIs() UIManager.UpdateAllResourceUIs() ~~~
~~~(verse) # Tem êxito quando a data atual é diferente do horário de abertura. IsDateRolledOver()
:void= # Obter a data atual. Now := RealTime.GetDateAndTime() # Professor Flopins: "Hmm, também está faltando o código para determinar se a data foi revertida." # "Vejamos. primeiro, obteremos o jogador selecionado." # "Consulte a função OnHarvesting para ver como fazer isso."
# Professor Flopkins: "Agora, devemos recuperar a última data e hora em que o presente foi aberto." # "Existe uma função para fazer isso em player_info.verse."
# Professor Flopkins: "Finalmente, devemos comparar essa data com a data atual." # "Queremos que o ano, o mês ou a data seja diferente, pois significa a data" # "rolou." ~~~
-
Agora você está pronto para testar sua solução! Compile o código Verse e envie as alterações de Verse para testá-lo em sua sessão.
Você pode usar o botão de depuração de Sub Zero como um atalho para avançar no tempo de testar se o presente ressurge quando a data mudar.
Explore
Agora que você venceu seus desafios, é hora de explorar alguns dos outros dispositivos usados neste modelo.
Dispositivo de relógio de tempo real
O dispositivo Relógio em Tempo Real dá a você o tempo atual no Tempo Universal Coordenado (UTC). Também anima os ponteiros de um relógio.
Você pode usá-lo para eventos de direção que devem acontecer em um determinado horário todos os dias, ou para acompanhar quanto tempo se passou.
Ele vem com uma função de teste integrada que pode compensar a hora atual. Confira os arquivos real_time_device.verse, date_and_time.verse e time_interval.verse
Dispositivo Campo de Bengala Doce
O dispositivo de autoria do Verse Campo de Bengala Doce rastreia um campo de bengalas doces coletáveis. Fornece recursos quando elas são coletadas e faz com que cresçam novamente com o tempo. Você pode usá-lo para todos os tipos de recursos de regeneração. Confira o arquivo candy_cane_field.verse.
Módulo de persistência
Esse módulo contém todos os dados persistentes associados a cada jogador. A classe principal é a classe "player_info" no arquivo player_info.verse.
Esse arquivo também contém todas as funções para ler e manipular os dados. Você também deve conferir as outras classes no módulo, pois cada uma define alguns dos dados armazenados para cada jogador. Você pode modificá-los ou adicionar mais dados para atender às suas necessidades.
# Este arquivo define player_info, a coleção de informações persistentes armazenadas para cada jogador.
# Também contém funções para criar, atualizar e retornar informações sobre um jogador.
using { /Verse.org/Simulation }
usando { Config }
using { Time }
# Mapeia cada jogador para suas informações persistentes.
var PlayerInfoMap:weak_map(player, player_info) = map{}
# Isso rastreia todas as informações persistentes para um jogador.
player_info := class<final><persistable>:
# A versão das informações atuais do jogador.
Version:int = 0
# Últimos tempos de coleta de todas as canas-doce.
CandyCaneHarvestTimes:[]date_and_time = array{date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{} , data_and_time{}, data_and_time{}, data_and_time{}}
# A quantidade de ouro que o jogador possui.
Gold:int = 0
# O estado da fábrica.
FábricaBeltInfos:[]factory_belt_info = array{factory_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}}
FábricaMouldInfos:[]factory_mould_info = array{factory_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}}
FactoryWrapperInfos:[]factory_wrapper_info = array{factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}}
FactoryStorageInfo:factory_storage_info = factory_storage_info{}
# A ordem atual.
OrderNumber:int = 0
OrderInfo:order_info = order_info{}
~~~
### Dispositivo Presente Diário
Esse dispositivo gera um presente todos os dias, ou pelo menos geraria se estivesse funcionando!
Aqui está a solução do [**desafio para especialista**](expertchamplenge:repairthedailygift) para ajudar a aproveitar ao máximo o dispositivo Presente Diário criado em Verse. Você pode usá-lo para realizar todos os tipos de eventos e recompensas diárias.
1. Comece adicionando os dados necessários à classe "player_info" e modifique o construtor "MakePlayerInfo" no arquivo **player_info.verse**:
~~~(verse)
# Isso rastreia todas as informações persistentes para um jogador.
player_info := class<final><persistable>:
# A versão das informações atuais do jogador.
Version:int = 0
# Últimos tempos de coleta de todas as canas-doce.
CandyCaneHarvestTimes:[]date_and_time = array{date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{},date_and_time{} , data_and_time{}, data_and_time{}, data_and_time{}}
# A quantidade de ouro que o jogador possui.
Gold:int = 0
# O estado da fábrica.
FábricaBeltInfos:[]factory_belt_info = array{factory_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}, fábrica_belt_info{}}
FábricaMouldInfos:[]factory_mould_info = array{factory_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}, fábrica_mould_info{}}
FactoryWrapperInfos:[]factory_wrapper_info = array{factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}}
FactoryStorageInfo:factory_storage_info = factory_storage_info{}
# A ordem atual.
OrderNumber:int = 0
OrderInfo:order_info = order_info{}
# A última vez que o presente diário foi aberto.
GiftOpeningTime:date_and_time = date_and_time{}
# Cria uma nova player_info com os mesmos valores da player_info anterior.
MakePlayerInfo<constructor>(Src:player_info)<transacts> := player_info:
Version := Src.Version
CandyCaneHarvestTimes := Src.CandyCaneHarvestTimes
Gold := Src.Gold
FábricaBeltInfos := Src.FactoryBeltInfos
FactoryMouldInfos := Src.FactoryMouldInfos
FábricaWrapperInfos := Src.FactoryWrapperInfos
FactoryStorageInfo := Src.FactoryStorageInfo
OrderNumber := Src.OrderNumber
OrderInfo := Src.OrderInfo
GiftOpeningTime := Src.GiftOpeningTime
~~~
1. Preencha as funções "SetGiftOpeningTime" e "GetGiftOpeningTime":
~~~(verse)
# Define o tempo de abertura do presente para o jogador.
SetGiftOpeningTime<public>(Player:player, GiftOpeningTime:date_and_time)<decides><transacts>:void=
CheckPlayerInfoForPlayer[Player]
SourceInfo := PlayerInfoMap[Player]
set PlayerInfoMap[Player] = player_info:
MakePlayerInfo<constructor>(SourceInfo)
GiftOpeningTime := GiftOpeningTime
# Obtém o tempo de abertura do presente para o jogador.
GetGiftOpeningTime<public>(Player:player)<decides><transacts>:date_and_time=
CheckPlayerInfoForPlayer[Player]
PlayerInfoMap[Player].GiftOpeningTime
~~~
1. Volte sua atenção para a classe "daily_gift" no arquivo **daily_gift.verse**. Primeiro, preencha o armazenamento da hora atual ao abrir o presente:
~~~(verse)
# Quando o presente for aberto (coletado), dê ouro ao jogador selecionado.
OnHarvesting(Agent:agent):void=
# Ocultar presente.
set Opened = true
PropManipulator.HideProps()
# Mostrar efeito.
spawn:
ShowGiftEffect()
Reproduzir áudio.
GiftOpenAudioPlayer.Play()
# Dê ao jogador um pouco de ouro e o tempo de abertura da loja.
if:
SelectedPlayer := MaybeSelectedPlayer?
GrantGold[SelectedPlayer, Gold]
Now := RealTime.GetDateAndTime()
SetGiftOpeningTime[SelectedPlayer, Now]
then:
# Atualize a IU de todos os jogadores.
UIManager.UpdateAllPriceUIs()
UIManager.UpdateAllResourceUIs()
-
Implemente a função "IsDateRolledOver":
~~~(verse) # Tem êxito quando a data atual é diferente do horário de abertura. IsDateRolledOver()
:void= # Obtenha a data atual. Now := RealTime.GetDateAndTime() SelectedPlayer := MaybeSelectedPlayer? GiftOpeningTime := GetGiftOpeningTime[SelectedPlayer] Now.Years <> GiftOpeningTime.Years or Now.Months <> GiftOpeningTime.Months or Now.Days <> GiftOpeningTime.Days ~~~
Dispositivo Gerenciador de Fábrica
O dispositivo Gerenciador de Fábrica criado em Verse inicializa e executa a fábrica. Ele lida com o cálculo de quantos produtos foram feitos enquanto o jogador estava fora.
Esse cálculo pode ser complexo, pois o armazenamento da fábrica é compartilhado entre várias esteiras da fábrica. Em uma configuração mais simples, você pode calcular o número de produtos feitos calculando quanto tempo se passou desde a última produção e, em seguida, dividindo esse valor pela velocidade de produção.