I've started working on a Java reboot with libGDX (Gfx/Audio for Win/Linux/OSX + Android), BeanShell (Scripting), and Maven (Easy building). No restrictive TWL skins this time.
I focused on laying the groundwork with ancestor superclasses and a roadmap for descendants' interactions.
- Blueprint: Essentially factories for Models.
- Model: Runtime state of a game element: Ship, Crew, System, PlotPoint (can't call it event), etc. Passively manipulated by dispatched events. When changed, it directly notifies a callback on registered graphical Actors, special Models that aggregate info for HUD Actors (e.g., Oxygen/Evade Monitor), and probably scripts. Subclasses implement interfaces to describe what can be done to them: Damageable, Ambulator, Powerable, etc. Contains a list of arbitrary string-int pairs (Ships have 'Hull' and 'Scrap'; Conceivably, scripts could assign 'PoisonRate' to CrewModels and constantly decrement 'HP'). Models exist in a hierarchy of other Models acting as containers, ultimately within a GameModel.
- Actor: Graphical representation of a game element. Passively reacts to changes in the Model it watches. May enqueue a UI event. "Actor" is what libGDX calls it, among other things (Widgets), but I'll create a special ancestor class once I decide what non-stock things Overdrive needs them to do. I haven't entirely settled on a roadmap for them yet (eg, A StageManager with Actor factories registered for specific Model classes; A means to assign Actor positions in a layout, etc).
- Event: A bundled request for something to change. It's generated by Actors, Scripts, and the render loop (periodic TickEvents to signal the passage of game-time units). Events are put on the queue of a central EventManager and scrutinized by scripts, which may veto and or enqueue additional events in response. An event that makes it through is dispatched to its destination, for now a Model. These are things like DoorEvent, PowerEvent, AmbulationEvent, etc.
- ScreenManager: Central means to set or progress through screens, like LoadingScreen, MainMenuScreen, HangarScreen, CampaignScreen, etc. I'll probably set up tiers of EventManagers: one per-Screen, occasionally delegating events to a global one for the engine - to do stuff like set the Screen via an event.
- Screen: Has its own EventManager and multiple Stages rendered on top of each other like layers (e.g., one for the player ship, and one for the HUD).
- Stage: A 2D region of space, viewed from a 3D camera, and containing Actors to render onto the screen. It should be possible to add a second camera - offset a bit with a clipped view. So a complete enemy ship just outside the first camera's view will be partially rendered inside a rectangle (overlaying cameras' views will have a picture-in-picture effect and projectiles will travel between them normally).
- Script: I haven't established conventions for writing scripts themselves yet. Technically, they can wield the full might of Java (optionally with looser syntax) to declare custom subclasses and call methods on anything. I only confirmed the interpreter is present and that it works by running hello world. A script's source will be interpreted once to create a long-lived object that will register with the EventManager. Different scripts will be loaded depending on the Screen (LoadingScreen will ask script objects what textures need pre-loading, etc). Like the EventManager, I'll probably have tiers of ScriptManagers as well.
I'm thinking I'll give each ShipModel a CoordinateManager to decide adjacency when queried in different contexts (for Ambulators planning walk paths, teleport doors are adjacent to different squares than the ones visually nearby). ShipCoordinates will unify the vertical-wall, horizontal-wall, and square positions using 3 numbers (x,y,v/h) - converted to normal screen x,y coords as needed. Models would register their locations with the manager as containers (SquareModel) or occupants (Ambulators, Breaches, etc), for lookup, and any containers implementing Traversable could be directly inspected with certain methods (to test if currently enterable, etc).
Right now I'm restructuring the Maven dir tree to accomodate building the engine and a separate setup tool (to locate and preprocess FTL's dats), then bundle everything together in archives for distribution.
At first, I took a shortcut by inefficiently transforming images on-the-fly, directly from the dats, tiled onto canvases of power-of-two dimensions, but that got problematic when it came time to write a cache manager to go with the LoadingScreen. I discovered textures generated that way can't be trusted to stay in the video card. So I'm going back and writing a setup tool to do that properly, so textures can be (re)loaded and used as-is.
I'll start a GitHub repo when the dir tree is stable.