Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет nancygold ([info]nancygold)
@ 2024-05-11 03:01:00

Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Настроение: contemplative
Музыка:Kuldahar Theme

Spell of Mastery Rewrite Progress
Previously I have split the UI and game objects across multiple tables.
Now I'm refactoring the game logic into systems.
That immediately resulted in about 1/2 of the code being thrown away.
In addition, all these

is_null_pointer(object) ? default_value : field[object]
are now handled by the table code.
And most common null pointer errors are now impossible, since the systems just won't get called on absent fields.

It was really surprising that something as simple playing a 2d animation could be so hard to do right on the first try, when considered in a general context. And it easy to mess up, like making planner depending on the currently playing animation. For example, I had actuator waiting for the animation to reach specific stages. So now I also had to redo all my animation scripts to not including any game logic. And all the online guides on animation systems recommend the hierarchical state machines cargo cult, which is a really bad idea architecturally wise, since it breeds non-uniformity further, requiring maintaining a HSM for each class of entities.

The game logic, which was previously a convoluted spaghetti mess, is now split into a conveyor tree, where each stage depends only on the previous stage:
- Player AI gives orders to entities.
- Planner pursues the order, and issues appropriate actions;
- Actuator, like attack and move from cell to cell.
Optionally it can awaken the planner on action completion;
Everything after actuator is optional and can be turned off for the server side code.
- Animator analyses the actuator's state and determines which animation to play.
Optionally it can awaken the actuator;
- Performer plays specific animation, by providing the frames to renderer.
Optionally it can awaken the animator when the animation finishes;
- Renderer, plays the frame, picked by performer.

For me the additional challenge is the discrete nature of the game, where all entities act inside the quantified time units. And ECS helped to clean up that logic. I.e. while the entity has already consumed the allocated quants, some of the animations, like idle or move, are still expected to play. basically entities walk in place (Final Fantasy Tactics style) to express that they perform movement order. Same way, poisoned units should have poison animation playing.

TODO1: integrating the physics with the actuator actions. I.e. a can a falling unit act? Like activating a parachute?
TODO2: introduce the phased methods, instead of the clunky update_systems.

Basically the below code could be organized as a set of methods like, `entity.motilize phase.each_cycle = ...`
update_systems Me =
  update_custom_systems Me

  //satellites
  for U each(add_cover){unit_}:  add_cover U
  for U each(add_shadow){unit_}: add_shadow U
  for U each(remove_sat){unit_}: remove_sat U
  for U each(place_sat){unit_}:  place_sat U

  //properties
  for U each(motilize){unit_}:      motilize U
  for U each(needs_globals){unit_}: U.add_global_acts


  //activation
  for U each(active){unit_}:    U.do_activation
  for U each(goal){unit_}:      U.break_idle
  for U each(ordered){unit_}:   U.break_idle

  //physics
  for U each(falling){unit_}:   update_falling U

  //actions
  for U each(members_){unit_}:  update_squad U
  for U each(planning){unit_}:  update_planning U
  for U each(ordered){unit_}:   take_order U
  for U each(acting){unit_}:    update_acting U
  for U each(actpost){unit_}:   update_actpost U
  for U each(pursued){unit_}:   update_pursued U
  for U each(enchng){unit_}:    update_enchng U

  for U each(sqid){unit_}:      update_sqid U
  for U each(host){unit_}:      update_hosted U

  //graphics
  for U each(animator){unit_}:   U.upd_animator
  for U each(animated){unit_}:   U.upd_animated
  for U each(anm_float){unit_}:  U.reset_visl
  for U each(made_step){unit_}:  made_step U //set by upd_animated
  //for U each(randidle){unit_}:  U.rand_anim_step

  for U each(fade_inc){unit_}:   U.update_fade
  for U each(suffers){unit_}:    upd_suffers U


(Читать комментарии)

Добавить комментарий:

Как:
Identity URL: 
имя пользователя:    
Вы должны предварительно войти в LiveJournal.com
 
E-mail для ответов: 
Вы сможете оставлять комментарии, даже если не введете e-mail.
Но вы не сможете получать уведомления об ответах на ваши комментарии!
Внимание: на указанный адрес будет выслано подтверждение.
Имя пользователя:
Пароль:
Тема:
HTML нельзя использовать в теме сообщения
Сообщение:



Обратите внимание! Этот пользователь включил опцию сохранения IP-адресов пишущих комментарии к его дневнику.