Introduction to your code
Dowiesz się w jaki sposób powinien wyglądać ecosystem Twoich plików gry
Krótki słownik nazw należący do modułów
W Engine.Farm stosując moduły mamy możliwość łatego zarządzania zależnościami, w tym przypadku wykorzystujemy:
- GameState - stan gry utrzymywany w pamięci
- Entity - definicja obiektu z parametrami danych, każdy parametr może mieć zależność w postaci kolejnego Entity
- ReactiveAction - mechanizm do wywołania funkcji z danymi wejściowymi oraz opcjonalne wywołanie kolejnej z przetworzonymi danymi, możliwość ustawienia timingu
- Timing - wywołanie kolejnej akcji:
- OneTime - jednorazowo
- MaxDelay - po danym czasie
- OnEnd - po zakończeniu aktualnej akcji
- Repository - każdy moduł może mieć swoje oddzielne repozytoria danych ale służą tylko do zrzucenia danych ze stanu gry przy danej akcji lub pobrania danych jeśli są potrzebne
- Model - definicja obiektu przeznaczonego do zapisu w bazie danych
- Events - lista nasłuchiwanych zdarzeń z danymi wejściowymi (wraz z walidacją) i wywołanie reaktywnej akcji
- Controller - miejsce gdzie zdefiniowane są główne Eventy wywoływane przez gracza. To tutaj tworzysz, modyfikujesz i usuwasz obiekty stanu gry ponieważ nie wszystkie obiekty Entity muszą być w Repozytorium
Przykładowy plik konfiguracyjny
Ten plik powinien znajdować się w głównym folderze gry
game:
map:
file: world-1-map.obj
worlds:
world-1:
name: World name
sector: # spliting your world map to sectors
length: # 2 x 3 = 6 => 6 deployed sector (in your cluster will be 6 pods)
x: 2
y: 3
size:
x: 200
y: 200
engine:
fps: 16 # server frame rate
endpoint:
type: socketio # upd | socketio
modules:
players:
className: PlayerModule
path: modules/players/player.module.ts
characters:
className: CharacterModule
path: modules/character/character.module.ts
game.map - mapa gry zoptymalizowana tylko do punktów kolizyjnych, obiekty podlegające kolizji nie będą mogły przekroczyć tych punktów
game.worlds - lista światów do których użytkownik loguje się docelowo
game.worlds.X.sector - podział świata na sektory
game.worlds.X.sector.length - liczba sektorów x i y w 2D gdzie x to z po rzutaowaniu na 3D
game.worlds.X.sector.size - rozmiar każdego sektora, musi odpowiadać skali punktów mapy
engine.fps - żądana ilość obliczeń stanu gry na sekundę
modules - lista modułów gry - nie są automatycznie ładowane a kolejność nie ma znaczenia
Files Ecosystem
.
├── src/
│ ├── entities/
│ │ ├── hp.entity.ts
│ │ └── direction.entity.ts
│ ├── modules/
│ │ ├── game.module.ts
│ │ ├── game.state.ts
│ │ ├── player/
│ │ │ ├── player.module.ts
│ │ │ ├── player.entity.ts
│ │ │ ├── player.actions.ts
│ │ │ ├── player.controller.ts
│ │ │ ├── player.model.ts
│ │ │ ├── player.repository.ts
│ │ │ ├── player.api.ts
│ │ │ ├── actions/
│ │ │ │ ├── player-select-character.action.ts
│ │ │ │ └── player-some-action.action.ts
│ │ │ ├── events/
│ │ │ │ ├── player-custom.event.ts
│ │ │ │ └── player-some.event.ts
│ │ └── character/
│ │ └── ... character module files
│ │ └── user/
│ │ └── ... user module files
│ ├── generated-types.ts # generated file by engine.farm
│ └── tsconfig.json
├── tests/
│ └── example-test.spec.ts
├── .enginefarm.json # .gitignore
└── package.json
Helpers
Na potrzeby gry i łatwego zarządzania późniejszymi akcjami zalecamy w pierwszej kolejności utworzenie plików pomocniczych zawierające konstanty. Przykładowo:
export enum PlayerEventType {
// player
PlayerSelectCharacter,
// character
CharacterMovement,
CharacterChangeDirection,
CharacterRotation,
CharacterSettTarget,
CharacterShooting,
// bullet
SpawnObjectBullet,
}
export enum ObjectMovementDirections {
Forward,
Backward,
Left,
Right,
Up,
Down,
}
Dzięki takiemu podejściu unikniesz pomyłek na wczesnym etapie