In part 1, I wrote about a difficulty endemic to just about any porting project,
the importing and trans-coding of data to different formats.
Here in part 2 I'll cover a few of the trickier engine architectural differences that exist between
the original engine for Static:IT (Selenite) and the new engine that will support it (base-code from 96Mill and Revel Immortal)
Originally designed to support editor-only development of Adventure and RPG games, Selenite
was a successor of the S3Engine (The Lost City of Malathedra); and shared many simularities
with the primary exception being that S3 was designed such that scripts and associated resources
were to be written in external tools, and the S3Engine was a pre-compiled exe run-time, that read and
executed the scripts and resources.
Selenite on the other hand, was an IDE, where game objects were added via a tree-view interface, along
with resources; and the IDE was responsible for processing and packaging these resources for optimal end-use.
The resulting resources were likewise run next to a pre-compiled SeleniteWin32.exe
There is a relatively large expanse of time between the creation of Selenite in 2009, and the creation of Engine4
(or EngineIV ...it's not really important) in 2013; E4 represents several massive shifts in the way I build engines
at least as of the time of this writing.
- It's in HTML5/JS, runs in the browser, and is 'wrapped' for platforms/services that only except exe, etc.
It's heavily designed around The Trinity Pattern which is a design pattern I developed to aid in making a game
expandable, without breaking save-games, or amassing technical-debt with each release.
- Dependency Injection and Law of Demeter are used heavily to reduce coupling
It's a series of engines, where for each new game we clone the engine code of a game most like it;
and features are selectively merged backwards if they're desired.
Each game's run-time is optimized to that game, without regard for other games. This is to avoid
having to square new features or feature modifications/removals against existing games.
It became clear early in the port, that I was going to have an issue with the difference each engine handles
a concept which I refer to as residency.
In Selenite, there is the the Game class, which has a list of Room classes, and each of these rooms had a list of Actor classes;
and when the game was loaded, that tree structure would be created and resident in memory; addressable at all times.
...not a terrible design, but one I had departed from a while ago; the primary issue is that Selenite mixes the issue of State
and Runtime ...that is, objects are in charge of their runtime representation, mechanics and non-persistent state and
they also hold their persistent (save game) state as well.
In Engine4, the there is a separate class for a game object's persistent state, as well as its runtime.
This allows an object's state to be retrieved, and passed into the construction of a newly minted runtime object.
runtime objects can be created and destroyed at will, with its separate persistent state living on.
This explicit separation of persistent state, as well as the tear-down and reconstruction of game objects
is really helpful in allowing for game changes, additions/updates; without breaking previously saved game-state.
...however! That is really not important in the context of porting Static:IT
So, the residency scheme in Engine4 (well new Static:IT's copy of it at least) needed to go, it simply wasn't worth
trying to massage the wealth of code to deal with alternate mechanisms for modifying non-resident runtime state
when I could bring the engine into alignment with the original needs.
...and thankfully, due to dependency injection and law of Demeter; the change was easy.
Instead of creating and destroying each room, and its actors as the player traversed them, I was able
to shift the code, changing mostly top-level factory functions, to create and maintain the total list of rooms
and actors at start.
...in Part:3 I'll cover issues pertaining with porting the scripting from Lua to JS