Skip to content

Conversation

@SlamBamActionman
Copy link
Member

Ever since I decided to implement photography into SS14 I have ended up in a crusade against how sprites are currently implemented and modified in the game. This design doc is a culmination of multiple discussions and deliberations on how to generalize sprite modifications, how to achieve reliable sprite copies and a proposal on how to tidy things up across the codebase. Multiple systems would benefit from this standardization; this design doc aims to answer how to get there.


- Any game logic system that modifies sprites is split up into a game logic system and a visualizer system (i.e. inherits `VisualizerSystem`). The game logic system *sets* `AppearanceData` for the visualizer system to work with, instead of modifying the sprites directly.
- All visualizer systems are connected to visualizer components (e.g. `ClothingSystem` have `ClothingVisualizerSystem` and `ClothingVisualizerComponent`). The visualizer system handles the visual logic, and the component on an entity indicates an entity should run the system.
- `SpriteSystem`/`SpriteComponent` may not be accessed outside of visualizer systems to prevent game logic systems modifying sprites.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anything, this should just be a convention / rule of thumb, and not actually enforced via an analyser or whatever because there's probably always going to be some exceptions. Especially when it comes to systems/components that control animated sprite layers, where you don't want to dirty/network unnecessary data every tick (e.g., something like RgbLightControllerSystem)

Comment on lines +51 to +52
2) A game logic system (`ExampleSystem` & `ExampleComponent`) performs its functions and, as a result, requires the sprite to change.
3) The game logic system sets a key-value pair in the entity's `AppearanceComponent.AppearanceData`, and ensures the entity has `ExampleVisualizerComponent`. This raises the `OnAppearanceDataChange` event.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of my gripes with this is that it will require networking redundant data, and I've generally been pushing people to using data in components instead of relying on AppearanceData unless its a server-side comp, or they want to use something like the GenericVisualizer.

I.e., if ExampleComponent is a shared/networked component, all the data required to update the sprite is already contained in that component, and copying the data to AppearanceData will just mean that anytime the component is modified it has to uneccesarily network that data twice. And currently its even worse as there are no delta states, so it always has to send all of AppearanceData.

Comment on lines +101 to +103
- Remembering sprites at point in time
- End of round sprites
- Photography
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I'm somewhat tempted to just move sprite component back to shared (with networking disabled by default) to make server-authoritative sprites & taking sprite snapshots much easier. Though that'd also have a performance impact on the server, though I have NFI if it'd be significant. It'd also be a giant refactor that'd require moving all visualizers to shared.

And while maybe somewhat overkill, sprite snapshots could also be obtained by actually serializing the whole entity & spawning a client-side dummy for rendering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants