Skip to content

Commit 8526ae6

Browse files
gajopclaude
andcommitted
docs: add Lua → Rust porting plan
docs/porting/ holds the plan: per-phase file lists (commands, state, model, view in two stages, cleanup, libraries), conventions (process + code structure + quality bar + tests), and an empty review queue ready to be populated as items land. No runtime changes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 72e22e6 commit 8526ae6

10 files changed

Lines changed: 635 additions & 0 deletions

File tree

docs/porting/01-commands.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
name: Phase 1 — Commands
3+
description: Per-file status of all Lua commands being ported to Rust
4+
---
5+
6+
# Phase 1 — Commands
7+
8+
85 Lua command files: 69 at the top level of [scen_edit/command/](../../scen_edit/command/), plus three subdirs — [textures/](../../scen_edit/command/textures/) (5), [sync/](../../scen_edit/command/sync/) (5), [project/](../../scen_edit/command/project/) (6).
9+
10+
5 of those (the terrain commands) already have partial Rust counterparts on a side branch that get re-landed as part of Phase 0/1.
11+
12+
Status terms in [README.md](README.md).
13+
14+
## Infrastructure (base classes — no 1:1 port)
15+
16+
| Lua | Status | Notes |
17+
|-----|--------|-------|
18+
| [command.lua](../../scen_edit/command/command.lua) | todo | Base `Command` class + `CompoundCommand`. Counterpart is a trait in Rust. |
19+
| [command_manager.lua](../../scen_edit/command/command_manager.lua) | todo | Dispatch + undo/redo stack. Counterpart in Rust manages the registry and the bridge to Lua. |
20+
21+
## Leaf commands — port first (no model/state deps beyond trivial)
22+
23+
| Lua | Status |
24+
|-----|--------|
25+
| [add_variable_command.lua](../../scen_edit/command/add_variable_command.lua) | todo |
26+
| [remove_variable_command.lua](../../scen_edit/command/remove_variable_command.lua) | todo |
27+
| [update_variable_command.lua](../../scen_edit/command/update_variable_command.lua) | todo |
28+
| [add_team_command.lua](../../scen_edit/command/add_team_command.lua) | todo |
29+
| [remove_team_command.lua](../../scen_edit/command/remove_team_command.lua) | todo |
30+
| [update_team_command.lua](../../scen_edit/command/update_team_command.lua) | todo |
31+
| [set_ally_command.lua](../../scen_edit/command/set_ally_command.lua) | todo |
32+
| [change_player_team_command.lua](../../scen_edit/command/change_player_team_command.lua) | todo |
33+
| [set_scenario_info_command.lua](../../scen_edit/command/set_scenario_info_command.lua) | todo |
34+
| [set_global_los_command.lua](../../scen_edit/command/set_global_los_command.lua) | todo |
35+
| [set_atmosphere_command.lua](../../scen_edit/command/set_atmosphere_command.lua) | todo |
36+
| [set_sun_lighting_command.lua](../../scen_edit/command/set_sun_lighting_command.lua) | todo |
37+
| [set_sun_parameters_command.lua](../../scen_edit/command/set_sun_parameters_command.lua) | todo |
38+
| [set_water_params_command.lua](../../scen_edit/command/set_water_params_command.lua) | todo |
39+
| [set_map_rendering_params_command.lua](../../scen_edit/command/set_map_rendering_params_command.lua) | todo |
40+
| [set_heightmap_brush_command.lua](../../scen_edit/command/set_heightmap_brush_command.lua) | todo |
41+
| [set_multiple_command_mode_command.lua](../../scen_edit/command/set_multiple_command_mode_command.lua) | todo |
42+
43+
## Terrain (already partially done in side branch)
44+
45+
| Lua | Status |
46+
|-----|--------|
47+
| [abstract_terrain_modify_command.lua](../../scen_edit/command/abstract_terrain_modify_command.lua) | todo |
48+
| [terrain_level_command.lua](../../scen_edit/command/terrain_level_command.lua) | todo |
49+
| [terrain_metal_command.lua](../../scen_edit/command/terrain_metal_command.lua) | todo |
50+
| [terrain_shape_modify_command.lua](../../scen_edit/command/terrain_shape_modify_command.lua) | todo |
51+
| [terrain_smooth_command.lua](../../scen_edit/command/terrain_smooth_command.lua) | todo |
52+
53+
## Trigger / actions
54+
55+
| Lua | Status |
56+
|-----|--------|
57+
| [add_trigger_command.lua](../../scen_edit/command/add_trigger_command.lua) | todo |
58+
| [remove_trigger_command.lua](../../scen_edit/command/remove_trigger_command.lua) | todo |
59+
| [update_trigger_command.lua](../../scen_edit/command/update_trigger_command.lua) | todo |
60+
| [execute_trigger_command.lua](../../scen_edit/command/execute_trigger_command.lua) | todo |
61+
| [execute_trigger_actions_command.lua](../../scen_edit/command/execute_trigger_actions_command.lua) | todo |
62+
63+
## Object lifecycle
64+
65+
| Lua | Status |
66+
|-----|--------|
67+
| [add_object_command.lua](../../scen_edit/command/add_object_command.lua) | todo |
68+
| [remove_object_command.lua](../../scen_edit/command/remove_object_command.lua) | todo |
69+
| [set_object_command.lua](../../scen_edit/command/set_object_command.lua) | todo |
70+
| [set_object_param_command.lua](../../scen_edit/command/set_object_param_command.lua) | todo |
71+
72+
## Terrain / map
73+
74+
| Lua | Status |
75+
|-----|--------|
76+
| [terrain_change_texture_command.lua](../../scen_edit/command/terrain_change_texture_command.lua) | todo |
77+
| [terrain_grass_command.lua](../../scen_edit/command/terrain_grass_command.lua) | todo |
78+
| [resize_area_command.lua](../../scen_edit/command/resize_area_command.lua) | todo |
79+
| [compile_map_command.lua](../../scen_edit/command/compile_map_command.lua) | todo |
80+
| [load_map_command.lua](../../scen_edit/command/load_map_command.lua) | todo |
81+
| [load_grass_map_command.lua](../../scen_edit/command/load_grass_map_command.lua) | todo |
82+
| [load_metal_map_command.lua](../../scen_edit/command/load_metal_map_command.lua) | todo |
83+
| [load_model_command.lua](../../scen_edit/command/load_model_command.lua) | todo |
84+
| [load_texture_command.lua](../../scen_edit/command/load_texture_command.lua) | todo |
85+
| [load_gui_state_command.lua](../../scen_edit/command/load_gui_state_command.lua) | todo |
86+
| [cache_texture_command.lua](../../scen_edit/command/cache_texture_command.lua) | todo |
87+
| [import_diffuse_command.lua](../../scen_edit/command/import_diffuse_command.lua) | todo |
88+
| [import_heightmap_command.lua](../../scen_edit/command/import_heightmap_command.lua) | todo |
89+
| [import_shading_image_command.lua](../../scen_edit/command/import_shading_image_command.lua) | todo |
90+
91+
## Save / export / lifecycle
92+
93+
| Lua | Status |
94+
|-----|--------|
95+
| [save_command.lua](../../scen_edit/command/save_command.lua) | todo |
96+
| [save_images_command.lua](../../scen_edit/command/save_images_command.lua) | todo |
97+
| [export_map_info_command.lua](../../scen_edit/command/export_map_info_command.lua) | todo |
98+
| [export_maps_command.lua](../../scen_edit/command/export_maps_command.lua) | todo |
99+
| [export_s11n_command.lua](../../scen_edit/command/export_s11n_command.lua) | todo |
100+
| [start_command.lua](../../scen_edit/command/start_command.lua) | todo |
101+
| [stop_command.lua](../../scen_edit/command/stop_command.lua) | todo |
102+
| [sync_file_command.lua](../../scen_edit/command/sync_file_command.lua) | todo |
103+
| [reload_meta_model_command.lua](../../scen_edit/command/reload_meta_model_command.lua) | todo |
104+
105+
## Undo / control
106+
107+
| Lua | Status |
108+
|-----|--------|
109+
| [compound_command.lua](../../scen_edit/command/compound_command.lua) | todo |
110+
| [undo_command.lua](../../scen_edit/command/undo_command.lua) | todo |
111+
| [redo_command.lua](../../scen_edit/command/redo_command.lua) | todo |
112+
| [clear_undo_redo_command.lua](../../scen_edit/command/clear_undo_redo_command.lua) | todo |
113+
| [merge_command.lua](../../scen_edit/command/merge_command.lua) | todo |
114+
| [resend_command.lua](../../scen_edit/command/resend_command.lua) | todo |
115+
116+
## Widget commands (`widget_*`)
117+
118+
These run on the unsynced side; check whether each still belongs in Rust before porting.
119+
120+
| Lua | Status |
121+
|-----|--------|
122+
| [widget_command_executed.lua](../../scen_edit/command/widget_command_executed.lua) | todo |
123+
| [widget_display_text.lua](../../scen_edit/command/widget_display_text.lua) | todo |
124+
| [widget_draw_texture_command.lua](../../scen_edit/command/widget_draw_texture_command.lua) | todo |
125+
| [widget_execute_unsynced_action_command.lua](../../scen_edit/command/widget_execute_unsynced_action_command.lua) | todo |
126+
| [widget_follow_unit_command.lua](../../scen_edit/command/widget_follow_unit_command.lua) | todo |
127+
| [widget_terrain_change_texture_command.lua](../../scen_edit/command/widget_terrain_change_texture_command.lua) | todo |
128+
| [widget_unit_say_command.lua](../../scen_edit/command/widget_unit_say_command.lua) | todo |
129+
130+
## Texture export ([scen_edit/command/textures/](../../scen_edit/command/textures/))
131+
132+
| Lua | Status |
133+
|-----|--------|
134+
| [export_diffuse_command.lua](../../scen_edit/command/textures/export_diffuse_command.lua) | todo |
135+
| [export_grass_command.lua](../../scen_edit/command/textures/export_grass_command.lua) | todo |
136+
| [export_heightmap_command.lua](../../scen_edit/command/textures/export_heightmap_command.lua) | todo |
137+
| [export_metal_command.lua](../../scen_edit/command/textures/export_metal_command.lua) | todo |
138+
| [export_shading_textures_command.lua](../../scen_edit/command/textures/export_shading_textures_command.lua) | todo |
139+
140+
## Sync ([scen_edit/command/sync/](../../scen_edit/command/sync/))
141+
142+
| Lua | Status |
143+
|-----|--------|
144+
| [object_sync.lua](../../scen_edit/command/sync/object_sync.lua) | todo |
145+
| [scenario_info_sync.lua](../../scen_edit/command/sync/scenario_info_sync.lua) | todo |
146+
| [team_sync.lua](../../scen_edit/command/sync/team_sync.lua) | todo |
147+
| [trigger_sync.lua](../../scen_edit/command/sync/trigger_sync.lua) | todo |
148+
| [variable_sync.lua](../../scen_edit/command/sync/variable_sync.lua) | todo |
149+
150+
## Project subcommands ([scen_edit/command/project/](../../scen_edit/command/project/))
151+
152+
| Lua | Status |
153+
|-----|--------|
154+
| [copy_custom_project_files_command.lua](../../scen_edit/command/project/copy_custom_project_files_command.lua) | todo |
155+
| [export_project_command.lua](../../scen_edit/command/project/export_project_command.lua) | todo |
156+
| [load_project_command_widget.lua](../../scen_edit/command/project/load_project_command_widget.lua) | todo |
157+
| [reload_into_project_command.lua](../../scen_edit/command/project/reload_into_project_command.lua) | todo |
158+
| [save_project_info_command.lua](../../scen_edit/command/project/save_project_info_command.lua) | todo |
159+
| [set_project_name_path_command.lua](../../scen_edit/command/project/set_project_name_path_command.lua) | todo |

docs/porting/02-state.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: Phase 2 — State
3+
description: Per-file status of Lua state classes being ported to Rust
4+
---
5+
6+
# Phase 2 — State
7+
8+
21 Lua state files in [scen_edit/state/](../../scen_edit/state/). Editor states (brush, selection, drag, etc.). Likely a strategy pattern in Lua — confirm shape before designing the Rust counterpart.
9+
10+
Don't start until Phase 1 commands these states depend on are at least at review. State and commands are coupled (states fire commands).
11+
12+
## Files
13+
14+
| Lua | Status | Notes |
15+
|-----|--------|-------|
16+
| [abstract_state.lua](../../scen_edit/state/abstract_state.lua) | todo | Base — port first |
17+
| [state_manager.lua](../../scen_edit/state/state_manager.lua) | todo | Dispatch — port second |
18+
| [default_state.lua](../../scen_edit/state/default_state.lua) | todo | |
19+
| [abstract_heightmap_editing_state.lua](../../scen_edit/state/abstract_heightmap_editing_state.lua) | todo | |
20+
| [abstract_map_editing_state.lua](../../scen_edit/state/abstract_map_editing_state.lua) | todo | |
21+
| [add_object_state.lua](../../scen_edit/state/add_object_state.lua) | todo | |
22+
| [add_rect_state.lua](../../scen_edit/state/add_rect_state.lua) | todo | |
23+
| [brush_object_state.lua](../../scen_edit/state/brush_object_state.lua) | todo | |
24+
| [drag_horizontal_state.lua](../../scen_edit/state/drag_horizontal_state.lua) | todo | |
25+
| [drag_object_state.lua](../../scen_edit/state/drag_object_state.lua) | todo | |
26+
| [grass_editing_state.lua](../../scen_edit/state/grass_editing_state.lua) | todo | |
27+
| [metal_editing_state.lua](../../scen_edit/state/metal_editing_state.lua) | todo | |
28+
| [rectangle_select_state.lua](../../scen_edit/state/rectangle_select_state.lua) | todo | |
29+
| [resize_area_state.lua](../../scen_edit/state/resize_area_state.lua) | todo | |
30+
| [rotate_object_state.lua](../../scen_edit/state/rotate_object_state.lua) | todo | |
31+
| [select_object_state.lua](../../scen_edit/state/select_object_state.lua) | todo | |
32+
| [select_object_type_state.lua](../../scen_edit/state/select_object_type_state.lua) | todo | |
33+
| [terrain_change_dnts_state.lua](../../scen_edit/state/terrain_change_dnts_state.lua) | todo | |
34+
| [terrain_change_texture_state.lua](../../scen_edit/state/terrain_change_texture_state.lua) | todo | |
35+
| [terrain_set_state.lua](../../scen_edit/state/terrain_set_state.lua) | todo | |
36+
| [terrain_shape_modify_state.lua](../../scen_edit/state/terrain_shape_modify_state.lua) | todo | |
37+
| [terrain_smooth_state.lua](../../scen_edit/state/terrain_smooth_state.lua) | todo | |
38+
39+
## Dispatch
40+
41+
State manager picks active state. Run Lua + Rust managers in parallel during port, flipping per-state, or hold off until the full set is ready and switch wholesale — decide once we know the manager's shape.

docs/porting/03-model.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
name: Phase 3 — Model
3+
description: Per-file status of Lua model layer being ported to Rust
4+
---
5+
6+
# Phase 3 — Model
7+
8+
24 Lua files in [scen_edit/model/](../../scen_edit/model/). Project state, managers, bridges to the engine.
9+
10+
The model is what commands and states *mutate*. It's the hottest coupling in the codebase. Approach: port managers behind a Rust-side facade with the same shape Lua expects, so commands don't all need to flip at once.
11+
12+
## Managers
13+
14+
| Lua | Status | Notes |
15+
|-----|--------|-------|
16+
| [model.lua](../../scen_edit/model/model.lua) | todo | Root — port first |
17+
| [project.lua](../../scen_edit/model/project.lua) | todo | |
18+
| [scenario_info.lua](../../scen_edit/model/scenario_info.lua) | todo | |
19+
| [area_manager.lua](../../scen_edit/model/area_manager.lua) | todo | |
20+
| [assets_manager.lua](../../scen_edit/model/assets_manager.lua) | todo | |
21+
| [brush_manager.lua](../../scen_edit/model/brush_manager.lua) | todo | |
22+
| [extensions_manager.lua](../../scen_edit/model/extensions_manager.lua) | todo | |
23+
| [springmon_manager.lua](../../scen_edit/model/springmon_manager.lua) | todo | |
24+
| [team_manager.lua](../../scen_edit/model/team_manager.lua) | todo | |
25+
| [terrain_manager.lua](../../scen_edit/model/terrain_manager.lua) | todo | |
26+
| [texture_manager.lua](../../scen_edit/model/texture_manager.lua) | todo | |
27+
| [trigger_manager.lua](../../scen_edit/model/trigger_manager.lua) | todo | |
28+
| [variable_manager.lua](../../scen_edit/model/variable_manager.lua) | todo | |
29+
30+
## Data + bridges
31+
32+
| Lua | Status | Notes |
33+
|-----|--------|-------|
34+
| [heightmap.lua](../../scen_edit/model/heightmap.lua) | todo | |
35+
| [area_model.lua](../../scen_edit/model/area_model.lua) | todo | |
36+
| [active_drawing.lua](../../scen_edit/model/active_drawing.lua) | todo | |
37+
| [runtime_model.lua](../../scen_edit/model/runtime_model.lua) | todo | |
38+
| [texture_undo_stack.lua](../../scen_edit/model/texture_undo_stack.lua) | todo | |
39+
| [field_resolver.lua](../../scen_edit/model/field_resolver.lua) | todo | |
40+
| [area_bridge.lua](../../scen_edit/model/area_bridge.lua) | todo | |
41+
| [feature_bridge.lua](../../scen_edit/model/feature_bridge.lua) | todo | |
42+
| [object_bridge.lua](../../scen_edit/model/object_bridge.lua) | todo | |
43+
| [position_bridge.lua](../../scen_edit/model/position_bridge.lua) | todo | |
44+
| [unit_bridge.lua](../../scen_edit/model/unit_bridge.lua) | todo | |
45+
46+
## Subdirs
47+
48+
[scen_edit/model/object/](../../scen_edit/model/object/) and [scen_edit/model/rendering/](../../scen_edit/model/rendering/) and [scen_edit/model/runtime_model/](../../scen_edit/model/runtime_model/) hold further files — enumerate when this phase opens.

docs/porting/04-view.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
name: Phase 4 — View (Chili → RmlUi)
3+
description: Migrating UI from Chili to RmlUi
4+
---
5+
6+
# Phase 4 — View: Chili → RmlUi (Lua-side)
7+
8+
118 Lua files under [scen_edit/view/](../../scen_edit/view/). This phase only kills Chili; the view logic stays in Lua. The follow-up phase ([05-view-rust.md](05-view-rust.md)) moves that logic into Rust.
9+
10+
Splitting it in two stages keeps each step small:
11+
1. Chili → RmlUi while the logic is still Lua (easier to verify visually, no FFI to debug).
12+
2. Then Lua RmlUi handlers → Rust, one panel at a time.
13+
14+
Some RmlUi work exists in side branches and may be cherry-picked in once this phase opens.
15+
16+
## Approach
17+
18+
Per-window: build the RmlUi version next to the Chili version, switch the loader, leave the Chili file for one cycle, then delete. The app stays usable throughout.
19+
20+
## Floating windows (start here — smallest surface)
21+
22+
| Chili source | Status |
23+
|--------------|--------|
24+
| [floating/status_window.lua](../../scen_edit/view/floating/status_window.lua) | todo |
25+
| [floating/command_window.lua](../../scen_edit/view/floating/command_window.lua) | todo |
26+
| [floating/control_buttons.lua](../../scen_edit/view/floating/control_buttons.lua) | todo |
27+
| [floating/top_left_menu.lua](../../scen_edit/view/floating/top_left_menu.lua) | todo |
28+
| [floating/bottom_bar.lua](../../scen_edit/view/floating/bottom_bar.lua) | todo |
29+
| [floating/team_selector.lua](../../scen_edit/view/floating/team_selector.lua) | todo |
30+
31+
## Remaining Chili-side areas
32+
33+
Each becomes its own task block when we open this phase. High-level inventory:
34+
35+
| Area | Status |
36+
|------|--------|
37+
| [view/main_window/](../../scen_edit/view/main_window/) | todo |
38+
| [view/dialog/](../../scen_edit/view/dialog/) | todo |
39+
| [view/object/](../../scen_edit/view/object/) | todo |
40+
| [view/trigger/](../../scen_edit/view/trigger/) | todo |
41+
| [view/general/](../../scen_edit/view/general/) | todo |
42+
| [view/map/](../../scen_edit/view/map/) | todo |
43+
| [view/actions/](../../scen_edit/view/actions/) | todo |
44+
| [view/fields/](../../scen_edit/view/fields/) | todo |
45+
| Top-level (asset_view, grid_view, editor, ...) | todo |
46+
47+
Enumerate file-by-file once Phases 1–3 are far enough that the underlying data shapes are stable. Building UI on a moving model multiplies churn.
48+
49+
## Exit criteria
50+
51+
All view files RmlUi-based, Chili dependency removed, Chili-specific helpers ([scen_edit/view/ui_controls.lua](../../scen_edit/view/ui_controls.lua) etc.) deleted. View *logic* is still Lua at this point — that's Phase 5.

docs/porting/05-view-rust.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
name: Phase 5 — View logic → Rust
3+
description: Drive RmlUi from native code instead of Lua handlers
4+
---
5+
6+
# Phase 5 — View logic → Rust
7+
8+
After Phase 4: all UI is RmlUi, but the event handlers, data binding, and view-model code still live in Lua. This phase moves that logic into Rust so RmlUi is driven from native — no Lua needed.
9+
10+
Prerequisites:
11+
- Phase 4 complete (no Chili left)
12+
- Engine API exposes whatever RmlUi bindings native needs (document context, event listeners, data sources)
13+
14+
## Approach
15+
16+
Per RmlUi document, in this order:
17+
18+
1. Pick a self-contained panel (start with `status_window` — small, isolated).
19+
2. Re-implement its handlers + view-model in Rust.
20+
3. Switch the loader to register the Rust handlers instead of Lua ones.
21+
4. Delete the Lua handler file.
22+
23+
Floating windows first (smallest surface), then dialogs, then the main editor panels.
24+
25+
## Inventory
26+
27+
Filled in once Phase 4 is far enough along that we know which Lua files survive into this phase.
28+
29+
Likely starting points (in order):
30+
31+
- `status_window` — small, isolated
32+
- `command_window`
33+
- `control_buttons`
34+
- `top_left_menu`
35+
- *(others — fill in as Phase 4 progresses)*
36+
37+
## Exit criteria
38+
39+
No Lua file in `scen_edit/view/` contains business logic. Anything that remains is a thin shim or has been deleted.

0 commit comments

Comments
 (0)