rom24-quickmud-python 2.5.4__tar.gz → 2.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rom24_quickmud_python-2.7.0/CHANGELOG.md +1315 -0
- rom24_quickmud_python-2.7.0/PKG-INFO +417 -0
- rom24_quickmud_python-2.7.0/README.md +364 -0
- rom24_quickmud_python-2.7.0/data/areas/air.json +1420 -0
- rom24_quickmud_python-2.7.0/data/areas/arachnos.json +2286 -0
- rom24_quickmud_python-2.7.0/data/areas/astral.json +6075 -0
- rom24_quickmud_python-2.7.0/data/areas/canyon.json +4744 -0
- rom24_quickmud_python-2.7.0/data/areas/catacomb.json +3500 -0
- rom24_quickmud_python-2.7.0/data/areas/chapel.json +3598 -0
- rom24_quickmud_python-2.7.0/data/areas/daycare.json +1402 -0
- rom24_quickmud_python-2.7.0/data/areas/draconia.json +3583 -0
- rom24_quickmud_python-2.7.0/data/areas/dream.json +1671 -0
- rom24_quickmud_python-2.7.0/data/areas/drow.json +2349 -0
- rom24_quickmud_python-2.7.0/data/areas/dwarven.json +3009 -0
- rom24_quickmud_python-2.7.0/data/areas/dylan.json +2768 -0
- rom24_quickmud_python-2.7.0/data/areas/eastern.json +2895 -0
- rom24_quickmud_python-2.7.0/data/areas/galaxy.json +4132 -0
- rom24_quickmud_python-2.7.0/data/areas/gnome.json +4421 -0
- rom24_quickmud_python-2.7.0/data/areas/grave.json +1808 -0
- rom24_quickmud_python-2.7.0/data/areas/grove.json +1806 -0
- rom24_quickmud_python-2.7.0/data/areas/haon.json +3761 -0
- rom24_quickmud_python-2.7.0/data/areas/hitower.json +11474 -0
- rom24_quickmud_python-2.7.0/data/areas/hood.json +4145 -0
- rom24_quickmud_python-2.7.0/data/areas/immort.json +769 -0
- rom24_quickmud_python-2.7.0/data/areas/limbo.json +480 -0
- rom24_quickmud_python-2.7.0/data/areas/mahntor.json +7795 -0
- rom24_quickmud_python-2.7.0/data/areas/marsh.json +1696 -0
- rom24_quickmud_python-2.7.0/data/areas/mega1.json +2079 -0
- rom24_quickmud_python-2.7.0/data/areas/midennir.json +2027 -0
- rom24_quickmud_python-2.7.0/data/areas/midgaard.json +12771 -0
- rom24_quickmud_python-2.7.0/data/areas/mirror.json +6112 -0
- rom24_quickmud_python-2.7.0/data/areas/mobfact.json +1045 -0
- rom24_quickmud_python-2.7.0/data/areas/moria.json +5565 -0
- rom24_quickmud_python-2.7.0/data/areas/newthalos.json +14363 -0
- rom24_quickmud_python-2.7.0/data/areas/nirvana.json +2236 -0
- rom24_quickmud_python-2.7.0/data/areas/ofcol.json +284 -0
- rom24_quickmud_python-2.7.0/data/areas/ofcol2.json +7288 -0
- rom24_quickmud_python-2.7.0/data/areas/olympus.json +3575 -0
- rom24_quickmud_python-2.7.0/data/areas/plains.json +2000 -0
- rom24_quickmud_python-2.7.0/data/areas/pyramid.json +4093 -0
- rom24_quickmud_python-2.7.0/data/areas/redferne.json +804 -0
- rom24_quickmud_python-2.7.0/data/areas/school.json +3380 -0
- rom24_quickmud_python-2.7.0/data/areas/sewer.json +7500 -0
- rom24_quickmud_python-2.7.0/data/areas/shire.json +3994 -0
- rom24_quickmud_python-2.7.0/data/areas/smurf.json +1697 -0
- rom24_quickmud_python-2.7.0/data/areas/thalos.json +3828 -0
- rom24_quickmud_python-2.7.0/data/areas/tohell.json +8843 -0
- rom24_quickmud_python-2.7.0/data/areas/trollden.json +794 -0
- rom24_quickmud_python-2.7.0/data/areas/valley.json +4291 -0
- rom24_quickmud_python-2.7.0/data/areas/wyvern.json +3366 -0
- rom24_quickmud_python-2.7.0/mud/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/account/__init__.py +74 -0
- rom24_quickmud_python-2.7.0/mud/account/account_manager.py +108 -0
- rom24_quickmud_python-2.7.0/mud/account/account_service.py +1100 -0
- rom24_quickmud_python-2.7.0/mud/admin_logging/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/advancement.py +229 -0
- rom24_quickmud_python-2.7.0/mud/agent/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/ai/__init__.py +381 -0
- rom24_quickmud_python-2.7.0/mud/combat/assist.py +211 -0
- rom24_quickmud_python-2.7.0/mud/combat/engine.py +1534 -0
- rom24_quickmud_python-2.7.0/mud/commands/admin_commands.py +491 -0
- rom24_quickmud_python-2.7.0/mud/commands/advancement.py +395 -0
- rom24_quickmud_python-2.7.0/mud/commands/affects.py +182 -0
- rom24_quickmud_python-2.7.0/mud/commands/alias_cmds.py +140 -0
- rom24_quickmud_python-2.7.0/mud/commands/auto_settings.py +446 -0
- rom24_quickmud_python-2.7.0/mud/commands/build.py +3267 -0
- rom24_quickmud_python-2.7.0/mud/commands/character.py +219 -0
- rom24_quickmud_python-2.7.0/mud/commands/combat.py +947 -0
- rom24_quickmud_python-2.7.0/mud/commands/communication.py +642 -0
- rom24_quickmud_python-2.7.0/mud/commands/consumption.py +353 -0
- rom24_quickmud_python-2.7.0/mud/commands/dispatcher.py +1051 -0
- rom24_quickmud_python-2.7.0/mud/commands/doors.py +605 -0
- rom24_quickmud_python-2.7.0/mud/commands/equipment.py +599 -0
- rom24_quickmud_python-2.7.0/mud/commands/give.py +249 -0
- rom24_quickmud_python-2.7.0/mud/commands/group_commands.py +498 -0
- rom24_quickmud_python-2.7.0/mud/commands/healer.py +247 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_admin.py +320 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_commands.py +489 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_display.py +328 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_emote.py +221 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_load.py +402 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_olc.py +561 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_punish.py +262 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_search.py +1137 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_server.py +255 -0
- rom24_quickmud_python-2.7.0/mud/commands/imm_set.py +593 -0
- rom24_quickmud_python-2.7.0/mud/commands/info.py +593 -0
- rom24_quickmud_python-2.7.0/mud/commands/info_extended.py +300 -0
- rom24_quickmud_python-2.7.0/mud/commands/inspection.py +287 -0
- rom24_quickmud_python-2.7.0/mud/commands/inventory.py +885 -0
- rom24_quickmud_python-2.7.0/mud/commands/liquids.py +321 -0
- rom24_quickmud_python-2.7.0/mud/commands/magic_items.py +362 -0
- rom24_quickmud_python-2.7.0/mud/commands/misc_player.py +274 -0
- rom24_quickmud_python-2.7.0/mud/commands/movement.py +98 -0
- rom24_quickmud_python-2.7.0/mud/commands/notes.py +480 -0
- rom24_quickmud_python-2.7.0/mud/commands/obj_manipulation.py +713 -0
- rom24_quickmud_python-2.7.0/mud/commands/player_info.py +223 -0
- rom24_quickmud_python-2.7.0/mud/commands/position.py +466 -0
- rom24_quickmud_python-2.7.0/mud/commands/remaining_rom.py +564 -0
- rom24_quickmud_python-2.7.0/mud/commands/session.py +414 -0
- rom24_quickmud_python-2.7.0/mud/commands/shop.py +1058 -0
- rom24_quickmud_python-2.7.0/mud/commands/socials.py +85 -0
- rom24_quickmud_python-2.7.0/mud/commands/thief_skills.py +441 -0
- rom24_quickmud_python-2.7.0/mud/commands/typo_guards.py +62 -0
- rom24_quickmud_python-2.7.0/mud/db/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/db/migrations.py +63 -0
- rom24_quickmud_python-2.7.0/mud/db/models.py +132 -0
- rom24_quickmud_python-2.7.0/mud/db/seed.py +27 -0
- rom24_quickmud_python-2.7.0/mud/devtools/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/game_loop.py +1224 -0
- rom24_quickmud_python-2.7.0/mud/handler.py +1685 -0
- rom24_quickmud_python-2.7.0/mud/loaders/json_loader.py +818 -0
- rom24_quickmud_python-2.7.0/mud/loaders/mob_loader.py +255 -0
- rom24_quickmud_python-2.7.0/mud/magic/effects.py +782 -0
- rom24_quickmud_python-2.7.0/mud/math/stat_apps.py +294 -0
- rom24_quickmud_python-2.7.0/mud/mob_cmds.py +1391 -0
- rom24_quickmud_python-2.7.0/mud/mobprog.py +1766 -0
- rom24_quickmud_python-2.7.0/mud/models/board.py +179 -0
- rom24_quickmud_python-2.7.0/mud/models/character.py +1230 -0
- rom24_quickmud_python-2.7.0/mud/models/clans.py +85 -0
- rom24_quickmud_python-2.7.0/mud/models/constants.py +1059 -0
- rom24_quickmud_python-2.7.0/mud/models/object.py +87 -0
- rom24_quickmud_python-2.7.0/mud/models/races.py +551 -0
- rom24_quickmud_python-2.7.0/mud/models/room.py +204 -0
- rom24_quickmud_python-2.7.0/mud/models/social.py +120 -0
- rom24_quickmud_python-2.7.0/mud/music/__init__.py +264 -0
- rom24_quickmud_python-2.7.0/mud/net/ansi.py +88 -0
- rom24_quickmud_python-2.7.0/mud/net/connection.py +2055 -0
- rom24_quickmud_python-2.7.0/mud/net/session.py +173 -0
- rom24_quickmud_python-2.7.0/mud/network/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/network/websocket_server.py +73 -0
- rom24_quickmud_python-2.7.0/mud/network/websocket_stream.py +162 -0
- rom24_quickmud_python-2.7.0/mud/notes.py +348 -0
- rom24_quickmud_python-2.7.0/mud/olc/editor_state.py +79 -0
- rom24_quickmud_python-2.7.0/mud/olc/save.py +534 -0
- rom24_quickmud_python-2.7.0/mud/persistence.py +1239 -0
- rom24_quickmud_python-2.7.0/mud/rom_api.py +677 -0
- rom24_quickmud_python-2.7.0/mud/scripts/convert_are_to_json.py +235 -0
- rom24_quickmud_python-2.7.0/mud/scripts/load_test_data.py +9 -0
- rom24_quickmud_python-2.7.0/mud/security/__init__.py +1 -0
- rom24_quickmud_python-2.7.0/mud/security/bans.py +311 -0
- rom24_quickmud_python-2.7.0/mud/skills/handlers.py +7924 -0
- rom24_quickmud_python-2.7.0/mud/skills/registry.py +396 -0
- rom24_quickmud_python-2.7.0/mud/spawning/mob_spawner.py +20 -0
- rom24_quickmud_python-2.7.0/mud/spawning/reset_handler.py +841 -0
- rom24_quickmud_python-2.7.0/mud/spawning/templates.py +553 -0
- rom24_quickmud_python-2.7.0/mud/spec_funs.py +1529 -0
- rom24_quickmud_python-2.7.0/mud/utils/bit.py +122 -0
- rom24_quickmud_python-2.7.0/mud/utils/fix_sex.py +24 -0
- rom24_quickmud_python-2.7.0/mud/utils/olc_tables.py +127 -0
- rom24_quickmud_python-2.7.0/mud/utils/poses.py +187 -0
- rom24_quickmud_python-2.7.0/mud/utils/prefix_lookup.py +217 -0
- rom24_quickmud_python-2.7.0/mud/utils/prompt.py +169 -0
- rom24_quickmud_python-2.7.0/mud/utils/string_editor.py +581 -0
- rom24_quickmud_python-2.7.0/mud/wiznet.py +324 -0
- rom24_quickmud_python-2.7.0/mud/world/char_find.py +132 -0
- rom24_quickmud_python-2.7.0/mud/world/look.py +402 -0
- rom24_quickmud_python-2.7.0/mud/world/movement.py +659 -0
- rom24_quickmud_python-2.7.0/mud/world/obj_find.py +201 -0
- rom24_quickmud_python-2.7.0/mud/world/world_state.py +257 -0
- rom24_quickmud_python-2.7.0/pyproject.toml +144 -0
- rom24_quickmud_python-2.7.0/rom24_quickmud_python.egg-info/PKG-INFO +417 -0
- rom24_quickmud_python-2.7.0/rom24_quickmud_python.egg-info/SOURCES.txt +781 -0
- rom24_quickmud_python-2.7.0/tests/integration/conftest.py +105 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_act_comm_gaps.py +285 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_act_enter_gaps.py +684 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_act_wiz_command_parity.py +1587 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_advancement_con_app.py +180 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_advancement_wis_app.py +136 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_alias_command_parity.py +56 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_architectural_parity.py +167 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_auto_flags.py +521 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_ban_command_parity.py +78 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_bit_flag_string.py +69 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_bit_flag_value.py +81 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_bit_is_stat.py +63 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_boards_rom_parity.py +430 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_character_advancement.py +521 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_character_commands.py +275 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_character_creation_runtime.py +258 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_combat_dex_app.py +113 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_combat_str_app.py +210 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_communication_enhancement.py +251 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_config_commands.py +317 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_consumables.py +864 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_container_retrieval.py +652 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_db2_loader_parity.py +195 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_door_portal_commands.py +293 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_drop_command.py +311 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_equipment_system.py +1202 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_flag_command_parity.py +231 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_furniture_occupancy.py +255 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_get_room_messages.py +303 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_give_command.py +324 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_group_combat.py +678 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_healer_command_parity.py +113 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_info_display.py +339 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_interp_dispatcher.py +287 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_interp_prefix_order.py +128 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_interp_trust.py +83 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_json_loader_parity.py +723 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_lookup_parity.py +132 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_ai.py +550 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_assist.py +117 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_call.py +129 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_cast.py +113 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_damage.py +121 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_flee.py +160 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_junk.py +56 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_kill.py +105 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_oload.py +127 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_purge.py +86 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mob_cmds_transfer.py +101 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mobprog_edge_cases.py +317 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mobprog_greet_trigger.py +100 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mobprog_predicates.py +251 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mobprog_program_flow.py +122 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_mobprog_scenarios.py +445 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_money_objects.py +675 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_music_load_songs.py +85 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_music_play.py +202 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_nanny_login_parity.py +615 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_new_player_workflow.py +183 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_numbered_get_syntax.py +270 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_001_aedit_create.py +128 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_002_redit_create.py +143 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_003_redit_reset.py +127 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_004_redit_vnum_teleport.py +150 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_005_oedit_create.py +168 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_006_medit_create.py +176 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_007_aedit_show_flags.py +93 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_008_redit_show_parity.py +76 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_009_oedit_show_parity.py +136 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_010_medit_show_parity.py +168 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_011_name_messages.py +70 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_012_aedit_reset.py +33 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_013_get_area_for_vnum_order.py +75 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_act_014_area_changed_protocol.py +104 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_alist.py +96 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_builders.py +383 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_descriptor_state.py +76 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_display_resets.py +344 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_do_resets_subcommands.py +492 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_001_mob_defensive_flags.py +123 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_002_mob_form_parts_size_material.py +125 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_003_mob_mprogs.py +118 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_004_mob_shops.py +130 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_005_mob_spec_fun.py +95 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_006_object_level.py +91 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_007_object_affects.py +147 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_008_object_extra_descr.py +130 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_009_area_helps_round_trip.py +128 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_010_asave_area_dispatch.py +146 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_011_autosave_entry.py +95 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_012_npc_security_gate.py +67 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_olc_save_013_area_list_social_prepend.py +77 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_pit_timer_handling.py +295 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_player_npc_interaction.py +233 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_position_commands.py +432 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_prompt_rom_parity.py +136 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_put_pit_timer.py +499 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_put_room_messages.py +496 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_put_weight_mult.py +385 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_recall_train_commands.py +296 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_remove_command.py +226 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_room_retrieval.py +377 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_runtime_bugs_2026_04_30.py +151 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_sacrifice_command.py +214 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_scan_broadcasts.py +108 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_skills_integration.py +494 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_socials.py +558 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_spell_affects_persistence.py +719 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_steal_command.py +351 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_append.py +110 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_edit.py +70 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_first_arg.py +74 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_format_string.py +147 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_lineadd.py +83 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_linedel.py +68 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_merc_getline.py +53 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_numlines.py +61 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_proper.py +46 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_replace.py +83 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_string_add.py +323 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_string_editor_unpad.py +38 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_tables_001_affect_migration.py +139 -0
- rom24_quickmud_python-2.7.0/tests/integration/test_tables_parity.py +218 -0
- rom24_quickmud_python-2.7.0/tests/test_account_auth.py +2535 -0
- rom24_quickmud_python-2.7.0/tests/test_advancement.py +428 -0
- rom24_quickmud_python-2.7.0/tests/test_affects.py +451 -0
- rom24_quickmud_python-2.7.0/tests/test_alias_parity.py +225 -0
- rom24_quickmud_python-2.7.0/tests/test_ansi.py +28 -0
- rom24_quickmud_python-2.7.0/tests/test_area_exits.py +20 -0
- rom24_quickmud_python-2.7.0/tests/test_area_loader.py +1140 -0
- rom24_quickmud_python-2.7.0/tests/test_bans.py +63 -0
- rom24_quickmud_python-2.7.0/tests/test_boards.py +835 -0
- rom24_quickmud_python-2.7.0/tests/test_combat.py +767 -0
- rom24_quickmud_python-2.7.0/tests/test_combat_death.py +875 -0
- rom24_quickmud_python-2.7.0/tests/test_commands.py +421 -0
- rom24_quickmud_python-2.7.0/tests/test_communication.py +494 -0
- rom24_quickmud_python-2.7.0/tests/test_db_resets_rom_parity.py +1123 -0
- rom24_quickmud_python-2.7.0/tests/test_db_seed.py +25 -0
- rom24_quickmud_python-2.7.0/tests/test_encumbrance.py +407 -0
- rom24_quickmud_python-2.7.0/tests/test_enter_portal.py +21 -0
- rom24_quickmud_python-2.7.0/tests/test_fix_sex.py +44 -0
- rom24_quickmud_python-2.7.0/tests/test_game_loop.py +627 -0
- rom24_quickmud_python-2.7.0/tests/test_game_loop_order.py +61 -0
- rom24_quickmud_python-2.7.0/tests/test_game_loop_wait_daze.py +63 -0
- rom24_quickmud_python-2.7.0/tests/test_healer.py +53 -0
- rom24_quickmud_python-2.7.0/tests/test_healer_parity.py +199 -0
- rom24_quickmud_python-2.7.0/tests/test_healer_rom_parity.py +98 -0
- rom24_quickmud_python-2.7.0/tests/test_help_system.py +355 -0
- rom24_quickmud_python-2.7.0/tests/test_inventory_persistence.py +27 -0
- rom24_quickmud_python-2.7.0/tests/test_mobprog_commands.py +679 -0
- rom24_quickmud_python-2.7.0/tests/test_movement_followers.py +150 -0
- rom24_quickmud_python-2.7.0/tests/test_movement_portals.py +140 -0
- rom24_quickmud_python-2.7.0/tests/test_networking_telnet.py +373 -0
- rom24_quickmud_python-2.7.0/tests/test_olc_aedit.py +286 -0
- rom24_quickmud_python-2.7.0/tests/test_olc_medit.py +489 -0
- rom24_quickmud_python-2.7.0/tests/test_olc_oedit.py +402 -0
- rom24_quickmud_python-2.7.0/tests/test_player_auto_settings.py +568 -0
- rom24_quickmud_python-2.7.0/tests/test_player_equipment.py +680 -0
- rom24_quickmud_python-2.7.0/tests/test_player_info_commands.py +207 -0
- rom24_quickmud_python-2.7.0/tests/test_player_prompt.py +83 -0
- rom24_quickmud_python-2.7.0/tests/test_player_title_description.py +254 -0
- rom24_quickmud_python-2.7.0/tests/test_rom_api.py +203 -0
- rom24_quickmud_python-2.7.0/tests/test_scan_parity.py +193 -0
- rom24_quickmud_python-2.7.0/tests/test_shops.py +1657 -0
- rom24_quickmud_python-2.7.0/tests/test_skill_envenom_rom_parity.py +350 -0
- rom24_quickmud_python-2.7.0/tests/test_skills.py +960 -0
- rom24_quickmud_python-2.7.0/tests/test_spec_funs.py +1501 -0
- rom24_quickmud_python-2.7.0/tests/test_spell_creation_rom_parity.py +482 -0
- rom24_quickmud_python-2.7.0/tests/test_telnet_server.py +676 -0
- rom24_quickmud_python-2.7.0/tests/test_thief_skills_dispatcher_parity.py +89 -0
- rom24_quickmud_python-2.7.0/tests/test_websocket_server.py +58 -0
- rom24_quickmud_python-2.7.0/tests/test_world.py +47 -0
- rom24_quickmud_python-2.5.4/CHANGELOG.md +0 -359
- rom24_quickmud_python-2.5.4/PKG-INFO +0 -339
- rom24_quickmud_python-2.5.4/README.md +0 -286
- rom24_quickmud_python-2.5.4/data/areas/air.json +0 -1418
- rom24_quickmud_python-2.5.4/data/areas/arachnos.json +0 -2278
- rom24_quickmud_python-2.5.4/data/areas/astral.json +0 -6023
- rom24_quickmud_python-2.5.4/data/areas/canyon.json +0 -4682
- rom24_quickmud_python-2.5.4/data/areas/catacomb.json +0 -3468
- rom24_quickmud_python-2.5.4/data/areas/chapel.json +0 -3550
- rom24_quickmud_python-2.5.4/data/areas/daycare.json +0 -1386
- rom24_quickmud_python-2.5.4/data/areas/draconia.json +0 -3501
- rom24_quickmud_python-2.5.4/data/areas/dream.json +0 -1663
- rom24_quickmud_python-2.5.4/data/areas/drow.json +0 -2319
- rom24_quickmud_python-2.5.4/data/areas/dwarven.json +0 -2975
- rom24_quickmud_python-2.5.4/data/areas/eastern.json +0 -2831
- rom24_quickmud_python-2.5.4/data/areas/galaxy.json +0 -4078
- rom24_quickmud_python-2.5.4/data/areas/gnome.json +0 -4373
- rom24_quickmud_python-2.5.4/data/areas/grove.json +0 -1778
- rom24_quickmud_python-2.5.4/data/areas/haon.json +0 -3719
- rom24_quickmud_python-2.5.4/data/areas/hitower.json +0 -11284
- rom24_quickmud_python-2.5.4/data/areas/hood.json +0 -4107
- rom24_quickmud_python-2.5.4/data/areas/immort.json +0 -769
- rom24_quickmud_python-2.5.4/data/areas/limbo.json +0 -442
- rom24_quickmud_python-2.5.4/data/areas/mahntor.json +0 -7607
- rom24_quickmud_python-2.5.4/data/areas/marsh.json +0 -1684
- rom24_quickmud_python-2.5.4/data/areas/mega1.json +0 -2045
- rom24_quickmud_python-2.5.4/data/areas/midennir.json +0 -2015
- rom24_quickmud_python-2.5.4/data/areas/midgaard.json +0 -12451
- rom24_quickmud_python-2.5.4/data/areas/mirror.json +0 -6048
- rom24_quickmud_python-2.5.4/data/areas/mobfact.json +0 -1045
- rom24_quickmud_python-2.5.4/data/areas/moria.json +0 -5507
- rom24_quickmud_python-2.5.4/data/areas/newthalos.json +0 -14163
- rom24_quickmud_python-2.5.4/data/areas/nirvana.json +0 -2232
- rom24_quickmud_python-2.5.4/data/areas/ofcol2.json +0 -7148
- rom24_quickmud_python-2.5.4/data/areas/olympus.json +0 -3519
- rom24_quickmud_python-2.5.4/data/areas/plains.json +0 -1978
- rom24_quickmud_python-2.5.4/data/areas/pyramid.json +0 -4037
- rom24_quickmud_python-2.5.4/data/areas/redferne.json +0 -798
- rom24_quickmud_python-2.5.4/data/areas/school.json +0 -3334
- rom24_quickmud_python-2.5.4/data/areas/sewer.json +0 -7434
- rom24_quickmud_python-2.5.4/data/areas/shire.json +0 -3958
- rom24_quickmud_python-2.5.4/data/areas/smurf.json +0 -1677
- rom24_quickmud_python-2.5.4/data/areas/thalos.json +0 -3750
- rom24_quickmud_python-2.5.4/data/areas/tohell.json +0 -8743
- rom24_quickmud_python-2.5.4/data/areas/trollden.json +0 -782
- rom24_quickmud_python-2.5.4/data/areas/valley.json +0 -4239
- rom24_quickmud_python-2.5.4/data/areas/wyvern.json +0 -3324
- rom24_quickmud_python-2.5.4/data/areas_backup/ofcol.json +0 -205
- rom24_quickmud_python-2.5.4/mud/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/account/__init__.py +0 -60
- rom24_quickmud_python-2.5.4/mud/account/account_manager.py +0 -135
- rom24_quickmud_python-2.5.4/mud/account/account_service.py +0 -978
- rom24_quickmud_python-2.5.4/mud/admin_logging/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/advancement.py +0 -203
- rom24_quickmud_python-2.5.4/mud/agent/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/ai/__init__.py +0 -380
- rom24_quickmud_python-2.5.4/mud/combat/assist.py +0 -205
- rom24_quickmud_python-2.5.4/mud/combat/engine.py +0 -1520
- rom24_quickmud_python-2.5.4/mud/commands/admin_commands.py +0 -499
- rom24_quickmud_python-2.5.4/mud/commands/advancement.py +0 -224
- rom24_quickmud_python-2.5.4/mud/commands/affects.py +0 -149
- rom24_quickmud_python-2.5.4/mud/commands/alias_cmds.py +0 -64
- rom24_quickmud_python-2.5.4/mud/commands/auto_settings.py +0 -321
- rom24_quickmud_python-2.5.4/mud/commands/build.py +0 -2493
- rom24_quickmud_python-2.5.4/mud/commands/character.py +0 -207
- rom24_quickmud_python-2.5.4/mud/commands/combat.py +0 -947
- rom24_quickmud_python-2.5.4/mud/commands/communication.py +0 -604
- rom24_quickmud_python-2.5.4/mud/commands/consumption.py +0 -257
- rom24_quickmud_python-2.5.4/mud/commands/dispatcher.py +0 -854
- rom24_quickmud_python-2.5.4/mud/commands/doors.py +0 -508
- rom24_quickmud_python-2.5.4/mud/commands/equipment.py +0 -483
- rom24_quickmud_python-2.5.4/mud/commands/give.py +0 -200
- rom24_quickmud_python-2.5.4/mud/commands/group_commands.py +0 -393
- rom24_quickmud_python-2.5.4/mud/commands/healer.py +0 -78
- rom24_quickmud_python-2.5.4/mud/commands/imm_admin.py +0 -280
- rom24_quickmud_python-2.5.4/mud/commands/imm_commands.py +0 -463
- rom24_quickmud_python-2.5.4/mud/commands/imm_display.py +0 -281
- rom24_quickmud_python-2.5.4/mud/commands/imm_emote.py +0 -156
- rom24_quickmud_python-2.5.4/mud/commands/imm_load.py +0 -382
- rom24_quickmud_python-2.5.4/mud/commands/imm_olc.py +0 -254
- rom24_quickmud_python-2.5.4/mud/commands/imm_punish.py +0 -259
- rom24_quickmud_python-2.5.4/mud/commands/imm_search.py +0 -593
- rom24_quickmud_python-2.5.4/mud/commands/imm_server.py +0 -239
- rom24_quickmud_python-2.5.4/mud/commands/imm_set.py +0 -500
- rom24_quickmud_python-2.5.4/mud/commands/info.py +0 -591
- rom24_quickmud_python-2.5.4/mud/commands/info_extended.py +0 -375
- rom24_quickmud_python-2.5.4/mud/commands/inspection.py +0 -279
- rom24_quickmud_python-2.5.4/mud/commands/inventory.py +0 -358
- rom24_quickmud_python-2.5.4/mud/commands/liquids.py +0 -246
- rom24_quickmud_python-2.5.4/mud/commands/magic_items.py +0 -450
- rom24_quickmud_python-2.5.4/mud/commands/misc_player.py +0 -274
- rom24_quickmud_python-2.5.4/mud/commands/movement.py +0 -87
- rom24_quickmud_python-2.5.4/mud/commands/notes.py +0 -469
- rom24_quickmud_python-2.5.4/mud/commands/obj_manipulation.py +0 -555
- rom24_quickmud_python-2.5.4/mud/commands/player_info.py +0 -183
- rom24_quickmud_python-2.5.4/mud/commands/position.py +0 -85
- rom24_quickmud_python-2.5.4/mud/commands/remaining_rom.py +0 -571
- rom24_quickmud_python-2.5.4/mud/commands/session.py +0 -413
- rom24_quickmud_python-2.5.4/mud/commands/shop.py +0 -959
- rom24_quickmud_python-2.5.4/mud/commands/socials.py +0 -34
- rom24_quickmud_python-2.5.4/mud/commands/thief_skills.py +0 -351
- rom24_quickmud_python-2.5.4/mud/commands/typo_guards.py +0 -86
- rom24_quickmud_python-2.5.4/mud/db/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/db/migrations.py +0 -51
- rom24_quickmud_python-2.5.4/mud/db/models.py +0 -142
- rom24_quickmud_python-2.5.4/mud/db/seed.py +0 -28
- rom24_quickmud_python-2.5.4/mud/devtools/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/game_loop.py +0 -1215
- rom24_quickmud_python-2.5.4/mud/handler.py +0 -1424
- rom24_quickmud_python-2.5.4/mud/loaders/json_loader.py +0 -540
- rom24_quickmud_python-2.5.4/mud/loaders/mob_loader.py +0 -187
- rom24_quickmud_python-2.5.4/mud/magic/effects.py +0 -775
- rom24_quickmud_python-2.5.4/mud/mob_cmds.py +0 -1145
- rom24_quickmud_python-2.5.4/mud/mobprog.py +0 -1685
- rom24_quickmud_python-2.5.4/mud/models/board.py +0 -156
- rom24_quickmud_python-2.5.4/mud/models/character.py +0 -1226
- rom24_quickmud_python-2.5.4/mud/models/clans.py +0 -83
- rom24_quickmud_python-2.5.4/mud/models/constants.py +0 -1005
- rom24_quickmud_python-2.5.4/mud/models/object.py +0 -59
- rom24_quickmud_python-2.5.4/mud/models/races.py +0 -534
- rom24_quickmud_python-2.5.4/mud/models/room.py +0 -191
- rom24_quickmud_python-2.5.4/mud/models/social.py +0 -99
- rom24_quickmud_python-2.5.4/mud/music/__init__.py +0 -161
- rom24_quickmud_python-2.5.4/mud/net/ansi.py +0 -42
- rom24_quickmud_python-2.5.4/mud/net/connection.py +0 -1873
- rom24_quickmud_python-2.5.4/mud/net/session.py +0 -165
- rom24_quickmud_python-2.5.4/mud/network/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/network/websocket_server.py +0 -111
- rom24_quickmud_python-2.5.4/mud/notes.py +0 -97
- rom24_quickmud_python-2.5.4/mud/olc/save.py +0 -293
- rom24_quickmud_python-2.5.4/mud/persistence.py +0 -1147
- rom24_quickmud_python-2.5.4/mud/rom_api.py +0 -677
- rom24_quickmud_python-2.5.4/mud/scripts/convert_are_to_json.py +0 -218
- rom24_quickmud_python-2.5.4/mud/scripts/load_test_data.py +0 -16
- rom24_quickmud_python-2.5.4/mud/security/__init__.py +0 -0
- rom24_quickmud_python-2.5.4/mud/security/bans.py +0 -309
- rom24_quickmud_python-2.5.4/mud/skills/handlers.py +0 -7884
- rom24_quickmud_python-2.5.4/mud/skills/registry.py +0 -381
- rom24_quickmud_python-2.5.4/mud/spawning/mob_spawner.py +0 -13
- rom24_quickmud_python-2.5.4/mud/spawning/reset_handler.py +0 -842
- rom24_quickmud_python-2.5.4/mud/spawning/templates.py +0 -532
- rom24_quickmud_python-2.5.4/mud/spec_funs.py +0 -1451
- rom24_quickmud_python-2.5.4/mud/wiznet.py +0 -268
- rom24_quickmud_python-2.5.4/mud/world/char_find.py +0 -132
- rom24_quickmud_python-2.5.4/mud/world/look.py +0 -388
- rom24_quickmud_python-2.5.4/mud/world/movement.py +0 -571
- rom24_quickmud_python-2.5.4/mud/world/obj_find.py +0 -201
- rom24_quickmud_python-2.5.4/mud/world/world_state.py +0 -249
- rom24_quickmud_python-2.5.4/pyproject.toml +0 -144
- rom24_quickmud_python-2.5.4/rom24_quickmud_python.egg-info/PKG-INFO +0 -339
- rom24_quickmud_python-2.5.4/rom24_quickmud_python.egg-info/SOURCES.txt +0 -662
- rom24_quickmud_python-2.5.4/tests/integration/conftest.py +0 -84
- rom24_quickmud_python-2.5.4/tests/integration/test_architectural_parity.py +0 -162
- rom24_quickmud_python-2.5.4/tests/integration/test_auto_flags.py +0 -487
- rom24_quickmud_python-2.5.4/tests/integration/test_character_advancement.py +0 -475
- rom24_quickmud_python-2.5.4/tests/integration/test_character_commands.py +0 -276
- rom24_quickmud_python-2.5.4/tests/integration/test_character_creation_runtime.py +0 -258
- rom24_quickmud_python-2.5.4/tests/integration/test_communication_enhancement.py +0 -243
- rom24_quickmud_python-2.5.4/tests/integration/test_config_commands.py +0 -315
- rom24_quickmud_python-2.5.4/tests/integration/test_equipment_system.py +0 -657
- rom24_quickmud_python-2.5.4/tests/integration/test_group_combat.py +0 -676
- rom24_quickmud_python-2.5.4/tests/integration/test_info_display.py +0 -328
- rom24_quickmud_python-2.5.4/tests/integration/test_mob_ai.py +0 -545
- rom24_quickmud_python-2.5.4/tests/integration/test_mobprog_scenarios.py +0 -445
- rom24_quickmud_python-2.5.4/tests/integration/test_money_objects.py +0 -415
- rom24_quickmud_python-2.5.4/tests/integration/test_new_player_workflow.py +0 -183
- rom24_quickmud_python-2.5.4/tests/integration/test_olc_builders.py +0 -366
- rom24_quickmud_python-2.5.4/tests/integration/test_player_npc_interaction.py +0 -234
- rom24_quickmud_python-2.5.4/tests/integration/test_skills_integration.py +0 -449
- rom24_quickmud_python-2.5.4/tests/integration/test_socials.py +0 -262
- rom24_quickmud_python-2.5.4/tests/integration/test_spell_affects_persistence.py +0 -717
- rom24_quickmud_python-2.5.4/tests/test_account_auth.py +0 -2605
- rom24_quickmud_python-2.5.4/tests/test_advancement.py +0 -397
- rom24_quickmud_python-2.5.4/tests/test_affects.py +0 -448
- rom24_quickmud_python-2.5.4/tests/test_alias_parity.py +0 -227
- rom24_quickmud_python-2.5.4/tests/test_ansi.py +0 -5
- rom24_quickmud_python-2.5.4/tests/test_area_exits.py +0 -22
- rom24_quickmud_python-2.5.4/tests/test_area_loader.py +0 -1140
- rom24_quickmud_python-2.5.4/tests/test_bans.py +0 -62
- rom24_quickmud_python-2.5.4/tests/test_boards.py +0 -813
- rom24_quickmud_python-2.5.4/tests/test_combat.py +0 -762
- rom24_quickmud_python-2.5.4/tests/test_combat_death.py +0 -874
- rom24_quickmud_python-2.5.4/tests/test_commands.py +0 -412
- rom24_quickmud_python-2.5.4/tests/test_communication.py +0 -489
- rom24_quickmud_python-2.5.4/tests/test_db_resets_rom_parity.py +0 -1118
- rom24_quickmud_python-2.5.4/tests/test_db_seed.py +0 -26
- rom24_quickmud_python-2.5.4/tests/test_encumbrance.py +0 -406
- rom24_quickmud_python-2.5.4/tests/test_enter_portal.py +0 -20
- rom24_quickmud_python-2.5.4/tests/test_game_loop.py +0 -596
- rom24_quickmud_python-2.5.4/tests/test_game_loop_order.py +0 -31
- rom24_quickmud_python-2.5.4/tests/test_game_loop_wait_daze.py +0 -33
- rom24_quickmud_python-2.5.4/tests/test_healer.py +0 -53
- rom24_quickmud_python-2.5.4/tests/test_healer_parity.py +0 -197
- rom24_quickmud_python-2.5.4/tests/test_healer_rom_parity.py +0 -100
- rom24_quickmud_python-2.5.4/tests/test_help_system.py +0 -353
- rom24_quickmud_python-2.5.4/tests/test_inventory_persistence.py +0 -33
- rom24_quickmud_python-2.5.4/tests/test_mobprog_commands.py +0 -677
- rom24_quickmud_python-2.5.4/tests/test_movement_followers.py +0 -132
- rom24_quickmud_python-2.5.4/tests/test_movement_portals.py +0 -139
- rom24_quickmud_python-2.5.4/tests/test_networking_telnet.py +0 -280
- rom24_quickmud_python-2.5.4/tests/test_olc_aedit.py +0 -286
- rom24_quickmud_python-2.5.4/tests/test_olc_medit.py +0 -490
- rom24_quickmud_python-2.5.4/tests/test_olc_oedit.py +0 -402
- rom24_quickmud_python-2.5.4/tests/test_player_auto_settings.py +0 -566
- rom24_quickmud_python-2.5.4/tests/test_player_equipment.py +0 -680
- rom24_quickmud_python-2.5.4/tests/test_player_info_commands.py +0 -204
- rom24_quickmud_python-2.5.4/tests/test_player_prompt.py +0 -83
- rom24_quickmud_python-2.5.4/tests/test_player_title_description.py +0 -155
- rom24_quickmud_python-2.5.4/tests/test_rom_api.py +0 -198
- rom24_quickmud_python-2.5.4/tests/test_scan_parity.py +0 -187
- rom24_quickmud_python-2.5.4/tests/test_shops.py +0 -1377
- rom24_quickmud_python-2.5.4/tests/test_skill_envenom_rom_parity.py +0 -257
- rom24_quickmud_python-2.5.4/tests/test_skills.py +0 -941
- rom24_quickmud_python-2.5.4/tests/test_spec_funs.py +0 -1494
- rom24_quickmud_python-2.5.4/tests/test_spell_creation_rom_parity.py +0 -481
- rom24_quickmud_python-2.5.4/tests/test_telnet_server.py +0 -668
- rom24_quickmud_python-2.5.4/tests/test_world.py +0 -45
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/LICENSE +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/MANIFEST.in +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/air.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/arachnos.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/area.lst +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/astral.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/canyon.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/catacomb.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/chapel.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/daycare.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/draconia.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/dream.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/drow.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/dwarven.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/dylan.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/eastern.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/galaxy.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/gnome.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/grave.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/group.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/grove.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/haon.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/help.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/hitower.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/hood.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/immort.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/limbo.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/mahntor.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/marsh.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/mega1.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/midennir.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/midgaard.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/mirror.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/mobfact.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/moria.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/newthalos.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/nirvana.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/ofcol.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/ofcol2.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/olympus.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/plains.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/proto.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/pyramid.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/quifael.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/redferne.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/rom.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/school.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/sewer.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/shire.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/smurf.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/social.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/thalos.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/tohell.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/trollden.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/valley.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/area/wyvern.are +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/area.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/area_0.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/group.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/help.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/quifael.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/rom.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas/social.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/arachnos.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/area.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/area_0.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/astral_plane.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/catacombs.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/chapel.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/day_care.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/dragon_tower.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/drow_city.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/dwarven_kingdom.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/dylan's_area.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/elemental_canyon.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/galaxy.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/gangland.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/gnome_village.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/graveyard.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/group.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/haon_dor.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/help.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/high_tower.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/holy_grove.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/in_the_air.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/limbo.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/machine_dreams.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/mahn-tor.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/marsh.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/mega_city_one.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/miden'nir.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/midgaard.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/mob_factory.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/moria.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/mud_school.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/new_ofcol.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/new_thalos.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/nirvana.json +0 -0
- {rom24_quickmud_python-2.5.4/data/areas → rom24_quickmud_python-2.7.0/data/areas_backup}/ofcol.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/old_thalos.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/olympus.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/plains.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/pyramid.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/quifael's.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/redferne's.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/rom.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/sands_of_sorrow.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/sewers.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/shire.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/smurfville.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/social.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/thalos.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/tohell.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/troll_den.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/valhalla.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/valley_of_the_elves.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/areas_backup/wyvern's_tower.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/help.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/attacker.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/eddol.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/hero.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/sleeper.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/players/trouble.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/shops.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/skills.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/socials.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/data/time.json +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/MPDocs/examples.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/MPDocs/hacker.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/MPDocs/mobprog.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/MPDocs/new_readme.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/QuickMUD.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/Rom2.4.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/act.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/area.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/c_module_inventory.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/c_python_cross_reference.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/c_to_python_file_coverage.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/class.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/command.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/contrib.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/drool.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/hacker.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/license.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/license.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/memory.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/new.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/pfile.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/port.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/pr_queue.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/python_architecture.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/python_module_inventory.md +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/security.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/sites.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/skill.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/sky.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/trad.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/vnum.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/doc/~$Rom2.4.doc +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/__main__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/admin_logging/admin.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/admin_logging/agent_trace.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/affects/engine.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/affects/saves.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/agent/agent_protocol.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/agent/character_agent.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/ai/aggressive.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/characters/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/characters/conditions.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/characters/follow.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/combat/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/combat/death.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/combat/kill_table.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/combat/messages.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/combat/safety.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/channels.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/compare.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/consider.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/decorators.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/feedback.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/help.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/imc.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/misc_info.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/mobprog_tools.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/murder.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/commands/player_config.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/config.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/db/init.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/db/migrate_from_files.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/db/session.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/devtools/agent_demo.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/entrypoint.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/game_tick_scheduler.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/groups/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/groups/xp.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/imc/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/imc/commands.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/imc/network.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/imc/protocol.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/area_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/base_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/help_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/json_area_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/mobprog_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/obj_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/reset_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/room_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/shop_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/social_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/loaders/specials_loader.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/logging.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/magic/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/math/c_compat.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/area.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/area_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/board_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/character_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/classes.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/help.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/help_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/json_io.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/mob.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/note.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/note_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/obj.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/object_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/player_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/room_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/shop.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/shop_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/skill.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/skill_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/models/social_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/net/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/net/protocol.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/net/ssh_server.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/net/telnet_server.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/network/websocket_session.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/olc/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/registry.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/scripts/convert_help_are_to_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/scripts/convert_player_to_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/scripts/convert_shops_to_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/scripts/convert_skills_to_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/scripts/convert_social_are_to_json.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/security/hash_utils.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/server.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/skills/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/skills/groups.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/skills/metadata.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/skills/say_spell.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/spawning/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/spawning/obj_spawner.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/time.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/utils/act.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/utils/rng_mm.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/utils/text.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/world/__init__.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/world/linking.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/mud/world/vision.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/rom24_quickmud_python.egg-info/dependency_links.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/rom24_quickmud_python.egg-info/entry_points.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/rom24_quickmud_python.egg-info/requires.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/rom24_quickmud_python.egg-info/top_level.txt +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/setup.cfg +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/setup.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/conftest.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/helpers.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/helpers_player.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_admin_commands.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_auto_sequences.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_channels.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_compare_critical_gaps.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_death_and_corpses.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_affects.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_consider_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_equipment.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_examine_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_exits_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_help_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_inventory.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_password_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_practice_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_time_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_weather_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_where_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_who_command.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_do_worth.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_environmental_effects.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_equipment_ac_calculations.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_invisibility_combat.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_pet_persistence.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_pilot_integration.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_player_config.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_room_light_tracking.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_room_safety_features.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_save_load_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_skills_integration_combat_specials.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_spell_casting.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/integration/test_weather_time.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_act_comm_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_act_enter_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_act_info_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_act_obj_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_act_wiz_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_agent_interface.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_are_conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_area_counts.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_area_specials.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_builder_hedit.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_builder_stat_commands.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_building.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_char_update_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_assist.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_damage_types.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_defenses_prob.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_messages.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_position_damage.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_skills.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_state.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_surrender.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_thac0.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_combat_thac0_engine.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_command_abbrev.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_command_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_connection_motd.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_convert_are_to_json_cli.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_critical_function_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_damage_reduction.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_damage_reduction_integration.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_defense_flags.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_fighting_state.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_golden_reference.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_handler_affects_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_hash_utils.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_help_conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_imc.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_json_io.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_json_model_instantiation.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_json_room_fields.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_load_midgaard.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_logging_admin.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_logging_rotation.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_mob_act_flags.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_mob_damage_modifiers.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_mobprog.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_mobprog_helpers.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_mobprog_triggers.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_charm.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_costs.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_doors.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_mobprog.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_npc.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_privacy.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_movement_visibility.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_music.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_nanny_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_obj_update_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_olc_save.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_passive_skills_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_persistence.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_affect_flags.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_combat_attributes.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_conditions.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_creation.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_flags.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_mechanics.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_resistance_flags.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_save_format.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_skills_spells.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_stats.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_player_wimpy.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_practice.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_reset_levels.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_resets.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_rng_and_ccompat.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_rng_dice.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_runtime_models.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_saves_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_say_spell.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_schema_validation.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_scripted_session.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_shop_conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_combat_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_haggle_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_hide_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_peek_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_pick_lock_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_recall_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_registry.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skill_steal_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_buffs.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_combat.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_conjuration.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_damage.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_debuffs.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_detection.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_healing.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_identify.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_learned.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_mass.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_misc.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_skills_transport.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_social_conversion.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_social_placeholders.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spawning.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spec_fun_behaviors.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spec_funs_extra.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_specials_loader_ext.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_area_effects_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_breath_weapons_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_buff_debuff_additional_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_buff_debuff_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_cancellation_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_charm_control_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_critical_gameplay_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_damage_additional_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_detection_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_enchantment_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_farsight_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_final_nine_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_harm_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_healing_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_heat_metal_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_high_priority_missing_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_information_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_mass_healing_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_priority_high_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_shocking_grasp_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spell_travel_portal_rom_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spells_basic.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_spells_damage.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_state_transitions.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_time_daynight.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_time_persistence.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_utility_spells_parity.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_weapon_damage.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_weapon_special_attacks.py +0 -0
- {rom24_quickmud_python-2.5.4 → rom24_quickmud_python-2.7.0}/tests/test_wiznet.py +0 -0
|
@@ -0,0 +1,1315 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.7.0] — ROM Character-First Login
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Login model replaced with ROM-faithful character-first auth** — the
|
|
15
|
+
`PlayerAccount` ORM table and account-layer have been removed entirely.
|
|
16
|
+
Characters now authenticate directly (mirroring ROM `nanny.c`/`save.c`):
|
|
17
|
+
the server prompts `Name:`, branches to `Password:` for returning chars or
|
|
18
|
+
`Did I get that right, <Name> (Y/N)?` → `New password:` → `Confirm
|
|
19
|
+
password:` for new ones. The `PlayerAccount` class is gone; `password_hash`
|
|
20
|
+
now lives on the `Character` row.
|
|
21
|
+
- **`_select_character` simplified** — no character-selection menu; the login
|
|
22
|
+
name *is* the character name, matching ROM's single-character-per-login model.
|
|
23
|
+
- **`login_with_host` / `login_character`** updated to query `Character` directly;
|
|
24
|
+
`create_account` / `list_characters` / `release_account` kept as thin shims
|
|
25
|
+
for call-site compatibility.
|
|
26
|
+
- **Reconnect flow** — duplicate-session detection and reconnect prompt now
|
|
27
|
+
occur at the `Name:` stage (before password), matching ROM nanny behaviour.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **`negotiate_ansi_prompt` test helper** — was waiting for `b"Account: "` after
|
|
32
|
+
the ANSI negotiation; updated to `b"Name: "` to match the new login prompt.
|
|
33
|
+
- **`test_select_character_allows_permit_from_permit_host`** — monkeypatched
|
|
34
|
+
`load_character` now uses single-arg signature; `account` arg updated to be
|
|
35
|
+
the character row directly (ROM model).
|
|
36
|
+
- **`test_websocket_boots_loaded_world_and_uses_account_login_flow`** — rewritten
|
|
37
|
+
for ROM flow (`Name:` → confirm → `New password:` → `Confirm password:`).
|
|
38
|
+
- **`test_telnet_server_handles_multiple_connections`** and
|
|
39
|
+
**`test_telnet_break_connect_prompts_and_reconnects`** — updated to ROM login
|
|
40
|
+
flow (no `Character:` prompt step).
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **Combat message delivery** — combat messages (damage, parry, dodge, position
|
|
45
|
+
changes, weapon specials) now reach connected players immediately via
|
|
46
|
+
fire-and-forget asyncio tasks, matching ROM C's `write_to_buffer()` real-time
|
|
47
|
+
delivery. Previously messages were queued in `char.messages` and only drained
|
|
48
|
+
when the player typed a command, causing combat to appear frozen.
|
|
49
|
+
See `docs/divergences/MESSAGE_DELIVERY.md` for the design rationale.
|
|
50
|
+
|
|
51
|
+
### Changed (v2.6.108)
|
|
52
|
+
|
|
53
|
+
- **JSON_LOADER_C_AUDIT.md** — all 18 gaps now closed (remaining 6 in this batch).
|
|
54
|
+
- JSON loader applies per-type value coercion (`_parse_item_values`) at load time, mirroring ROM `src/db2.c:429-478` and the `.are` loader path.
|
|
55
|
+
- `attack_lookup` now handles numeric-string inputs (in-range passes through, out-of-range falls to name prefix-match), consistent with `_skill_lookup`/`_liq_lookup`/`_weapon_type_lookup`.
|
|
56
|
+
|
|
57
|
+
### Fixed (json_loader.py parity closures — JSONLD-001,003,015,016,017,018)
|
|
58
|
+
|
|
59
|
+
- **JSONLD-001** — Object keyword list populated from JSON `keywords` key (with `name` fallback) so `is_name()` matching works on JSON-loaded objects. Converter (`convert_are_to_json.py`) now emits `keywords` separately from display `name`. All 44 area JSONs regenerated.
|
|
60
|
+
- **JSONLD-003** — Object `level` field emitted by converter (`convert_are_to_json.py:object_to_dict`) and read by JSON loader. All area JSONs regenerated with `level` for every object.
|
|
61
|
+
- **JSONLD-015** — JSON loader now calls `_parse_item_values` (from `obj_loader`) to apply per-type value coercion at load time. `attack_lookup` updated to handle pre-resolved integer values from JSON.
|
|
62
|
+
- **JSONLD-016** — Object `short_descr` lowercased-first and `description` uppercased-first at load time, mirroring ROM `src/db2.c:869-870`.
|
|
63
|
+
- **JSONLD-017** — Room `light` verified at dataclass default 0 (ROM `src/db.c:1164`). Explicit init deemed redundant — closed-by-design.
|
|
64
|
+
- **JSONLD-018** — JSON-only `ROOM_NO_MOB` auto-add on no-exit rooms removed. ROM does not do this; rooms now behave identically to the `.are` path.
|
|
65
|
+
|
|
66
|
+
### Changed (v2.6.107)
|
|
67
|
+
|
|
68
|
+
- Includes previously uncommitted JSONLD-012, OLC, and build changes from earlier session.
|
|
69
|
+
|
|
70
|
+
### Fixed (act_wiz.c stat family parity closures — WIZ-039..044)
|
|
71
|
+
|
|
72
|
+
- **WIZ-039** — `do_mstat` practices now uses caller's NPC status (`char.is_npc`) instead of victim's, matching ROM `IS_NPC(ch) ? 0 : victim->practice`.
|
|
73
|
+
- **WIZ-040** — `do_mstat` Hit/Dam now use `get_hitroll(victim)` / `get_damroll(victim)` (including STR-app bonuses) per ROM `GET_HITROLL` / `GET_DAMROLL`.
|
|
74
|
+
- **WIZ-041** — `do_mstat` Age/Played/Last_Level now computed via `get_age(victim)`, `(played + current_time - logon) / 3600`, and `pcdata.last_level` per ROM instead of hardcoded 17/0/0.
|
|
75
|
+
- **WIZ-042** — `do_mstat` Carry weight now uses `get_carry_weight(victim) // 10` (includes coin burden) per ROM.
|
|
76
|
+
- **WIZ-043** — `do_ostat` Number/Weight line now uses `_object_carry_number(obj)` and `_get_obj_weight(obj)` per ROM `get_obj_number` / `get_obj_weight` / `get_true_weight`.
|
|
77
|
+
- **WIZ-044** — `do_rstat` Objects list now has 3 spaces after colon per ROM `".\n\rObjects: "`.
|
|
78
|
+
|
|
79
|
+
### Fixed (JSON loader parity closures — v2.6.105)
|
|
80
|
+
|
|
81
|
+
- **JSONLD-012** — JSON-loaded mob `race` values now resolve through ROM `race_lookup` into integer `race_table` indexes at load time, matching ROM `src/db2.c:234`. Race flag merging, OLC JSON save, and `medit show` display now handle integer-backed mob races without losing the human-readable race name.
|
|
82
|
+
|
|
83
|
+
### Fixed (JSON loader parity closures — v2.6.104)
|
|
84
|
+
|
|
85
|
+
- **JSONLD-009** — JSON-loaded areas now default `security` to 9 for both supported JSON formats, preserving explicit JSON values when present. This mirrors ROM `src/db.c:452` / `src/db.c:531` and restores the expected OLC builder-security default.
|
|
86
|
+
- **JSONLD-010** — Format 1 JSON areas now hydrate `credits` from the JSON payload when present, mirroring ROM `src/db.c:457`.
|
|
87
|
+
- **JSONLD-013** — JSON room `clan` values now resolve through `lookup_clan_id`, including ROM-style prefix matching, instead of preserving raw strings. Mirrors ROM `src/db.c:1192`.
|
|
88
|
+
- **JSONLD-014** — JSON `D` resets now apply boot-time door state and are discarded rather than retained in `area.resets` / `room.resets`, mirroring ROM `src/db.c:1058-1104`.
|
|
89
|
+
|
|
90
|
+
### Fixed (JSON loader parity closures — v2.6.103)
|
|
91
|
+
|
|
92
|
+
- **JSONLD-002** — Object `extra_descr` now stores `ExtraDescr` instances instead of raw dicts, matching the `.are` loader and ROM (`src/db2.c:571-580`). Consumer sites no longer need dict-aware fallback.
|
|
93
|
+
- **JSONLD-004** — Mob `hit`/`mana`/`damage` int tuples now parsed from `hit_dice`/`mana_dice`/`damage_dice` strings at load time via `_parse_dice_tuple`, matching ROM (`src/db2.c:251-269`). The `templates.py:_parse_dice` fallback still works as defense.
|
|
94
|
+
- **JSONLD-005** — Object `wear_flags` now converted from ROM letter string to int bitmask via `convert_flags_from_letters(WearFlag)`, matching the `.are` loader (`obj_loader.py:389`).
|
|
95
|
+
- **JSONLD-006** — Object `affected` list now populated with typed `Affect` instances from `affects` dicts, matching ROM (`src/db2.c:519-568`). `obj.affected` is no longer empty on JSON-loaded objects.
|
|
96
|
+
- **JSONLD-007** — Mob `hitroll` now populated from JSON `hitroll` key (falling back to `thac0`), matching ROM (`src/db2.c:248`). Previously `hitroll` was always 0 for JSON-loaded mobs.
|
|
97
|
+
- **JSONLD-008** — Mob `off_flags`/`imm_flags`/`res_flags`/`vuln_flags` int fields now populated after `merge_race_flags` via `_to_int_flags`, matching ROM (`src/db2.c:279-286`). Previously these stayed 0 on JSON-loaded mobs.
|
|
98
|
+
- **JSONLD-011** — Mob `form`/`parts` now converted from letter strings to int bitmasks after `merge_race_flags`, matching ROM (`src/db2.c:295-297`). Previously `IS_SET(mob.form, FORM_EDIBLE)` would fail with `ValueError`.
|
|
99
|
+
|
|
100
|
+
### Fixed (in-game runtime bugs surfaced 2026-04-30)
|
|
101
|
+
|
|
102
|
+
- `BUG-MOBHP` — Every JSON-loaded mob spawned with `max_hit=0` / `current_hp=1`, so look reported "awful condition" universally and a level 1 PC could one-shot Hassan (level 45). `mud/spawning/templates.py:_parse_dice` short-circuited on the default `(0,0,0)` primary tuple before consulting the `hit_dice` / `mana_dice` / `damage_dice` string fallback the JSON loader populated. Now treats all-zero primary as "unset" and falls through. ROM ref: `src/db.c:fread_mobile`. (commit `715469d`)
|
|
103
|
+
- `BUG-CORPSEINT` — `get coins corpse` raised `ValueError: invalid literal for int() with base 10: 'npc_corpse'`. `mud/loaders/json_loader.py:_load_objects_from_json` now routes prototype `item_type` through `_resolve_item_type_code` (mirroring the legacy `.are` loader), and `mud/commands/inventory.py:do_get` defensively coerces. ROM ref: `src/db.c:load_objects` `flag_value`. (commit `0f0d871`)
|
|
104
|
+
- `BUG-EDDICT` — `look fountain`, `read letter` raised `'dict' object has no attribute 'description'` because the JSON loader stores `extra_descr` as raw dicts and `mud/world/look.py` accessed `.description` attribute-style. Added `_ed_fields(ed)` helper accepting both shapes. ROM ref: `src/act_info.c:do_look`, `EXTRA_DESCR_DATA`. (commit `cb4eed7`)
|
|
105
|
+
- `BUG-NLOWER` — `look corpse`, `open south`, `open door` raised `'NoneType' object has no attribute 'lower'` because JSON-loaded prototypes carry `name=None` (the JSON schema collapsed ROM's separate keyword field) and ~15 helper sites used `getattr(x, "name", "").lower()`. Swept all match sites to the safe `(getattr(x, "name", None) or "").lower()` form across `mud/world/{obj_find,char_find}.py` and `mud/commands/{obj_manipulation,combat,misc_player,info_extended,imm_commands,imm_search,socials,remaining_rom}.py`. (commit `658d319`)
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
- `docs/parity/ROM_C_SUBSYSTEM_AUDIT_TRACKER.md` and `docs/parity/DB_C_AUDIT.md` — added "Re-audit Triggers from In-Game Debug Pass (2026-04-30)" sections flagging `mud/loaders/json_loader.py` as a partial port of `src/db.c:load_objects` / `load_mobiles` / `fread_obj` / `fread_mobile`. The four fixed bugs all trace to the JSON-path skipping ROM normalization that the `.are` loader performs. Recommendation to downgrade the db.c "100% certified" badge or split scope deferred to next session. The data-side gap (JSON dropped ROM's separate `name`/keyword field on objects) is still unfixed.
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- `mud/loaders/json_loader.py` parity audit (`docs/parity/JSON_LOADER_C_AUDIT.md`) — Phase 1–3 complete. Function inventory mapped against `src/db.c:load_objects` / `load_mobiles` / `load_rooms` / `load_resets` / `load_shops` / `fread_obj` / `fread_mobile` / `convert_mob` / `convert_obj`. **18 stable gap IDs filed (JSONLD-001..018)**: 7 CRITICAL (object keyword list missing from schema; `extra_descr` raw dicts; object `level` missing; mob hit/mana/damage tuples not populated at load; `wear_flags` raw string; `obj.affected` typed list never populated; mob `hitroll` populated from wrong JSON key — `thac0`); 8 IMPORTANT (off/imm/res/vuln int fields zero on JSON-loaded mobs; area `security`/`credits` defaults; `form`/`parts` raw strings; `race` as string not index; room `clan` not lookup-validated; D-reset semantics divergence; no per-type `value[]` coercion at load time); 3 MINOR (`short_descr`/`description` first-letter normalization; room `light` default reliance; `_link_exits_for_area` JSON-only `ROOM_NO_MOB` auto-set). The four runtime bugs fixed earlier today appear as JSONLD-001/002/003/004 — three are mitigated at consumer sites and remain ⚠️ OPEN at the loader, JSONLD-003 (`item_type`) is ✅ FIXED loader-side. `convert_mob` / `convert_obj` documented as intentionally absent (JSON files carry pre-resolved new-format values). Closures pending via `rom-gap-closer` per-gap; suggested ordering (single-commit fixes first): JSONLD-002, 004, 005, 006, 007, 008, 011 → then schema/converter changes for JSONLD-001, 003.
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
|
|
117
|
+
- `olc_save.c` parity audit (`docs/parity/OLC_SAVE_C_AUDIT.md`) — Phase 1–3 complete. 17 ROM functions inventoried. **JSON-authoritative framing locked**: Python writes JSON via `mud/olc/save.py` (`save_area_to_json`); `.are` remains read-only legacy input via `mud/loaders/area_loader.py`. Format-level divergences (ROM `fwrite_flag` A–Za–z encoding, `fix_string` tilde strip, `.are` column widths) are documented as N/A under this framing. 20 stable gap IDs filed (OLC_SAVE-001..020): **8 CRITICAL** round-trip data-loss bugs (mob `off`/`imm`/`res`/`vuln` flags, `form`/`parts`/`size`/`material`, mprog list, shop binding, spec_fun binding; object `level`, structured affect chain, structured extra-descr); **5 IMPORTANT** (no help-save path, `cmd_asave area` only handles `redit`, no autosave entry, NPC security gate gap, `save_area_list` missing `social.are` + HELP_AREA prepend); **7 MINOR** (4 string-drift cases, condition-letter ladder, exit lock-flag normalization, door-reset synthesis). Closures pending via `rom-gap-closer` per-gap. Tracker: `olc_save.c` row flipped ❌ Not Audited → ⚠️ Partial.
|
|
118
|
+
|
|
119
|
+
### Fixed
|
|
120
|
+
|
|
121
|
+
- `OLC_SAVE-009` — Area-grouped help-save / help-load round trip. New `_serialize_help` helper in `mud/olc/save.py` emits the canonical `{level, keywords, text}` shape; `save_area_to_json` now includes a per-area `helps` list (symmetric with mobs / objects / rooms / mob_programs / shops / specials). Paired loader-side change: new `_load_helps_from_json` in `mud/loaders/json_loader.py` walks the section, appends each entry to `area.helps`, and registers it in `help_registry` so `do help <keyword>` keeps resolving across save→reload cycles. Mirrors ROM `src/olc_save.c:826-843` (save_helps). Closes the IMPORTANT-block hole that forced the OLC_SAVE-010 hedit dispatcher to no-op behind a "Grabando area :" placeholder. ROM `save_other_helps` standalone-help-file fan-out (`src/olc_save.c:845-872`) remains N/A under JSON-authoritative framing — Python has no global `had_list`; helps live on their owning area. Tests: `tests/integration/test_olc_save_009_area_helps_round_trip.py` (3 cases).
|
|
122
|
+
- `OLC_SAVE-013` — `save_area_list` (`mud/olc/save.py`) now prepends `social.are\n` as the first line of the area.lst file, mirroring ROM `src/olc_save.c:94` (ROM OLC convention). Python omitted the prepend, causing the first area filename to appear in the position ROM reserves for the `social.are` marker. HAD/HELP_AREA standalone-help-area filename rows remain N/A pending OLC_SAVE-009 (help-save port). Tests: `tests/integration/test_olc_save_013_area_list_social_prepend.py` (2 cases: prepend with areas present, prepend with empty registry).
|
|
123
|
+
- `OLC_SAVE-012` — `_is_builder` (`mud/commands/build.py`) now gates on `char.is_npc` before consulting `pcdata.security` or `area.builders`, mirroring the ROM `IS_BUILDER` macro's leading `!IS_NPC(ch)` clause (`src/merc.h`) and the `IS_NPC(ch) → sec = 0` clamp in `cmd_asave` (`src/olc_save.c:933`). Without this gate, an NPC whose name happened to appear in an area's `builders` list (or one carrying a stub `pcdata.security`) would have passed the builder check, letting mob_special-style flows bypass area security. Existing OLC test fixtures updated to set `is_npc=False` on PCs (they were relying on the missing gate). Tests: `tests/integration/test_olc_save_012_npc_security_gate.py` (3 cases: NPC name match, NPC stub-pcdata bypass, PC regression).
|
|
124
|
+
- `OLC_SAVE-011` — `cmd_asave` now accepts `char=None` for the autosave-timer entry path. Mirrors ROM `src/olc_save.c:931-936` (`if (!ch) sec = 9` lets `do_asave(NULL, "world")` persist every area). The "world" branch now skips the `_is_builder` gate when ch is None and returns silently (ROM `if (ch) send_to_char`); other args short-circuit before char-attribute access. Unblocks future autosave wiring (`olc_save.c` autosave timer port). Tests: `tests/integration/test_olc_save_011_autosave_entry.py` (3 cases: null-ch saves every area, null-ch with empty registry no-crash, player-path message regression).
|
|
125
|
+
- `OLC_SAVE-010` — `@asave area` now dispatches across all five ROM editor types (aedit / redit / oedit / medit / hedit) instead of only `redit`. `cmd_asave` (`mud/commands/build.py`) now resolves the target area from `session.editor_state["area"]` for aedit, `room.area` for redit, `obj_proto.area` for oedit, and `mob_proto.area` for medit; hedit returns the ROM-faithful "Grabando area :" prefix pending OLC_SAVE-009 (help-save port). Mirrors ROM `src/olc_save.c:1080-1128`. Without this, aedit/oedit/medit users got "You are not editing an area, therefore an area vnum is required." and their changes were silently unsaveable. Tests: `tests/integration/test_olc_save_010_asave_area_dispatch.py` (6 cases: aedit/redit/oedit/medit dispatch, hedit help-save marker, ED_NONE error).
|
|
126
|
+
- `OLC_SAVE-008` — Object extra-description list now routed through `_serialize_extra_descr` (`mud/olc/save.py`), which is dict-aware so a prototype carrying either a plain `{"keyword", "description"}` dict (from `mud/loaders/obj_loader.py`) or an `ExtraDescr` dataclass instance produces an identical flat payload. Mirrors ROM `src/olc_save.c:431-435`. Replaces the prior raw `list(...extra_descr, [])` pass-through that crashed `json.dump` on dataclass values and let stray dict keys leak through. Tests: `tests/integration/test_olc_save_008_object_extra_descr.py` (3 cases: dict round-trip, `ExtraDescr` dataclass json-safe, canonical-key shape).
|
|
127
|
+
- `OLC_SAVE-007` — Object affect chain now serialized through a dedicated `_serialize_affect` helper (`mud/olc/save.py`) that normalizes a prototype affect — accepting either a plain dict (A-line `{location, modifier}` or F-line `{where, location, modifier, bitvector}` per `mud/loaders/obj_loader.py`) or an `Affect` dataclass instance — into a json-safe dict. Mirrors ROM `src/olc_save.c:399-429` (TO_OBJECT applies + TO_AFFECTS/IMMUNE/RESIST/VULN). Replaces the prior opaque `list(...affects, [])` pass-through that silently dropped fields and crashed `json.dump` on dataclass values. Tests: `tests/integration/test_olc_save_007_object_affects.py` (5 cases: A-line dict normalization, F-line preservation, `Affect` dataclass shape, mixed-shape round-trip, `json.dump` regression).
|
|
128
|
+
- `OLC_SAVE-006` — Object `level` now persisted on JSON save. `_serialize_object` (`mud/olc/save.py`) emits the field; paired loader-side change in `_load_objects_from_json` (`mud/loaders/json_loader.py`) reads it back. Mirrors ROM `src/olc_save.c:378` (save_object level emission). Without this, a save→reboot→reload cycle silently reset every object level to 0, breaking level-gated drops, identify output, and equipment loadout heuristics. Tests: `tests/integration/test_olc_save_006_object_level.py` (3 cases: serializer field emit, full round-trip, default level=0 round-trip).
|
|
129
|
+
- `OLC_SAVE-005` — Mob `spec_fun` bindings now persisted on JSON save via a new top-level `specials` section emitted by `save_area_to_json` (`mud/olc/save.py`). Mirrors ROM `src/olc_save.c:578-606` (save_specials writes `M <vnum> <spec_fun>` rows in the per-area `#SPECIALS` section). Loader-side `apply_specials_from_json` (`mud/loaders/specials_loader.py`) was already in place; this closure adds the missing serialize half. Without this, a save→reboot→reload cycle silently erased every spec_fun binding (e.g. `spec_breath_fire` on dragons reverted to no special). Tests: `tests/integration/test_olc_save_005_mob_spec_fun.py` (3 cases: section emit, full round-trip, mob-without-spec_fun emits no entry).
|
|
130
|
+
- `OLC_SAVE-004` — Mob shop bindings (`MobIndex.pShop` → keeper / buy_types[5] / profit_buy / profit_sell / open_hour / close_hour) now persisted on JSON save via a new top-level `shops` section emitted by `save_area_to_json` (`mud/olc/save.py`). Mirrors ROM `src/olc_save.c:786-824` (save_shops). Paired loader-side change: new `_load_shops_from_json` (`mud/loaders/json_loader.py`) rehydrates `mud.registry.shop_registry` keyed by keeper vnum and re-attaches `MobIndex.pShop` after mob load. Without this, a save→reboot→reload cycle silently erased every shop binding — keepers reverted to non-merchant NPCs. Tests: `tests/integration/test_olc_save_004_mob_shops.py` (3 cases: section emit, full round-trip restoring `shop_registry`, mob-without-shop emits no entry). Loader and serializer changes ship in one commit per the audit's locked closure rule.
|
|
131
|
+
- `OLC_SAVE-003` — Mob `mprogs` (mob program assignments) now persisted on JSON save via a new `mob_programs` section emitted by `save_area_to_json` (`mud/olc/save.py`). Mirrors ROM `src/olc_save.c:151-169` (save_mobprogs writes the per-area `#MOBPROGS` section) plus `src/olc_save.c:245-250` (per-mob MPROG_LIST inside save_mobile). Without this, a save→reboot→reload cycle silently erased every mob program binding. Python's JSON layout factors program code area-wide and links via assignments (matching `mud/loaders/json_loader.py:_load_mob_programs_from_json`); the new `_collect_mob_programs` helper reverses that projection by walking each mob's `mprogs` list and grouping by program vnum. Triggers serialize via `mud.mobprog.format_trigger_flag` (int → ROM keyword). Tests: `tests/integration/test_olc_save_003_mob_mprogs.py` (3 cases: single assignment, multiple mobs sharing one program, mob without mprogs).
|
|
132
|
+
- `OLC_SAVE-002` — Mob `form`/`parts`/`size`/`material` now persisted by `_serialize_mobile` on JSON save (`mud/olc/save.py:136`). Mirrors ROM `src/olc_save.c:213-219` (save_mobile fwrite/fwrite_flag for Form/Parts/Size/Material). Without this, a save→reload cycle silently dropped physical descriptors that drive corpse parts, magic targeting, and combat sizing. `Size` enum values are coerced to lowercase names (e.g. `Size.MEDIUM` → `"medium"`) to match the `_load_mobs_from_json` string contract. JSON-write content locked by `tests/integration/test_olc_save_002_mob_form_parts_size_material.py` (3 cases). Note: a full Python-object equality round-trip is not asserted because the loader's `merge_race_flags` unions race-default bits into `form`/`parts` on read; the JSON file itself is the canonical write surface and is asserted directly.
|
|
133
|
+
- `OLC_SAVE-001` — Mob defensive/offensive flag sets (`offensive`/`immune`/`resist`/`vuln` letter-strings) now persisted by `_serialize_mobile` on JSON save (`mud/olc/save.py:136`). Mirrors ROM `src/olc_save.c:205-208` (save_mobile fwrite_flag for Off/Imm/Res/Vuln). Without this, a save→reboot→reload cycle silently dropped all mob defensive flag sets. Round-trip locked by `tests/integration/test_olc_save_001_mob_defensive_flags.py` (3 cases: serializer field emission, full save→load round-trip, empty/zero flag-string safety).
|
|
134
|
+
- `OLC_ACT-014` — Locked the `area.changed = True` protocol divergence between Python and ROM. ROM `src/olc.c:452-463`/`:510-521` dispatchers `SET_BIT(pArea->area_flags, AREA_CHANGED)` whenever a subcommand handler returns `TRUE`; Python uses an imperative pattern where each `_interpret_*edit` branch sets `area.changed = True` directly after a successful mutation. Structural divergence with equivalent behavior. Added a ROM-cite comment to `_mark_area_changed` (`mud/commands/build.py:220`) and a regression test that exercises one representative `name` mutation per editor (aedit/redit/oedit/medit), one secondary subcommand (aedit `security`), and one failed-mutation no-op case mirroring ROM's "handler returned FALSE → no SET_BIT" path. Test: `tests/integration/test_olc_act_014_area_changed_protocol.py` (6 cases).
|
|
135
|
+
- `OLC_ACT-013` — Locked the equivalence between Python `_get_area_for_vnum` (`mud/commands/build.py:1352`) and ROM `get_vnum_area` (`src/olc_act.c:588-599`). ROM walks the `area_first` linked list; Python iterates `area_registry.values()`. CPython dicts preserve insertion order (3.7+), so load-order traversal is equivalent to ROM's linked-list walk. Added a ROM-cite comment to the function and a regression test that locks the dict insertion-order guarantee plus first-match-on-overlap behavior. Test: `tests/integration/test_olc_act_013_get_area_for_vnum_order.py` (3 cases).
|
|
136
|
+
|
|
137
|
+
### Added
|
|
138
|
+
|
|
139
|
+
- `OLC-016` / `OLC-017` / `OLC-018` / `OLC-019` — sibling-audit dispatcher gaps closed transitively by OLC_ACT-001/002/003/004/005/006. The OLC-NNN gaps were filed in `OLC_C_AUDIT.md` as "missing dispatcher subcommand" entries; the OLC_ACT-NNN gaps are the corresponding builder-logic closures in `src/olc_act.c`. In Python, the dispatcher and builder live in the same `cmd_*edit` function in `mud/commands/build.py`, so closing the OLC_ACT side automatically closes the OLC side. All four CRITICAL `do_*edit create` paths are now wired with full ROM validation chains and authoritative `new_*_index` defaults from `src/mem.c`.
|
|
140
|
+
- `OLC_ACT-002` + `OLC_ACT-003` + `OLC_ACT-004` — `redit create <vnum>` / `redit reset` / `redit <vnum>` silent teleport (`mud/commands/build.py:cmd_redit`). All three are branches of ROM's single `do_redit` function (`src/olc.c:745-821`) so they ship in one combined commit. **OLC_ACT-002**: explicit `redit create <vnum>` keyword wired with full ROM validation chain (vnum required, area assignment, IS_BUILDER, already-exists). `new_room_index` defaults from `src/mem.c:181-218` (heal_rate=100, mana_rate=100). After create, builder is moved into the new room via silent `_char_from_room`/`_char_to_room`. **OLC_ACT-003**: `redit reset` dispatcher wired — security gate, exact ROM message "Room reset.\\n\\r", area `changed=True`, calls `apply_resets(area)` via `_apply_resets_for_redit` wrapper. ROM uses `reset_room(pRoom)` (src/olc.c:765); Python's broader-scope `apply_resets(area)` is a documented minor divergence pending a per-room reset port. **OLC_ACT-004**: `redit <vnum>` silent-teleport reuses existing `_char_from_room`/`_char_to_room` primitives from `mud.commands.imm_commands` per the locked human-decision flag — no new movement infra. Validates target room exists, IS_BUILDER on TARGET area, relocates, sets descriptor edit pointer. Unblocks OLC-017 (all three halves: create/reset/vnum). Tests: `tests/integration/test_olc_act_002_redit_create.py` (8), `tests/integration/test_olc_act_003_redit_reset.py` (4), `tests/integration/test_olc_act_004_redit_vnum_teleport.py` (5).
|
|
141
|
+
- `OLC_ACT-006` — `medit create <vnum>` subcommand (`mud/commands/build.py:_medit_create`). Mirrors ROM `src/olc_act.c:3704-3753` plus `new_mob_index` defaults from `src/mem.c:365-424` (player_name="no name", short_descr="(no short description)", long_descr="(no long description)\\n\\r", description="", level=0, sex=Sex.NONE, size=Size.MEDIUM, start_pos="standing", default_pos="standing", material="unknown", new_format=True). **CRITICAL**: `ActFlag.IS_NPC` is set on both `act_flags` (modern) and legacy `act` per ROM `src/olc_act.c:3745` `pMob->act = ACT_IS_NPC;` — without this, every NPC-classification check downstream would misclassify newly-built mobs as players. Full ROM validation chain (vnum required, area assignment, builder security, already-exists). Removed pre-existing auto-create-on-unknown-vnum bug. Unblocks OLC-019. Test: `tests/integration/test_olc_act_006_medit_create.py` (12 cases). Drive-by: `tests/integration/test_olc_builders.py:test_mob_proto` fixture also patched to write to the canonical `mud.models.mob.mob_registry` (matching the OLC_ACT-005 obj-fixture fix).
|
|
142
|
+
- `OLC_ACT-005` — `oedit create <vnum>` subcommand (`mud/commands/build.py:_oedit_create`). Mirrors ROM `src/olc_act.c:3178-3225` plus `new_obj_index` defaults from `src/mem.c:297-335` (name="no name", short_descr="(no short description)", description="(no description)", item_type="trash", material="unknown", extra_flags=0, wear_flags=0, weight=0, cost=0, value=[0]*5, new_format=True). Full ROM validation chain: vnum required (empty/zero rejected with "Syntax: oedit create [vnum]"), area assignment ("OEdit: That vnum is not assigned an area."), builder security ("OEdit: Vnum in an area you cannot build in."), already-exists ("OEdit: Object vnum already exists."). Returns "Object Created.\n\r" on success. **Removed** the pre-existing auto-create-on-unknown-vnum bug — unknown vnums without the explicit `create` keyword now return an error instead of silently allocating a new proto. Unblocks OLC-018. Test: `tests/integration/test_olc_act_005_oedit_create.py` (11 cases). Drive-by: fixed `tests/integration/test_olc_builders.py:test_obj_proto` fixture which registered protos in the wrong registry (`mud.registry.obj_registry` vs the canonical `mud.models.obj.obj_index_registry`).
|
|
143
|
+
- `OLC_ACT-001` — `aedit create` subcommand (`mud/commands/build.py:cmd_aedit` + `_aedit_create`). Mirrors ROM `src/olc_act.c:667-679` plus authoritative defaults from `src/mem.c:91-122` (`new_area`): `name="New area"`, `builders="None"`, `security=1`, `min/max_vnum=0`, `empty=True`, `area_flags=AreaFlag.ADDED`, `file_name="area<vnum>.are"`. Vnum allocation uses `max(area_registry) + 1` (Python adaptation; ROM uses global `top_area` counter). Reachable from both `@aedit create` (no active session) and `create` typed inside an active aedit session. Unblocks OLC-016 in the sibling audit. Test: `tests/integration/test_olc_act_001_aedit_create.py` (9 cases).
|
|
144
|
+
- `olc_act.c` parity audit (`docs/parity/OLC_ACT_C_AUDIT.md`) — Phase 1–3 complete. 108 ROM functions inventoried across four editors (aedit/redit/oedit/medit); mpedit/hedit out of scope (sibling audits). 14 stable gap IDs filed (OLC_ACT-001..014): 6 CRITICAL (aedit_create wholly missing; redit_create missing; redit reset/vnum dispatcher gaps; oedit_create missing security gate; medit_create missing ACT_IS_NPC flag on new mobs), 6 IMPORTANT (show-command completeness for all four editors; success message string drift; aedit_reset missing), 2 MINOR (structural). Tier breakdown: TIER A 9 functions (line-by-line), TIER B 8 functions (moderate), TIER C ~78 functions (inventory). Closures pending via `rom-gap-closer` per-gap. Tracker: olc_act.c row flipped ❌ Not Audited → ⚠️ Partial.
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- `OLC_ACT-007` — `aedit show` now includes the area flags row (mirroring ROM `src/olc_act.c:644-646`). The Flags line uses `flag_string(AreaFlag, area.area_flags)` to format the ADDED/CHANGED/LOADING flags. Test: `tests/integration/test_olc_act_007_aedit_show_flags.py` (5 cases).
|
|
149
|
+
- `OLC_ACT-008` — `redit show` brought to ROM byte-parity with `src/olc_act.c:1068-1236`. Sector display labels in `_SECTOR_NAMES` (`mud/commands/build.py`) now use `swim`/`noswim` per ROM `src/tables.c:391-392` (previously `water_swim`/`water_noswim`); the exit line in `_room_summary` now emits the two-space gap between `Key: [%5d]` and `Exit flags:` per ROM lines 1184/1196 (single sprintf trailing space + strcat leading space). The remaining ROM fields (description, name, area, vnum, room flags, heal/mana/clan/owner/extra-descs, characters, objects, per-exit keyword/description, uppercase-non-reset flag rule) were already implemented in `_room_summary`; the new parity tests lock them in going forward. Test: `tests/integration/test_olc_act_008_redit_show_parity.py` (4 cases).
|
|
150
|
+
- `OLC_ACT-010` — `medit show` rewritten to ROM byte layout (`src/olc_act.c:3519-3699`). Now emits all ROM rows in order: Name/Area, Act flags, Vnum/Sex/Race, Level/Align/Hitroll/DamType, conditional Group, Hit/Damage/Mana dice, Affected by, Armor (4 columns), Form, Parts, Imm, Res, Vuln, Off, Size, Material, Start/Default pos, Wealth, Short/Long/Description. New helpers `_format_intflag`/`_format_position`/`_format_size`/`_format_sex` in `mud/commands/build.py`. Three sub-gaps explicitly deferred and recorded in `docs/parity/OLC_ACT_C_AUDIT.md`: **OLC_ACT-010b** dice/AC byte format (Python data model stores strings; ROM stores 3 ints per dice); **OLC_ACT-010c** shop/mprogs/spec_fun rendering (needs MobShop/MProg model alignment + `spec_name` lookup); **OLC_ACT-010d** ROM-faithful flag-table name strings (display tables analogous to OLC_ACT-009's `_WEAR_FLAG_DISPLAY`/`_EXTRA_FLAG_DISPLAY` needed for 10 mob flag tables). Existing `tests/test_olc_medit.py::test_medit_show_command` assertions updated to ROM format. New: `tests/integration/test_olc_act_010_medit_show_parity.py` (8 cases).
|
|
151
|
+
- `OLC_ACT-012` — `aedit reset` subcommand wired in `_interpret_aedit` (`mud/commands/build.py`). Mirrors ROM `src/olc_act.c:653-663` `aedit_reset`: calls `apply_resets(area)` via the existing `_apply_resets_for_redit` wrapper, sets `area.changed=True`, returns ROM-exact `"Area reset."` (previously `"Unknown area editor command: reset"`). Test: `tests/integration/test_olc_act_012_aedit_reset.py` (1 case).
|
|
152
|
+
- `OLC_ACT-011` — All four `*_name` OLC builders (`aedit_name`, `redit_name`, `oedit_name`, `medit_name`) now return ROM's exact `"Name set."` success message (was Python-verbose "Area name set to: X" / "Room name set to X" / "Object name (keywords) set to: X" / "Player name set to: X"). ROM source: `src/olc_act.c:683-700`/`1770-1787`/`2990-3010`/`3913-3931`. Existing assertions in `tests/test_olc_aedit.py` / `test_olc_medit.py` / `test_olc_oedit.py` updated. New: `tests/integration/test_olc_act_011_name_messages.py` (4 cases).
|
|
153
|
+
- `OLC_ACT-009` — `oedit show` rewritten to ROM byte layout (`src/olc_act.c:2733-2812`) + `_show_obj_values` ported from ROM `show_obj_values` (`src/olc_act.c:2210-2374`). New display tables `_WEAR_FLAG_DISPLAY` / `_EXTRA_FLAG_DISPLAY` mirror `src/tables.c:434-483` byte-for-byte (ROM-faithful labels: "finger"/"nosac"/"wearfloat"/"antigood"/"rotdeath" — not Python enum-name forms). New `_APPLY_NAMES` dict mirrors `src/merc.h:1205-1231` + `src/tables.c:489-516` for the affects table (with the ROM `APPLY_SAVES`/`APPLY_SAVING_PARA` 20-collision resolved to "saves"). `_show_obj_values` covers 13 ITEM_* cases (LIGHT, WAND/STAFF, PORTAL, FURNITURE, SCROLL/POTION/PILL, ARMOR, WEAPON, CONTAINER, DRINK_CON, FOUNTAIN, FOOD, MONEY); WAND/STAFF/SCROLL/POTION/PILL spell-name lookup emits raw value-index until a skill-by-index registry lands. Existing `tests/test_olc_oedit.py::test_oedit_show_command` assertions updated from Python-only verbose labels to ROM format. New: `tests/integration/test_olc_act_009_oedit_show_parity.py` (8 cases).
|
|
154
|
+
- `OLC-022` — `do_resets` (`mud/commands/imm_olc.py`) rewritten with full ROM subcommand set (src/olc.c:1232-1469): P-reset via `inside <containerVnum> [limit] [count]` (validates ITEM_CONTAINER or ITEM_CORPSE_NPC), O-reset via `room`, G/E-reset via wear-loc prefix lookup (`lfin` → FINGER_L), R-reset via `random 1..6`, M-reset extended with optional `[max#area] [max#room]` args. 6-line syntax block on unrecognized numeric-arg subcommand. `_add_reset` helper extracted. Test: `tests/integration/test_olc_do_resets_subcommands.py` (27 cases).
|
|
155
|
+
- `OLC-020` — `display_resets` (`mud/commands/imm_olc.py`) now faithfully formats each reset type (M/O/P/G/E/D/R) with exact ROM `sprintf` column widths, pet-shop `final[5]='P'` overlay (src/olc.c:1037-1044), wear-loc decoding via `wear_loc_strings` table, and door-reset state decoding. Bad-mob/obj `continue` paths correctly suppress output per ROM. New `mud/utils/olc_tables.py` provides `WEAR_LOC_STRINGS`, `WEAR_LOC_FLAGS`, `DOOR_RESETS`, `DIR_NAMES` tables ported from `src/tables.c:355-572`. Test: `tests/integration/test_olc_display_resets.py` (16 cases).
|
|
156
|
+
- `OLC-023` — `do_alist` (`mud/commands/imm_olc.py:121-146`) iterated the nonexistent `registry.areas` attribute and returned a header-only listing on a live system. Now iterates `area_registry.values()`, prints `area.vnum` (was a 1-indexed enumerate counter — drifted from ROM `src/olc.c:1494`'s `pArea->vnum`), and reads `area.file_name` (was the nonexistent `area.filename`). Test: `tests/integration/test_olc_alist.py` (4 cases).
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
|
|
160
|
+
- `STRING-004` — `string_add` OLC editor input dispatcher (.c/.s/.r/.f/.h/.ld/.li/.lr dot-commands, ~/@ termination with on_commit callback, MAX_STRING_LENGTH-4 length cap) (src/string.c:121). 24 integration tests in `tests/integration/test_string_editor_string_add.py`. Completes `string.c` at 100%.
|
|
161
|
+
- `STRING-005` — `format_string` word-wrap, sentence capitalization (src/string.c:299).
|
|
162
|
+
- `STRING-002` — `mud/utils/string_editor.py:string_append(string_edit_obj, current) -> str`. Mirrors ROM `src/string.c:66-86`: enter APPEND mode, preserve the buffer, and return the editor banner (4 lines) plus the `numlines()` line-numbered listing. Takes a `StringEdit` object and a *current* string (the existing text to append to), unlike `string_edit` which clears. The banner matches ROM verbatim: `-=======- Entering APPEND Mode -========-`, help, termination, and separator. The listing shows each line with its 1-indexed line number in `%2d` format. Used by every OLC description builder (`aedit_builder`, `redit`, `medit`, `oedit`, etc.). Test: `tests/integration/test_string_editor_append.py` (9 cases).
|
|
163
|
+
- `STRING-001` — `mud/utils/string_editor.py:string_edit(string_edit_obj) -> str`. Mirrors ROM `src/string.c:38-57`: enter EDIT mode, clear the buffer, return the editor banner (4 lines). Takes a `StringEdit` object (mirrors ROM `ch->desc->pString` field) and initializes it with an empty buffer. The returned banner matches ROM verbatim: `-========- Entering EDIT Mode -=========-`, help prompt, termination instructions, and separator. Used by `olc_act.c::aedit_builder` ("desc edit"), `redit` (edit-description), `medit` (edit-description). Test: `tests/integration/test_string_editor_edit.py` (6 cases).
|
|
164
|
+
- `STRING-003` — `mud/utils/string_editor.py:string_replace(orig, old, new) -> str`. Mirrors ROM `src/string.c:95-112`: replace the first occurrence of *old* substring within *orig* with *new*. If *old* is not found, returns *orig* unchanged. Empty *old* returns *orig* unchanged (ROM behavior). Used by `string_add::.r` dot-command (STRING-004) and `aedit_builder::replace`. Test: `tests/integration/test_string_editor_replace.py` (9 cases).
|
|
165
|
+
- `STRING-010` — `mud/utils/string_editor.py:string_lineadd(string, newstr, line) -> str`. Mirrors ROM `src/string.c:607-645`: insert *newstr* as the 1-indexed line N. The inserted line gets a `\n\r` suffix. If line is past the end, insertion doesn't happen (never reached). Used by `.li` and `.lr` dot-commands. Test: `tests/integration/test_string_editor_lineadd.py` (10 cases).
|
|
166
|
+
- `STRING-009` — `mud/utils/string_editor.py:string_linedel(string, line) -> str`. Mirrors ROM `src/string.c:574-605`: remove the 1-indexed line N from the string, preserving `\n\r` line endings. Out-of-range line numbers are a no-op. Used by `.ld` dot-command. Test: `tests/integration/test_string_editor_linedel.py` (8 cases).
|
|
167
|
+
- `STRING-012` — `mud/utils/string_editor.py:numlines(string) -> str`. Mirrors ROM `src/string.c:676-692`: format string as line-numbered listing (`%2d. <line>\n\r`), 1-indexed. Used by `.s` dot-command and `string_append` greeting. Test: `tests/integration/test_string_editor_numlines.py` (7 cases).
|
|
168
|
+
- `STRING-011` — `mud/utils/string_editor.py:merc_getline(string) -> tuple[str, str]`. Mirrors ROM `src/string.c:647-674`: read one `\n`-terminated line; consume trailing `\r` when present (ROM `\n\r` canonical line ending). Returns `(rest, line)`. Test: `tests/integration/test_string_editor_merc_getline.py` (6 cases).
|
|
169
|
+
- `STRING-006` — `mud/utils/string_editor.py:first_arg(argument, lower=False) -> tuple[str, str]`. Mirrors ROM `src/string.c:468-508`: quote/paren-aware single-arg parser. Recognizes `'`/`"`/`%` (self-pair quotes) and `(`/`)` (balanced pair). Unterminated quotes consume the entire remainder. The `lower` flag (ROM `fCase`) lowercases the parsed word. Test: `tests/integration/test_string_editor_first_arg.py` (10 cases).
|
|
170
|
+
- `STRING-008` — `mud/utils/string_editor.py:string_proper(argument) -> str`. Mirrors ROM `src/string.c:551-572`: uppercases first char of each space-delimited word, leaves rest of each word as-is. Differs from Python `str.title()` which also lowercases the rest. Test: `tests/integration/test_string_editor_proper.py` (8 cases).
|
|
171
|
+
- `STRING-007` — `mud/utils/string_editor.py:string_unpad(argument) -> str`. Mirrors ROM `src/string.c:516-543`: trims leading/trailing spaces (only spaces, not all whitespace) — `aedit_builder` callers expect tab/newline preservation. Test: `tests/integration/test_string_editor_unpad.py` (7 cases).
|
|
172
|
+
- `BIT-003` — `mud/utils/bit.py:is_stat(table) -> bool`. Mirrors ROM `src/bit.c:93-104` (and replaces ROM's static `flag_stat_table[]` registry at `src/bit.c:50-83`): returns True for IntEnum (stat) tables, False for IntFlag (flag) tables. The Python port encodes the stat-vs-flag distinction in the type system, so no runtime registry is needed. With BIT-001/002/003 closed, `bit.c` flips ✅ Audited 90% → ✅ Audited 100%. Test: `tests/integration/test_bit_is_stat.py` (5 cases).
|
|
173
|
+
- `BIT-002` — `mud/utils/bit.py:flag_string(table, bits) -> str`. Mirrors ROM `src/bit.c:151-177`: returns a space-joined string of every flag name set in *bits* for IntFlag (flag) tables, the single matched name for IntEnum (stat) tables, or the literal `"none"` when nothing matched. The ROM rotating two-buffer trick (`buf[2][512]`) is unnecessary in Python (immutable strings). Composite alias IntFlag members are skipped to avoid double-printing. Test: `tests/integration/test_bit_flag_string.py` (8 cases).
|
|
174
|
+
- `BIT-001` — `mud/utils/bit.py:flag_value(table, argument) -> int | None`. Mirrors ROM `src/bit.c:111-142`: tokenizes the argument, prefix-looks up each token, OR-accumulates hits for IntFlag (flag) tables, returns a single matched value for IntEnum (stat) tables, returns `None` (the `NO_FLAG` sentinel) on no match. Unknown tokens are silently skipped, mirroring ROM `flag_value` semantics (which differ from ROM `do_flag` on purpose). Test: `tests/integration/test_bit_flag_value.py` (9 cases).
|
|
175
|
+
- `OLC-INFRA-001` — descriptor-level OLC editor state plumbing. New `mud/olc/editor_state.py` provides `EditorMode` IntEnum (mirrors ROM `src/olc.h:53-59` — `NONE`/`AREA`/`ROOM`/`OBJECT`/`MOBILE`/`MPCODE`/`HELP`), `StringEdit` dataclass (mirrors ROM `desc->pString` — buffer + on-commit hook + `MAX_STRING_EDIT_LENGTH=4604`), and `route_descriptor_input(session)` (mirrors ROM `src/comm.c:833-847` — `string_edit` precedes `editor_mode` precedes normal interpret). `Session.editor_mode` and `Session.string_edit` fields wired in `mud/net/session.py`. Destinations (`string_add` for STRING-004, `run_olc_editor` for OLC-001) remain stubbed under their own gap IDs; this commit lands only the routing decision and data shapes that unblock the STRING-001..012 cluster. Test: `tests/integration/test_olc_descriptor_state.py` (6 cases).
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
|
|
179
|
+
- `string.c` parity audit (`docs/parity/STRING_C_AUDIT.md`) — `string.c` flipped ⚠️ Partial 85% (stale, wrong file path) → ✅ Audited 5% (accurate). Phase 1 inventory catalogues all 12 public functions (`string_edit`, `string_append`, `string_replace`, `string_add`, `format_string`, `first_arg`, `string_unpad`, `string_proper`, `string_linedel`, `string_lineadd`, `merc_getline`, `numlines`); every one is OLC-editor backend operating on `ch->desc->pString`/`ch->desc->editor` with no current Python consumer (`mud/olc/` skeleton only). 12 stable gap IDs filed (`STRING-001..STRING-012`), all DEFERRED to the OLC audit cluster (`olc.c`/`olc_act.c`/`olc_save.c`/`olc_mpcode.c`/`hedit.c`) where their first concrete consumers will appear. Previous tracker note "85% — `mud/utils.py`" was stale: that file does not exist; only `mud/utils/text.py:smash_tilde` (a `merc.h` helper, not a `string.c` helper) is ported. No code changes.
|
|
180
|
+
- `const.c` parity audit (`docs/parity/CONST_C_AUDIT.md`) — Phase 1–3 complete. 16 ROM data tables inventoried; 13 ✅ AUDITED (item, wiznet, attack, race, pc_race, class, int_app, liq, skill, group, plus `str_app.carry` + `str_app.wield` columns); 7 stable gap IDs filed (`CONST-001`..`CONST-007`). **Four CRITICAL combat-math gaps surfaced**: `CONST-002` `GET_HITROLL` macro missing `str_app[STR].tohit` (`mud/combat/engine.py:411,420`), `CONST-003` `GET_DAMROLL` missing `str_app[STR].todam` (`mud/combat/engine.py:1184`), `CONST-004` `GET_AC` missing `dex_app[DEX].defensive` (`mud/combat/engine.py:391`), `CONST-005` `advance_level` missing `con_app[CON].hitp` + `number_range(hp_min,hp_max)` per-level HP roll (`mud/advancement.py:91`). One IMPORTANT advancement gap (`CONST-006` `wis_app[WIS].practice` in `advance_level`). One IMPORTANT data gap (`CONST-001` `title_table` 480 entries — defer to NANNY-009 dedicated session). One MINOR (`CONST-007` `weapon_table` — defer to OLC audit, BIT-style). `ROM_C_SUBSYSTEM_AUDIT_TRACKER.md` row updated; tracker held at ⚠️ Partial 80% pending closures via `/rom-gap-closer`. No code changes.
|
|
181
|
+
- `bit.c` parity audit (`docs/parity/BIT_C_AUDIT.md`) — `bit.c` flipped ⚠️ Partial 90% → ✅ Audited 90%. Confirmed the only current Python consumer of bit.c-shaped logic (`do_flag` in `mud/commands/remaining_rom.py`) faithfully mirrors ROM `do_flag` semantics (not ROM `flag_value` — they differ on unknown-name handling on purpose). Three MINOR helpers (`flag_value`, `flag_string`, `flag_stat_table`+`is_stat`) recorded as `BIT-001`/`BIT-002`/`BIT-003` and deferred to the OLC audit, where their first concrete consumers (`olc.c`, `olc_act.c`, `olc_save.c`, `act_olc.c`) will appear. No code changes.
|
|
182
|
+
- `docs/parity/ROM_C_SUBSYSTEM_AUDIT_TRACKER.md` — reconciled the stale `P1-3: db.c + db2.c (PARTIAL - 55%)` section with the actual audit state. Both files have been ✅ Audited 100% on the summary table since the Jan 5 (db.c) and Apr 28 (db2.c) sessions; the P1-3 narrative section has been rewritten to reflect that and to point at the per-file audit docs (`DB_C_AUDIT.md` covers db.c's 44/44 functional functions; `DB2_C_AUDIT.md` covers DB2-001/002/003/006 closures and DB2-004/005 deferred MINORs). No code changes.
|
|
183
|
+
|
|
184
|
+
### Added
|
|
185
|
+
|
|
186
|
+
- `comm.c` parity audit (`docs/parity/COMM_C_AUDIT.md`) — non-networking surface of `src/comm.c` (`bust_a_prompt`, `act_new`, `colour`, `check_parse_name`, `stop_idling`, `fix_sex`, `show_string`) mapped to Python equivalents. Networking layer (`main`, `init_socket`, `game_loop_*`, descriptor I/O) confirmed deferred-by-design per the asyncio rewrite. Phase 3 produces 9 stable gap IDs (`COMM-001..COMM-009`).
|
|
187
|
+
- `mud/utils/prompt.py:bust_a_prompt(char) -> str` — port of ROM `src/comm.c:1420-1595`. Expands `%h %H %m %M %v %V %x %X %g %s %a %r %R %z %% %e %c %o %O` against character state, falls back to `<%dhp %dm %dmv> %s` when `ch->prompt` is unset, short-circuits to `<AFK>` when `COMM_AFK` is on. Wired into both telnet game-loop call sites in `mud/net/connection.py`. Test: `tests/integration/test_prompt_rom_parity.py` (8 cases).
|
|
188
|
+
- `board.c` parity audit (`docs/parity/BOARD_C_AUDIT.md`) — full Phase 1 inventory of every public ROM function in `src/board.c` (Erwin Andreasen 1995–96 note-board subsystem) mapped to `mud/notes.py`, `mud/models/board.py`, and `mud/commands/notes.py`. Phase 3 produces 14 stable gap IDs (BOARD-001..BOARD-014); `tracker.md` flips `board.c` from ❌ Not Audited 35% → ⚠️ Partial 85%. New regression suite `tests/integration/test_boards_rom_parity.py` (6 ROM-parity tests, all green).
|
|
189
|
+
|
|
190
|
+
### Added
|
|
191
|
+
|
|
192
|
+
- `MUSIC-002` — `mud/music/__init__.py:load_songs(path=area/music.txt)` ports ROM `src/music.c:160-218`. Reads the ROM-format music data file (`group~` / `name~` / lyric lines / `~` / `#`), populates `mud.music.song_table` (up to `MAX_SONGS=20`), resets `channel_songs[0..MAX_GLOBAL]` to `-1`, drops lyrics past `MAX_LINES=100` with a warning, and gracefully no-ops on a missing file. Wired into `mud/world/world_state.py:initialize_world` so the song table is populated at boot — the global "MUSIC:" channel and `play list` previously had nothing to broadcast or display. Tests: `tests/integration/test_music_load_songs.py` (3 cases).
|
|
193
|
+
|
|
194
|
+
### Fixed
|
|
195
|
+
|
|
196
|
+
- `CONST-006` — `advance_level` per-level practice gain now applies `wis_app[get_curr_stat(ch, STAT_WIS)].practice`, mirroring ROM `src/update.c:87`. Previously the gain was a hardcoded `PRACTICES_PER_LEVEL = 2` constant — WIS-3 dunce was getting 2 free practices/level instead of 0; WIS-13 default got 2 instead of 1; WIS-25 sage got 2 instead of 5. New `mud/math/stat_apps.py::WIS_APP` table (verbatim port of `src/const.c:790-817`) and `wis_practice_bonus(ch)` accessor. The level-up message now reflects the actual roll with correct singular/plural pluralisation. Per AGENTS.md "test asserting behavior that contradicts ROM is a bug in the test", five existing tests in `tests/test_advancement.py` and `tests/integration/test_character_advancement.py` that asserted the old constant gain were updated to assert ROM's wis_app formula. Test: `tests/integration/test_advancement_wis_app.py` (26 cases).
|
|
197
|
+
- `CONST-005` — `advance_level` per-level HP gain now follows ROM `src/update.c:74-79` exactly: `UMAX(2, (con_app[get_curr_stat(ch, STAT_CON)].hitp + number_range(class_table[ch->class].hp_min, class_table[ch->class].hp_max)) * 9 / 10)`. Previously used a static `LEVEL_BONUS[ch_class]` dict (`mud/advancement.py:91`) — both the RNG roll and the CON modifier were absent, so a CON-25 character was missing +8 hitp/level and a CON-3 character was missing −2 hitp/level on top of the missing variability. New `mud/math/stat_apps.py::CON_APP` table (verbatim port of `src/const.c:850-878`) and `con_hitp_bonus(ch)` accessor. Mana/move continue to use the legacy `LEVEL_BONUS` path until their respective gaps close. Per AGENTS.md "test asserting behavior that contradicts ROM is a bug in the test", six existing tests in `tests/test_advancement.py` and `tests/integration/test_character_advancement.py` that asserted the old static HP values were updated to seed `rng_mm.number_range` and assert the ROM formula. Test: `tests/integration/test_advancement_con_app.py` (14 cases).
|
|
198
|
+
- `CONST-004` — Armor class now augments `armor[type]` with `dex_app[get_curr_stat(ch, STAT_DEX)].defensive` when the character `IS_AWAKE` (`position > POS_SLEEPING`), mirroring ROM `src/merc.h:2104-2106`. New `mud/math/stat_apps.py::DEX_APP` table (verbatim from `src/const.c:821-848`) and `get_ac(ch, ac_type)` accessor; combat at `mud/combat/engine.py:391`, `do_score` at `mud/commands/session.py`, and the wiz `stat char` AC line at `mud/commands/imm_search.py` all read through it. Sleeping/stunned/incap/dead victims still show raw armor (the IS_AWAKE gate). Before this fix, a DEX-3 character was missing +40 AC penalty and a DEX-25 character was missing −120 AC bonus on every combat hit-roll and every AC display. Test: `tests/integration/test_combat_dex_app.py` (11 cases).
|
|
199
|
+
- `CONST-003` — Combat `GET_DAMROLL` now augments `ch->damroll` with `str_app[get_curr_stat(ch, STAT_STR)].todam`, mirroring ROM `src/merc.h:2109-2110` (consumed at `src/fight.c:588` for weapon damage). New `mud/math/stat_apps.py::get_damroll(ch)` accessor; `calculate_weapon_damage` at `mud/combat/engine.py:1189` now reads it. Before this fix, a STR-3 attacker missed −1 damage and a STR-25 attacker missed +9 damage. Test: `tests/integration/test_combat_str_app.py::test_get_damroll_*` (7 cases).
|
|
200
|
+
- `CONST-002` — Combat `GET_HITROLL` now augments `ch->hitroll` with `str_app[get_curr_stat(ch, STAT_STR)].tohit`, mirroring ROM `src/merc.h:2107-2108` (consumed at `src/fight.c:471` for THAC0). New module `mud/math/stat_apps.py` ports `STR_APP[26]` verbatim from `src/const.c:728-755` and exposes `get_hitroll(ch)`; both attack paths in `mud/combat/engine.py` (THAC0 at L411, percent fallback at L420) now read the augmented value. Before this fix, a STR-3 attacker missed −3 to-hit and a STR-25 attacker missed +6. Test: `tests/integration/test_combat_str_app.py` (8 cases).
|
|
201
|
+
- `MUSIC-004` — `mud/commands/player_info.py:do_play` jukebox scan now applies `mud.world.vision.can_see_object(ch, obj)` so invisible / VIS_DEATH / dark-room jukeboxes drop out of selection, mirroring ROM `src/music.c:229-232`'s `can_see_obj(ch, juke)` filter. Test: `tests/integration/test_music_play.py::test_do_play_skips_invisible_jukebox`.
|
|
202
|
+
|
|
203
|
+
- `MUSIC-003` — `play list` in `mud/commands/player_info.py:do_play` now reads `mud.music.song_table` (previously `mud.registry.song_table`, which doesn't exist, so it always fell through to a 3-song hardcoded stub). Reproduces ROM `src/music.c:246-292`: capitalized `"<short_descr> has the following songs available:"` header, `play list <prefix>` filters song names by case-insensitive prefix in two `%-35s` columns, `play list artist [<prefix>]` filters by group name in single-line `%-39s %-39s` group/name pairs, and a trailing odd column is flushed on its own line. Tests: `tests/integration/test_music_play.py` (4 new list-formatting cases).
|
|
204
|
+
|
|
205
|
+
- `MUSIC-001` — `mud/commands/player_info.py:do_play` now ports the queueing half of ROM `src/music.c:220-354`. Previously a stub: it found a jukebox, returned `"Coming right up."`, and queued nothing — so `song_update()` had nothing to broadcast and `play loud` was silently ignored. The port now resolves the `loud` keyword for global plays, enforces the `value[4] > -1` / `channel_songs[MAX_GLOBAL] > -1` queue-full check (`"The jukebox is full up right now."`), case-insensitive name-prefix matches against `mud.music.song_table`, surfaces `"That song isn't available."` on no match, and writes the song id into the first free `juke.value[1..4]` (local) or `channel_songs[1..MAX_GLOBAL]` (global) slot — also resetting the slot-0 line cursor to `-1` when slot 1 is filled, matching ROM `src/music.c:337-352`. Tests: `tests/integration/test_music_play.py` (7 cases).
|
|
206
|
+
|
|
207
|
+
- `NANNY-008` — `broadcast_entry_to_room` (`mud/net/connection.py`) now moves `char.pet` into the owner's room via `char_to_room` and emits a TO_ROOM "$n has entered the game." for the pet on login, mirroring ROM `src/nanny.c:810-815`. Previously a returning player's pet stayed un-roomed and onlookers never saw the pet's arrival. Test: `tests/integration/test_nanny_login_parity.py::test_login_pet_follows_owner_into_room`.
|
|
208
|
+
- `COMM-009` — Standalone `mud/utils/fix_sex.py:fix_sex(ch)` helper added, mirroring ROM `src/comm.c:2178-2182`: clamps `ch.sex` to `[0,2]`, falling back to `pcdata.true_sex` for PCs and `0` for NPCs. Inline clamp at the affect-strip site in `mud/handler.py:1110-1112` now delegates to the helper. Test: `tests/test_fix_sex.py` (5 cases).
|
|
209
|
+
- `COMM-008` — ANSI translator now covers ROM `colour()` specials at `src/comm.c:2714-2728`: `{D` → `\x1b[1;30m`, `{*` → `\x07` (bell), `{/` → `\n\r`, `{-` → `~`, `{{` → `{`. `mud/net/ansi.py` rewritten as a single-pass `re.sub` so `{{` cannot be re-matched as `{h` once partially consumed; `strip_ansi` mirrors ROM `send_to_char` non-colour branch (`src/comm.c:1995-2007`) by eating both characters of any `{X` pair. Tests: `tests/test_ansi.py::test_translate_ansi_handles_rom_specials` and `::test_strip_ansi_eats_rom_token_pairs`.
|
|
210
|
+
- `COMM-007` — `_stop_idling` now broadcasts the ROM "$n has returned from the void." message through `mud/utils/act.py:act_format`, mirroring ROM `act(...)` at `src/comm.c:1922`. The previous literal `f"{name} has returned from the void."` fallback rendered "Someone has returned…" for entities without a `name`; with the new act_format pipeline, `$n` expands via `_pers` (name → short_descr fallback). Test: `tests/test_networking_telnet.py::test_stop_idling_broadcast_uses_rom_act_format`.
|
|
211
|
+
- `COMM-002` — `show_string` pager input semantics now match ROM. While paging, `_read_player_command` (`mud/net/connection.py`) used to treat `"c"` as continue and dispatch arbitrary non-empty input to `interpret()`. ROM `src/comm.c:632-633` instead routes input to `show_string` instead of `interpret`, and `show_string` at `src/comm.c:2131-2141` aborts on any non-empty input and consumes it as no-op. Fix: empty input continues paging; any non-empty input clears the pager and returns `" "` (no-op). The bulk paging machinery (`Session.start_paging` / `send_next_page`) was already wired through `mud/net/protocol.py:send_to_char`; this closure pinned the missing ROM-faithful abort semantics. Tests: `tests/test_networking_telnet.py::test_show_string_pager_aborts_on_any_non_empty_input_per_rom` (new) and `test_show_string_paginates_output` (updated to assert `" "` no-op consumption).
|
|
212
|
+
- `COMM-006` — `is_valid_character_name` now rejects names matching any clan in `CLAN_TABLE` (case-insensitive), mirroring ROM `src/comm.c:1713-1718`. `rom`/`ROM` and `loner` are both rejected at character creation.
|
|
213
|
+
- `COMM-004` — Character-creation name validator now rejects names that collide with any mob prototype's `player_name` keyword list, mirroring ROM `src/comm.c:1782-1796`. Implemented as a new `mud.account.is_valid_character_name` helper layered on top of `is_valid_account_name`; the old syntactic-only validator stays intact for account-name validation (a Python addition with no ROM analogue). `create_character` and the connection-layer character-creation flow both use the new validator. Pre-existing tests in `tests/test_account_auth.py` that used stock RPG names colliding with real mobs (`Zeus`, `Nomad`, `Queen`, `Guardian`) were renamed to invented tokens — per AGENTS.md "test contradicting ROM C is a bug in the test."
|
|
214
|
+
- `COMM-003` — `check_parse_name` length floor now matches ROM. `is_valid_account_name` rejected names shorter than 3 characters; ROM `src/comm.c:1729` rejects only names shorter than 2. Two-letter ROM-legal names (e.g. `Bo`) are now accepted. The previous NANNY-012 test (`test_name_validator_matches_rom_check_parse_name`) had locked in the buggy `< 3` threshold with a docstring misreading ROM — the test now asserts the correct ROM `< 2` bound (`Bo` accepted, `a` rejected).
|
|
215
|
+
- `COMM-001` — Player prompts now render character state. The telnet game loop previously emitted a literal `"> "` regardless of `do_prompt` settings; HP / mana / move / room / alignment never reached the client. Fix: replaced the hard-coded `send_prompt("> ")` with `send_prompt(bust_a_prompt(char))` at `mud/net/connection.py:1698,1923` and made `do_prompt` write to `Character.prompt` (mirrors ROM `ch->prompt`, `src/act_info.c:951-952`) instead of `PCData.prompt` (which in ROM is the colour triplet, not the format string). `send_prompt` now applies ANSI rendering so `{p…{x` colour wrappers don't leak as raw text. Five existing tests in `test_player_prompt.py` / `test_player_auto_settings.py` / `test_config_commands.py` updated to assert the correct field (per AGENTS.md "test contradicting ROM C is a bug in the test").
|
|
216
|
+
- `BOARD-001` — Five hardcoded ROM boards (General/Ideas/Announce/Bugs/Personal) are now seeded on `load_boards()` with the exact ROM levels, force-types, default recipients, and purge-days from `src/board.c:67-76`. Persisted JSON content is overlaid on top so notes survive a reload but the static metadata cannot drift below ROM defaults.
|
|
217
|
+
- `BOARD-002` / `BOARD-003` — `note write` and `note send` now emit ROM TO_ROOM `act()` broadcasts ("$n starts writing a note." / "$n finishes $s note.") via `char.room.broadcast(..., exclude=char)`, mirroring `src/board.c:503` and `src/board.c:1181`. Adds `_possessive(char)` helper for ROM `$s` (his/her/its from `Character.sex`).
|
|
218
|
+
- `BOARD-004` — `Board.post` now routes through a new `mud.notes.next_note_stamp(base)` helper backed by a module-level `_last_note_stamp` counter, mirroring ROM `finish_note` (`src/board.c:154-160`). Two notes posted in the same wall-clock second now get distinct, monotonically increasing timestamps so the `> last_read` unread cursor cannot collide. Test fixtures reset the counter per test (parallel to ROM rebooting `boot_db` globals).
|
|
219
|
+
- `BOARD-005` (and `BOARD-006`) — `Board.unread_count_for(char, last_read)` mirrors ROM `unread_notes` (`src/board.c:444-460`) by filtering through `mud.notes.is_note_to(char, note)` (the canonical recipient predicate, factored out of `mud/commands/notes.py`). `do_board` listing now uses the recipient-aware count, so Personal/per-name notes no longer leak into non-recipients' unread totals. `BOARD-006` is subsumed by this fix (ROM's listing filter `unread_notes != BOARD_NOACCESS` is now consistent with what each row displays).
|
|
220
|
+
- `BOARD-008` — `load_boards` now sweeps every loaded board for notes whose `expire < now` and appends them to `<board>.old.json` before re-saving the active board, mirroring ROM `load_board`'s archive at `src/board.c:365-383`. Boards no longer grow without bound across reloads.
|
|
221
|
+
- `BOARD-012` — `do_note` now mirrors ROM `src/board.c:736-737`: an unknown subcommand (anything other than `read`/`list`/`write`/`remove`/`purge`/`archive`/`catchup` and the Python-only draft verbs) dispatches to `do_help(ch, "note")` instead of returning the generic `"Huh?"`. Test: `tests/integration/test_boards_rom_parity.py::test_note_unknown_subcommand_shows_help`.
|
|
222
|
+
- `BOARD-011` — `note write` now mirrors ROM `do_nwrite` at `src/board.c:482-488`: when the player has an in-progress draft whose `text` is empty (e.g. lost link before typing the body), the stale draft is discarded and the actor sees the ROM cancellation notice ("Note in progress cancelled because you did not manage to write any text before losing link.") before a fresh draft is started. Test: `tests/integration/test_boards_rom_parity.py::test_note_write_discards_textless_in_progress_draft`.
|
|
223
|
+
- `BOARD-013` — Added `mud.notes.make_note(board_name, sender, to, subject, expire_days, text)` and `mud.notes.personal_message(...)` mirroring ROM `make_note` / `personal_message` at `src/board.c:843-886`. Unknown boards and text exceeding `MAX_NOTE_TEXT` (= `4 * MAX_STRING_LENGTH - 1000` = 17432, per `src/board.h:19`) return `None` (mirroring ROM's silent `bug` + return); on success the note is appended via `Board.post` (so it picks up the unique `last_note_stamp` cursor), persisted with `save_board`, and `expire = current_time + expire_days * 86400`. Unblocks programmatic Personal-board injection for death notifications and system mail.
|
|
224
|
+
|
|
225
|
+
- `TABLES-001` — `AffectFlag` bit positions (`mud/models/constants.py`) renumbered to match ROM `src/merc.h:953-982` exactly (letters A..dd → bits 0..29). Closes a 20-of-29-bit divergence where `convert_flags_from_letters` was decoding ROM area-file letters with the canonical mapping (e.g. `G` → bit 6) but Python `AffectFlag.SANCTUARY` sat on bit 6, so any letter-form area data was silently mis-aligned with the enum. Pfile schema gains `pfile_version: int` (default `0`); legacy saves are translated on load by `mud/persistence.py:translate_legacy_affect_bits` (covers character `affected_by`, every nested `Affect.bitvector` on persisted items, pet `affected_by`, and pet affect bitvectors), then re-saved at `pfile_version=1`. Reproducer `tests/integration/test_tables_parity.py::test_affect_flag_letters_match_rom_merc_h` flipped from `xfail(strict)` → green; `test_merc_h_letter_macros_match_python_intflag_values` now also covers `AFF_*`. New migration tests in `tests/integration/test_tables_001_affect_migration.py`. Tables.c flips ⚠️ Partial 75% → ✅ AUDITED 100%.
|
|
226
|
+
- `TABLES-003` — Programmatic verification of every `src/merc.h` letter-mapped `#define` macro against the matching Python `IntFlag` member's bit value. New test `tests/integration/test_tables_parity.py::test_merc_h_letter_macros_match_python_intflag_values` parses merc.h, resolves A..Z / aa..dd letter tokens, and cross-checks ~210 macros across the `ACT_/PLR_/OFF_/IMM_/RES_/VULN_/FORM_/PART_/COMM_/ROOM_/GATE_/FURN_/WEAPON_` prefixes. Confirms only `AFF_*` (TABLES-001) diverges; all other letter-mapped tables in `src/tables.c` have correct Python bit positions. Acts as a durable regression guard.
|
|
227
|
+
- `TABLES-002` — `mud/utils/prefix_lookup.py:prefix_lookup_intflag` now consults a ROM `src/tables.c` table-name alias map (`rom_flag_aliases`) before falling back to Python IntFlag member names. ROM-style abbreviations like `+npc`/`+healer`/`+changer`/`+can_loot`/`+dirt_kick`/`+noclangossip` now resolve to the matching Python flag member (`IS_NPC`/`IS_HEALER`/`IS_CHANGER`/`CANLOOT`/`KICK_DIRT`/`NOAUCTION`), restoring ROM `flag_lookup` parity for `do_flag` and OLC.
|
|
228
|
+
|
|
229
|
+
### Added
|
|
230
|
+
|
|
231
|
+
- `tables.c` parity audit (`docs/parity/TABLES_C_AUDIT.md`): Phase 1 inventory of all 38 ROM data tables in `src/tables.c` mapped to Python `IntFlag`/`IntEnum` equivalents in `mud/models/constants.py`; Phase 2 spot-checks confirm `ActFlag` / `PlayerFlag` / `OffFlag` / `CommFlag` bit positions match ROM letters A..dd. Three gaps documented: **TABLES-001 (CRITICAL)** — `AffectFlag` bit positions diverge from ROM `merc.h:953-982` (e.g. `AFF_DETECT_GOOD=G=1<<6` in ROM, but `AffectFlag.SANCTUARY=1<<6` in Python); `convert_flags_from_letters` decodes ROM letters with the ROM-correct mapping, so any area-file `AFF G` is silently mis-decoded as `SANCTUARY`. Closure deferred — requires `AffectFlag` renumber + persistence migration plan. TABLES-002 (ROM-name aliases for prefix-match) and TABLES-003 (per-table value verification for the remaining 30+ tables) also open. New `tests/integration/test_tables_parity.py` (4 passing spot-checks + 1 xfail reproducer for TABLES-001).
|
|
232
|
+
|
|
233
|
+
### Fixed
|
|
234
|
+
|
|
235
|
+
- `LOOKUP-008` — Added public `liq_lookup(name)` to `mud/utils/prefix_lookup.py` mirroring ROM `src/lookup.c:138-150` (case-insensitive prefix-match against `LIQUID_TABLE`, returns `-1` on miss). The loader-internal `mud/loaders/obj_loader.py:_liq_lookup` is retained because it intentionally returns `0` (water) on miss for object-load defaults. With this `lookup.c` is ✅ AUDITED at 100% (LOOKUP-001..008 all closed).
|
|
236
|
+
- `LOOKUP-007` — Added `item_lookup(name)` to `mud/utils/prefix_lookup.py` mirroring ROM `src/lookup.c:124-136` (case-insensitive prefix-match against `ItemType` IntEnum, returns the ITEM_X type value, `-1` on miss). Python's `ItemType` IntEnum values match ROM ITEM_X constants 1:1.
|
|
237
|
+
- `LOOKUP-006` — Added `size_lookup(name)` to `mud/utils/prefix_lookup.py` mirroring ROM `src/lookup.c:95-107` (case-insensitive prefix-match against `Size` IntEnum, returns `-1` on miss).
|
|
238
|
+
- `LOOKUP-005` — Added `sex_lookup(name)` to `mud/utils/prefix_lookup.py` mirroring ROM `src/lookup.c:81-93` (case-insensitive prefix-match against `Sex` IntEnum, returns `-1` on miss). ROM `sex_table {none, male, female, either}` maps 1:1 to Python's enum.
|
|
239
|
+
- `LOOKUP-004` — Added `position_lookup(name)` to `mud/utils/prefix_lookup.py` mirroring ROM `src/lookup.c:67-79` (case-insensitive prefix-match against `Position` IntEnum, returns `-1` on miss).
|
|
240
|
+
- `LOOKUP-003` — `lookup_clan_id` (`mud/models/clans.py`) now uses ROM-faithful prefix-match instead of exact-match. `lookup_clan_id("lo")` returns clan `loner`, `lookup_clan_id("ro")` returns clan `rom`, mirroring ROM `src/lookup.c:53-65` (`clan_lookup` calls `str_prefix`).
|
|
241
|
+
- `LOOKUP-002` — `_lookup_flag_bit` (`mud/commands/remaining_rom.py`) now uses ROM-faithful prefix-match instead of exact-match. `flag char Bob plr +holy` matches `HOLYLIGHT` per ROM `src/lookup.c:39-51` (`flag_lookup` calls `str_prefix`). Introduces `mud/utils/prefix_lookup.py` with shared `prefix_lookup_index` and `prefix_lookup_intflag` helpers for the remaining LOOKUP-003..008 closures.
|
|
242
|
+
- `LOOKUP-001` — Added `race_lookup(name: str | None) -> int` to `mud/models/races.py` mirroring ROM `src/lookup.c:110-122` (case-insensitive prefix-match against `RACE_TABLE`, fall-through `return 0`). Fixes a latent `ImportError` in `mud/persistence.py:614`'s pet-restore path: every pet load with a non-None race snapshot was crashing with `ImportError: cannot import name 'race_lookup'` because the function had not been ported. Caught during the `lookup.c` parity audit.
|
|
243
|
+
- `FLAG-001` — `do_flag` (`mud/commands/remaining_rom.py`) is now a fully-wired immortal command instead of a syntax-validator stub. Mirrors ROM `src/flags.c:44-251`: parses the `=`/`+`/`-`/toggle operator, dispatches `act`/`plr`/`aff`/`immunity`/`resist`/`vuln`/`form`/`parts`/`comm` to the matching Character attribute and IntFlag enum (`ActFlag`, `PlayerFlag`, `AffectFlag`, `ImmFlag`, `FormFlag`, `PartFlag`, `CommFlag`), enforces NPC-only / PC-only field guards (`Use 'plr' for PCs.`, `Use 'act' for NPCs.`, `Form/Parts can't be set on PCs.`, `Comm can't be set on NPCs.`), looks up flag names case-insensitively, rejects unknown flags with `That flag doesn't exist!`, and mutates the matching bit on the victim. Previously the command returned a confirmation string but performed no mutation. New 9-test integration suite in `tests/integration/test_flag_command_parity.py`. FLAG-002 (preserve ROM `flag_type.settable=FALSE` bits across the `=` operator) deferred as MINOR — requires per-bit settable metadata on the IntFlag enums.
|
|
244
|
+
|
|
245
|
+
### Changed
|
|
246
|
+
|
|
247
|
+
- `sha256.c` audit completed (`docs/parity/SHA256_C_AUDIT.md`). SHA-256 primitive is delegated to Python's stdlib `hashlib` (byte-for-byte equivalent to ROM `src/sha256.c:131-318`). The `sha256_crypt` password hash (ROM `src/sha256.c:320-336`, plain unsalted single-round SHA-256) is replaced by PBKDF2-HMAC-SHA256 with a 16-byte random salt and 100 000 rounds in `mud/security/hash_utils.py` — a deliberate security upgrade with no observable gameplay parity surface (no pfile compatibility goal). Tracker row flipped from ⚠️ Partial → ✅ AUDITED.
|
|
248
|
+
|
|
249
|
+
### Fixed
|
|
250
|
+
|
|
251
|
+
- `NANNY-012` — Name validator (`is_valid_account_name` in `mud/account/account_service.py`) now matches ROM `check_parse_name` (`src/comm.c`, called from `nanny.c:188`): minimum length raised from 2 to 3 chars, and `god` / `imp` added to the reserved-name set. Existing reserved tokens (`all auto immortal self someone something the you loner none`) are unchanged.
|
|
252
|
+
- `NANNY-013` — Audit correction: ROM `hit=max_hit; mana=max_mana; move=max_move` (src/nanny.c:772-775) is already covered by `from_orm` initialising `max_*` from `perm_*` plus `hit` from saved `hp` (a fresh character is persisted with `hp=perm_hit=100`). NANNY-014 reset_char further guarantees max_* are restored on every login. Added regression test.
|
|
253
|
+
- `NANNY-006` — Login fallback room now distinguishes immortals from mortals when no saved room can be loaded. Added `ROOM_VNUM_CHAT = 1200` constant (ROM `src/merc.h:1250`) and `default_login_room_vnum(char)` helper in `mud/net/connection.py`; an `is_admin` character with `char.room is None` lands in ROOM_VNUM_CHAT (the immortal chat room), mortals in ROOM_VNUM_TEMPLE. Mirrors ROM `src/nanny.c:791-802` `IS_IMMORTAL ? ROOM_VNUM_CHAT : ROOM_VNUM_TEMPLE`.
|
|
254
|
+
- `NANNY-001` — Account login now disconnects on the first wrong password (returns `None` from `_run_account_login`) instead of looping back to the Account prompt, mirroring ROM `src/nanny.c:269-274` (`close_socket(d)` on bad password). The same path applies to reconnect attempts (matching ROM's "one chance" rule for both fresh logins and CON_BREAK_CONNECT).
|
|
255
|
+
- `NANNY-005` — Audit correction: ROM `perm_stat[class.attr_prime] += 3` (src/nanny.c:769) was already implemented in `mud/account/account_service.py:finalize_creation_stats` and locked in by `tests/test_nanny_rom_parity.py::test_prime_attribute_bonus_formula`. ROM applies the bonus during the `level == 0 → 1` promotion inside `CON_READ_MOTD`; Python applies it equivalently during `create_character` since Python characters are persisted at level 1.
|
|
256
|
+
- `NANNY-004` — Audit correction: ROM `learned[weapon_gsn] = 40` (src/nanny.c:653) was already implemented in `mud/models/character.py:from_orm` (lines 1047-1051), which uses `_STARTING_WEAPON_SKILL_BY_VNUM` to seed the picked weapon's skill to ≥40 on every load. Audit had cited the prompt-time path. Added regression test.
|
|
257
|
+
- `NANNY-003` — Audit correction: ROM `learned[gsn_recall] = 50` (src/nanny.c:581) was already implemented in `mud/models/character.py:from_orm` (lines 1052-1053), which clamps `learned["recall"]` to ≥50 on every character load. Audit had cited the wrong source location. Added regression test to lock in the behavior.
|
|
258
|
+
- `NANNY-002` — Login flow now honors the `PlayerFlag.DENY` bit per ROM `src/nanny.c:197-205`: a denied character logs `Denying access to <name>@<host>.`, receives `You are denied access.`, and is rejected before reaching the game loop. New `is_character_denied_access` helper in `mud/net/connection.py`, wired into both load branches of `_select_character`.
|
|
259
|
+
- `NANNY-007` — Login flow now broadcasts `<Name> has entered the game.` to other room occupants on every fresh (non-reconnect) login, mirroring ROM `act("$n has entered the game.", ch, NULL, NULL, TO_ROOM)` at `src/nanny.c:804`. New `broadcast_entry_to_room` helper in `mud/net/connection.py` excludes the actor and uses `act_format` for `$n` substitution.
|
|
260
|
+
- `BAN-004` — `BanEntry.matches` (`mud/security/bans.py`) no longer falls through to exact-string match when neither PREFIX nor SUFFIX bit is set; ROM `src/ban.c:104-132` `check_ban` silently skips such entries. Pre-existing tests in `tests/test_bans.py` and `tests/test_account_auth.py` were updated to use `*host*` patterns so a host-specific ban actually matches under ROM semantics.
|
|
261
|
+
- `BAN-003` — `_apply_ban` (`mud/commands/admin_commands.py`) now accepts ROM-style prefix abbreviations of the type token (`a`, `n`, `p`, `al`, `ne`, …), matching `src/ban.c:180-191` `!str_prefix(arg2, "all"/"newbies"/"permit")`. Previously required full-prefix `startswith` so single-letter abbreviations were rejected.
|
|
262
|
+
- `BAN-002` — `_render_ban_listing` now mirrors ROM's chained ternary at `src/ban.c:166-168`: prints `"newbies"` / `"permit"` / `"all"` based on the corresponding flag bits and falls through to `""` when none is set. Previously defaulted to `"all"` in the no-flag case.
|
|
263
|
+
- `BAN-001` — `_render_ban_listing` (`mud/commands/admin_commands.py`) now left-aligns the level column (`:<3d`) to match ROM `src/ban.c:164` `%-3d` instead of right-aligning. Visible in `banlist` / `ban` (no-arg) output.
|
|
264
|
+
- `NANNY-011` — `_prompt_new_password` (`mud/net/connection.py`) now rejects passwords containing `~` with ROM message "New password not acceptable, try again." mirroring ROM `src/nanny.c:396-405` file-format poisoner check. Python uses a DB backend so the practical risk is gone, but parity with ROM input validation is preserved.
|
|
265
|
+
- `NANNY-014` — Login flow now invokes `reset_char(ch)` on every successful login (ROM `src/nanny.c:760`), restoring `max_hit`/`max_mana`/`max_move` from `pcdata.perm_*`, zeroing transient `mod_stat[]`/`hitroll`/`damroll`/`saving_throw`, and re-applying equipment affects so returning characters land with clean state. Wired into both branches of `mud/net/connection.py:handle_connection` via new `apply_login_state_refresh` helper. Also corrected a latent bug in `mud/handler.py:reset_char` where `range(int(WearLocation.MAX))` raised `AttributeError` (the enum has no `MAX` member); replaced with literal `19` matching ROM `MAX_WEAR` (`src/merc.h:1356`).
|
|
266
|
+
- `SPEC-001` — `spec_executioner` yell now broadcasts area-wide (ROM `src/special.c:890-893`) instead of room-only. Added `_yell_area` helper mirroring ROM `do_yell`.
|
|
267
|
+
- `SPEC-002` — `spec_guard` now checks ALL room occupants for evil-alignment combatants (ROM `src/special.c:948-972`), not just PCs. The fallback path targeting `alignment < max_evil` fighters now works for NPCs too.
|
|
268
|
+
- `SPEC-003` — `spec_mayor` gate open/close now emits proper TO_CHAR (`You open the gate.`) and TO_ROOM (`Mayor opens gate.`) messages, plus reverse-exit toggle. Mirrors ROM `do_function(ch, &do_open, "gate")` / `do_function(ch, &do_close, "gate")`.
|
|
269
|
+
- `SPEC-004` — `spec_thief` gold/silver division now uses `c_div` (C integer division) instead of Python `//`, matching ROM `src/special.c:1174-1186`.
|
|
270
|
+
- `SPEC-005` — `spec_nasty` ambush now calls `do_murder` (which sets PLR_KILLER flag) instead of `do_kill`, matching ROM `src/special.c:368-371`. Updated `_issue_command` to search multiple command modules.
|
|
271
|
+
- `SPEC-006` — `spec_troll_member` and `spec_ogre_member` now check `is_safe()` before attacking, matching ROM `src/special.c:145,213`. Prevents attacks in safe rooms.
|
|
272
|
+
- `SPEC-008` — `spec_mayor` movement now uses `move_character()` (with fallback for test SimpleNamespace objects), matching ROM `move_char(ch, dir, FALSE)`.
|
|
273
|
+
- `SPEC-012` — `spec_nasty` gold steal now uses `c_div(gold_before, 10)` instead of `gold_before // 10`, matching ROM `src/special.c:394-396`.
|
|
274
|
+
|
|
275
|
+
- `WIZ-001` — `goto`, `at`, and `transfer` now mirror ROM `src/act_wiz.c:821-839,897-905,957-966` owner/private-room gating by honoring owner-locked rooms, the canonical `ROOM_SOLITARY` flag value, and `is_room_owner()` bypass semantics.
|
|
276
|
+
- `WIZ-002` — `violate` now mirrors ROM `src/act_wiz.c:1000-1057`: it targets rooms through `find_location()`, rejects public rooms with the `use goto` hint, and no longer parses directions/exits.
|
|
277
|
+
- `WIZ-003` — `protect` now mirrors ROM `src/act_wiz.c:2086-2118` lookup/messages and toggles the real `CommFlag.SNOOP_PROOF` bit instead of the old `COMM_NOTELL` value.
|
|
278
|
+
- `WIZ-004` — `snoop` now honors the canonical `CommFlag.SNOOP_PROOF` bit from ROM `src/act_wiz.c:2167-2174`, preventing snooping of correctly protected targets.
|
|
279
|
+
- `WIZ-006` — `log` command now mirrors ROM `src/act_wiz.c:2927-2984`: uses `get_char_world()` for lookup, toggles `PlayerFlag.LOG` on `victim.act` instead of a `log_commands` bool, rejects NPCs with ROM message, and uses canonical `\n\r` line endings.
|
|
280
|
+
- `WIZ-007` — `force` command now mirrors ROM `src/act_wiz.c:4183-4322`: adds `gods` branch for hero+ players, adds private-room check before forcing individuals, applies trust check to all victims (not just non-NPCs), iterates `descriptor_list` for `force all` and `char_list` for `force players`/`force gods`, and uses canonical `\n\r` line endings.
|
|
281
|
+
- `WIZ-005` — `stat` family now mirrors ROM `src/act_wiz.c:1059-1742`: `do_stat` dispatcher uses `get_char_world`/`get_obj_world`/`find_location` per ROM; `do_rstat` outputs Name/Area/Vnum/Sector/Light/Healing/Mana/Room flags/Description/Extra descs/Characters/Objects/Door details; `do_ostat` outputs Name(s)/Vnum/Format/Type/Resets/Short+Long descr/Wear bits/Extra bits/Number+Weight/Level+Cost+Condition+Timer/In room+In obj+Carried by+Wear_loc/Values/Item-type blocks (scroll, potion, pill, wand, staff, drink_con, weapon, armor, container)/Extra descs/Affects; `do_mstat` outputs Name/Vnum/Format/Race/Group/Sex/Room/Count+Killed/Stats/Hp+Mana+Move+Practices/Level+Class+Align+Gold+Silver+Exp/AC per type/Hit+Dam+Saves+Size+Position+Wimpy/Damage+Fighting/Thirst+Hunger+Full+Drunk for PCs/Carry number+Weight/Age+Played/Act/Comm/Offense/Immune/Resist/Vulnerable/Form+Parts/Affected by/Master+Leader+Pet/Security/Short+Long desc/Spec fun/Affected. Added 8 ROM-faithful bit-name helpers (`wear_bit_name`, `extra_bit_name`, `imm_bit_name`, `off_bit_name`, `form_bit_name`, `part_bit_name`, `weapon_bit_name`, `cont_bit_name`) and 5 display helpers (`size_name`, `position_name`, `sex_name`, `class_name`, `race_name`) to `mud/handler.py`.
|
|
282
|
+
- `WIZ-008` — Punish commands (`nochannels`, `noemote`, `noshout`, `notell`, `freeze`, `pardon`) now use canonical `CommFlag`/`PlayerFlag` enum values instead of hardcoded wrong bit positions that were corrupting unrelated flags. Added `wiznet()` broadcasts with `WIZ_PENALTIES` + `WIZ_SECURE` flags. Added `\n\r` line endings.
|
|
283
|
+
- `WIZ-009` — `peace` now calls `stop_fighting(person, True)` instead of setting `fighting = None` (properly clearing all combat references). Uses `ActFlag.AGGRESSIVE` enum instead of hardcoded `0x20`. Added `\n\r` line endings.
|
|
284
|
+
- `WIZ-010` — `invis` and `incognito` now broadcast room-wide `act()` messages per ROM `src/act_wiz.c:4329-4420`. `incognito` clears `reply` when setting a specific level. Added `\n\r` line endings.
|
|
285
|
+
- `WIZ-011` — Echo family (`echo`, `recho`, `zecho`, `pecho`) now iterates `descriptor_list` with `CON_PLAYING` filter per ROM `src/act_wiz.c:674-777` instead of `registry.players` dict. `pecho` uses ROM trust check and exact messages. Added `\n\r` line endings.
|
|
286
|
+
- `WIZ-012` — `bamfin`/`bamfout` now use `smash_tilde()` and ROM `strstr` case-sensitive name check per `src/act_wiz.c:455-512`. Added `\n\r` line endings.
|
|
287
|
+
- `WIZ-013` — `wizlock`/`newlock` now use `\n\r` line endings per ROM `src/act_wiz.c:3150-3188`.
|
|
288
|
+
- `WIZ-014` — `holylight` now returns empty string for NPCs (ROM parity) and uses `\n\r` line endings per `src/act_wiz.c:4422-4439`.
|
|
289
|
+
- `WIZ-015` — `slookup` now supports `all` arg, shows `Slot` column, uses prefix-match lookup per ROM `src/act_wiz.c:3191-3229`. Added `\n\r` line endings.
|
|
290
|
+
- `WIZ-016` — `sockets` now uses `\n\r` line endings per ROM `src/act_wiz.c:4140-4176`.
|
|
291
|
+
- `WIZ-017` — `deny` rewritten to ROM parity per `src/act_wiz.c:517-557`: SET-only (not toggle), uses `get_char_world()` not `character_registry`, adds `PlayerFlag.DENY` flag, wiznet broadcast, `stop_fighting(victim, True)`, forced quit, `\n\r` line endings.
|
|
292
|
+
- `WIZ-018` — `switch` now has private-room check (`is_room_owner`/`room_is_private`) and wiznet broadcast per ROM `src/act_wiz.c:2202-2269`. Added `\n\r` line endings.
|
|
293
|
+
- `WIZ-019` — `return` now has full ROM message, prompt cleanup, and wiznet broadcast per `src/act_wiz.c:2273-2303`. Added `\n\r` line endings.
|
|
294
|
+
- `WIZ-020` — `smote` now uses ROM `_smote_substitute` letter-by-letter algorithm, case-sensitive `strstr` name check, skips no-descriptor viewers per `src/act_wiz.c:362-453`. Added `\n\r` line endings.
|
|
295
|
+
- `WIZ-021` — `pecho` now uses ROM trust check (`get_trust(char) != MAX_LEVEL`) and exact messages per `src/act_wiz.c:750-777`. Added `\n\r` line endings.
|
|
296
|
+
- `WIZ-022` — `disconnect` now follows ROM descriptor-list victim lookup per `src/act_wiz.c:561-614`. Added `\n\r` line endings.
|
|
297
|
+
- `WIZ-023` — `guild` now uses `lookup_clan_id`/`CLAN_TABLE` per ROM `src/act_wiz.c:196-249`; distinguishes independent-clan (`"a <name>"`) vs member-clan (`"member of clan <Name>"`) messaging; uses `str_prefix`-style match for "none"; all messages have `\n\r`.
|
|
298
|
+
- `WIZ-024` — `outfit` now always returns `"You have been equipped by Mota.\n\r"` per ROM `src/act_wiz.c:251-310` (removed "You already have your equipment" branch).
|
|
299
|
+
- `WIZ-025` — `copyover` now iterates `descriptor_list` with `CON_PLAYING` filter per ROM `src/act_wiz.c:4498-4588`; all messages have `\n\r`.
|
|
300
|
+
- `WIZ-026` — `qmconfig` verified as already ROM-faithful per `src/act_wiz.c:4685-4787`; added test coverage for `"I have no clue..."` fallback.
|
|
301
|
+
- `wiznet()` broadcast now iterates `descriptor_list` with `CON_PLAYING` filter per ROM `src/act_wiz.c:171-194`; falls back to `character_registry` in test environments without descriptor setup.
|
|
302
|
+
- `WIZ-027` — `load` syntax messages now have `\n\r` line endings per ROM; re-invokes `do_load("")` on invalid type.
|
|
303
|
+
- `WIZ-028` — `mload` now returns `"Ok.\n\r"` instead of `"You have created {name}!"` per ROM `src/act_wiz.c:2489-2517`; added `wiznet()` broadcast; safe `getattr` for registry.
|
|
304
|
+
- `WIZ-029` — `oload` now returns `"Ok.\n\r"` instead of `"You have created {name}!"` per ROM `src/act_wiz.c:2521-2570`; added `wiznet()` broadcast; ROM typo preserved in level message; fixed `char.inventory` slot name.
|
|
305
|
+
- `WIZ-030` — `purge` trust check now uses ROM `<=` comparison per `src/act_wiz.c:2625`; added `"X tried to purge you!\n\r"` notification to victim; all messages have `\n\r`.
|
|
306
|
+
- `WIZ-031` — `restore` iterates `descriptor_list` for `restore all` per ROM `src/act_wiz.c:2820-2845`; added wiznet broadcasts; all messages have `\n\r`.
|
|
307
|
+
- `WIZ-032` — `clone` now has wiznet broadcasts per ROM `src/act_wiz.c:2338-2455`; added trust check for mob cloning; uses `obj.carried_by` to determine placement; all messages have `\n\r`.
|
|
308
|
+
- `WIZ-033` — `set` command now uses `\n\r` line endings and re-invokes `do_set("")` on invalid type per ROM `src/act_wiz.c:3233-3275`.
|
|
309
|
+
- `WIZ-034` — `sset` now uses `getattr(registry, "skill_table", [])` iteration; added `(use the name of the skill, not the number)` hint; all messages have `\n\r` per ROM `src/act_wiz.c:3278-3352`.
|
|
310
|
+
- `WIZ-035` — `mset` now fully ROM-parity per `src/act_wiz.c:3355-3790`: uses `smash_tilde()`; uses `get_max_train()` for stat ranges; `level` rejects PCs; `sex` sets `pcdata.true_sex`; `hp`/`mana`/`move` set PC `perm_*` values; uses ROM field name prefixes (`startswith()`); adds fields: `class`, `race`, `group`, `hours`, `thirst`, `drunk`, `full`, `hunger`; `security` uses `ch->pcdata->security` range; clears `victim.zone`; re-invokes `do_mset("")` on unknown field; all messages have `\n\r`.
|
|
311
|
+
- `WIZ-036` — `oset` now fully ROM-parity per `src/act_wiz.c:3958-4067`: uses `smash_tilde()`; adds `v0`-`v4` aliases; caps `value0` at `min(50, value)` per ROM:3998; adds `timer` field; uses ROM field prefixes; re-invokes `do_oset("")` on unknown field; all messages have `\n\r`.
|
|
312
|
+
- `WIZ-037` — `rset` now fully ROM-parity per `src/act_wiz.c:4071-4136`: uses `smash_tilde()`; uses `find_location()` for room lookup; adds private-room check (`is_room_owner`/`room_is_private`); adds "Value must be numeric.\n\r" check; uses ROM field prefixes; re-invokes `do_rset("")` on unknown field; all messages have `\n\r`.
|
|
313
|
+
- `WIZ-038` — `string` now fully ROM-parity per `src/act_wiz.c:3793-3954`: uses `smash_tilde()`; adds `spec` field via `get_spec_fun()`; `long` appends `\n\r`; uses `set_title()` for title; uses ROM field prefixes; adds ROM `extra_descr` insertion; re-invokes `do_string("")` on bad type; all messages have `\n\r`.
|
|
314
|
+
- `ALIAS-001` — `alia` now returns the ROM `src/alias.c:97-100` typo-guard text instead of a generic helper string.
|
|
315
|
+
- `ALIAS-002` — `alias` now mirrors ROM `src/alias.c:112-220`: exact list/query/set/realias messages, reserved-word checks, quote/name validation, `delete`/`prefix` expansion guards, and the five-alias limit.
|
|
316
|
+
- `ALIAS-003` — alias substitution now mirrors ROM `src/alias.c:69-99`: one expansion pass only, truncation warning handling, and `mud.rom_api.substitute_alias()` now returns the expanded string instead of an internal tuple.
|
|
317
|
+
- `ALIAS-004` — `unalias` now mirrors ROM `src/alias.c:236-274` prompt/removal/failure messages.
|
|
318
|
+
- `ALIAS-005` — prefix preprocessing before alias expansion now mirrors ROM `src/alias.c:49-61,88-95`, including the overlong-line warning and full-`prefix` bypass semantics.
|
|
319
|
+
- `HEALER-001` — `heal` now finds NPC healers via `ACT_IS_HEALER` and shows the ROM `src/healer.c:49-79` service table instead of a compressed summary string.
|
|
320
|
+
- `HEALER-002` — `heal mana` now mirrors ROM `src/healer.c:147-190`: silver-aware affordability, `deduct_cost`, healer payout, TO_ROOM utterance, and `dice(2, 8) + level/3` mana restoration.
|
|
321
|
+
- `HEALER-003` — `heal refresh` now dispatches to the underlying ROM spell path from `src/healer.c:156-160,196` instead of a placeholder full-restore shortcut.
|
|
322
|
+
- `HEALER-004` — `heal heal` now dispatches to the underlying ROM `spell_heal` path from `src/healer.c:107-112,196` instead of always filling hit points to max.
|
|
323
|
+
|
|
324
|
+
## [2.6.15] - 2026-04-28
|
|
325
|
+
|
|
326
|
+
Closes the `scan.c` audit (P2): all 3 gaps fixed, ROM-faithful TO_ROOM/TO_CHAR
|
|
327
|
+
broadcasts on the `scan` command, divergent header and fallback lines removed.
|
|
328
|
+
|
|
329
|
+
### Added
|
|
330
|
+
|
|
331
|
+
- `SCAN-001` — `do_scan` with no argument now emits the TO_ROOM broadcast
|
|
332
|
+
`"$n looks all around."` so onlookers see the scan, mirroring ROM
|
|
333
|
+
`src/scan.c:60` (`act("$n looks all around.", ch, NULL, NULL, TO_ROOM);`).
|
|
334
|
+
- `SCAN-002` — directional `do_scan` now emits the TO_CHAR/TO_ROOM act() pair
|
|
335
|
+
`"You peer intently <dir>."` / `"$n peers intently <dir>."`, mirroring ROM
|
|
336
|
+
`src/scan.c:89-90`.
|
|
337
|
+
|
|
338
|
+
### Fixed
|
|
339
|
+
|
|
340
|
+
- `SCAN-002` — directional `do_scan` no longer prints a spurious
|
|
341
|
+
`"Looking <dir> you see:"` header. ROM builds that string into `buf` at
|
|
342
|
+
`src/scan.c:91` but never calls `send_to_char(buf, ch)`; the only visible
|
|
343
|
+
scanner-facing message is the `"You peer intently <dir>."` act().
|
|
344
|
+
- `SCAN-003` — `do_scan` no longer emits non-ROM fallback lines
|
|
345
|
+
(`"No one is nearby."`, `"Nothing of note."`) when no visible characters
|
|
346
|
+
are found. ROM emits only the act() messages and header in that case
|
|
347
|
+
(`src/scan.c:48-104`).
|
|
348
|
+
|
|
349
|
+
## [2.6.14] - 2026-04-28
|
|
350
|
+
|
|
351
|
+
Closes the `db2.c` audit (P1): all CRITICAL/IMPORTANT mob-loader gaps fixed.
|
|
352
|
+
Both `.are` and JSON loaders now match ROM `src/db2.c:load_mobiles` for AC
|
|
353
|
+
scaling, `ACT_IS_NPC` enforcement, race-table flag merge, and first-char
|
|
354
|
+
uppercase of long_descr/description. Two MINOR gaps (`DB2-004` kill_table,
|
|
355
|
+
`DB2-005` single-line fread_string) remain deferred — both documented as
|
|
356
|
+
not user-reachable in the current port.
|
|
357
|
+
|
|
358
|
+
### Fixed
|
|
359
|
+
|
|
360
|
+
- `DB2-003` — both mob loaders now uppercase the first character of
|
|
361
|
+
`long_descr` and `description` at load time, mirroring ROM
|
|
362
|
+
`src/db2.c:236-237` (`pMobIndex->long_descr[0] = UPPER(...)`).
|
|
363
|
+
Previously mob protos with a lowercase first letter rendered that way in
|
|
364
|
+
room/look output. `.are` loader normalizes after `read_string_tilde`;
|
|
365
|
+
JSON loader normalizes inline at MobIndex construction.
|
|
366
|
+
- `DB2-006` — mob armor-class fields (`ac_pierce`/`ac_bash`/`ac_slash`/`ac_exotic`)
|
|
367
|
+
are now multiplied by 10 at load time in both the `.are` loader
|
|
368
|
+
(`mud/loaders/mob_loader.py`) and the JSON loader (`mud/loaders/json_loader.py`),
|
|
369
|
+
mirroring ROM `src/db2.c:273-276`. Previously every loaded NPC had an AC value
|
|
370
|
+
10× off in ROM's negative-AC convention, making them noticeably easier to hit.
|
|
371
|
+
`mud/scripts/convert_are_to_json.py` now divides back when re-emitting JSON so
|
|
372
|
+
the JSON files stay a faithful mirror of the raw `.are` upstream.
|
|
373
|
+
- `DB2-002` — both mob loaders now merge ROM `race_table[race].{act, aff,
|
|
374
|
+
off, imm, res, vuln, form, parts}` flag bits into each loaded mob's
|
|
375
|
+
letter-based flag fields, mirroring ROM `src/db2.c:239-242,279-286,295-297`.
|
|
376
|
+
Previously race-derived intrinsics (dragon flying, troll regeneration,
|
|
377
|
+
modron immunities, undead form/parts) were silently dropped at load time.
|
|
378
|
+
Implemented in `mud/loaders/mob_loader.py:merge_race_flags`; the JSON
|
|
379
|
+
loader (`mud/loaders/json_loader.py`) invokes it after MobIndex construction.
|
|
380
|
+
- `DB2-001` — both mob loaders now unconditionally OR `ACT_IS_NPC` (letter `A`)
|
|
381
|
+
into every prototype's `act_flags` letter string, mirroring ROM
|
|
382
|
+
`src/db2.c:239`. Previously a mob whose area-file flags omitted the `A`
|
|
383
|
+
letter would spawn with `IS_NPC()` returning false, breaking every
|
|
384
|
+
downstream `is_npc` check (combat, save, look, mobprog dispatch).
|
|
385
|
+
|
|
386
|
+
## [2.6.13] - 2026-04-28
|
|
387
|
+
|
|
388
|
+
Closes the cross-file dependency that blocked `interp.c` completion:
|
|
389
|
+
`WEAR-010` (do_wear dispatches weapons to wield) and `WEAR-011`
|
|
390
|
+
(do_hold auto-replaces) cleared the way for `INTERP-013` to collapse
|
|
391
|
+
`do_wield`/`do_hold` into aliases on `do_wear`, mirroring ROM
|
|
392
|
+
`cmd_table[]`. `interp.c` now closes at **24/24 fixed + 1
|
|
393
|
+
closed-deferred**.
|
|
394
|
+
|
|
395
|
+
### Fixed
|
|
396
|
+
|
|
397
|
+
- `act_obj.c:WEAR-010` — `do_wear` now dispatches `ITEM_WEAPON` items
|
|
398
|
+
to the WIELD branch (`_dispatch_wield`) instead of rejecting with
|
|
399
|
+
"You need to wield weapons, not wear them." Mirrors ROM
|
|
400
|
+
`src/act_obj.c:1401-1697` `wear_obj` single-dispatcher design where
|
|
401
|
+
`do_wear`/`do_wield`/`do_hold` are all the same function. Tests:
|
|
402
|
+
`tests/integration/test_equipment_system.py::test_wear_010_do_wear_dispatches_weapon_to_wield`.
|
|
403
|
+
- `act_obj.c:WEAR-011` — `do_hold` now auto-unequips an existing held
|
|
404
|
+
item via `_unequip_to_inventory()` instead of rejecting with
|
|
405
|
+
"You're already holding {name}." Mirrors ROM
|
|
406
|
+
`src/act_obj.c:1670-1677` `remove_obj(WEAR_HOLD, fReplace=TRUE)`
|
|
407
|
+
semantics. Tests:
|
|
408
|
+
`tests/integration/test_equipment_system.py::test_wear_011_do_hold_auto_replaces_existing_held`.
|
|
409
|
+
- `interp.c:INTERP-013` — `wield` and `hold` now dispatch to `do_wear`
|
|
410
|
+
via the dispatcher's `aliases=("wield", "hold")` on the `wear`
|
|
411
|
+
Command, mirroring ROM `cmd_table[]` (src/interp.c:103, 215, 232).
|
|
412
|
+
`do_wield`/`do_hold` collapsed to thin wrappers around `do_wear`
|
|
413
|
+
for direct-import callers. Closes `interp.c` to **24/24 fixed +
|
|
414
|
+
1 closed-deferred** (100% of closeable gaps). Tests:
|
|
415
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_013_wear_wield_hold_share_do_wear`.
|
|
416
|
+
|
|
417
|
+
### Changed
|
|
418
|
+
|
|
419
|
+
- `wield <non-weapon>` and `hold <non-holdable>` no longer reject with
|
|
420
|
+
command-specific errors ("You can't wield that." / "You can't hold
|
|
421
|
+
that."). They now run the full `do_wear` dispatcher, so
|
|
422
|
+
e.g. `wield ring` wears the ring on a finger — ROM-faithful since
|
|
423
|
+
ROM has no separate `do_wield`/`do_hold` functions.
|
|
424
|
+
- `wield` and `hold` with no argument now emit
|
|
425
|
+
`"Wear, wield, or hold what?"` instead of `"Wield what?"` /
|
|
426
|
+
`"Hold what?"`, mirroring ROM's single-prompt design.
|
|
427
|
+
|
|
428
|
+
## [2.6.12] - 2026-04-28
|
|
429
|
+
|
|
430
|
+
Closes the remaining `interp.c` parser/extension gaps:
|
|
431
|
+
`INTERP-015` (port ROM `one_argument` to replace `shlex.split`) and
|
|
432
|
+
`INTERP-016` (verify `tail_chain` is a no-op in stock ROM and close-defer).
|
|
433
|
+
`interp.c` is now 22/24 gaps fixed + 1 closed-deferred + 1 deferred-pending
|
|
434
|
+
(`INTERP-013`, blocked on `ACT_OBJ_C` `do_wear` port).
|
|
435
|
+
|
|
436
|
+
### Fixed
|
|
437
|
+
|
|
438
|
+
- `interp.c:INTERP-015` — `_split_command_and_args` no longer routes
|
|
439
|
+
through `shlex.split`; the new `_one_argument()` mirrors ROM
|
|
440
|
+
`src/interp.c:766-798` byte-for-byte (lowercases head, single-char
|
|
441
|
+
`'` and `"` quote sentinels with no nesting, backslash treated
|
|
442
|
+
literally, surrounding whitespace stripped). `shlex` import dropped.
|
|
443
|
+
Tests:
|
|
444
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_015_one_argument_matches_rom`
|
|
445
|
+
(8 cases).
|
|
446
|
+
|
|
447
|
+
### Changed
|
|
448
|
+
|
|
449
|
+
- `interp.c:INTERP-016` — closed-deferred. Confirmed `tail_chain()`
|
|
450
|
+
is `return;` only in stock ROM 2.4b6 (`src/db.c:3929`); empty
|
|
451
|
+
hook used by some ROM derivatives for stack-tail-call extension.
|
|
452
|
+
Stock-ROM behavior is "do nothing", which Python already matches
|
|
453
|
+
by omission.
|
|
454
|
+
- `tests/test_alias_parity.py::test_alias_case_sensitivity` renamed
|
|
455
|
+
to `test_alias_case_insensitive_lookup_matches_rom` and flipped to
|
|
456
|
+
assert ROM-correct behavior — ROM `do_alias` stores keys via
|
|
457
|
+
`one_argument` which lowercases (`src/alias.c:127, 217`), so an
|
|
458
|
+
uppercase input head expands a lowercased alias key. The previous
|
|
459
|
+
Python assertion mirrored pre-port `shlex` behavior, not ROM.
|
|
460
|
+
|
|
461
|
+
## [2.6.11] - 2026-04-28
|
|
462
|
+
|
|
463
|
+
Closes the three small position/trust gates left in `interp.c`
|
|
464
|
+
(`INTERP-004`/`-005`/`-006`). `interp.c` is now 20/24 gaps closed
|
|
465
|
+
(83%); only `INTERP-013` (deferred until `do_wear` ports the missing
|
|
466
|
+
wield/hold logic), `INTERP-015` (shlex/one_argument port), and
|
|
467
|
+
`INTERP-016` (`tail_chain` documentation, no-op) remain.
|
|
468
|
+
|
|
469
|
+
### Fixed
|
|
470
|
+
|
|
471
|
+
- `interp.c:INTERP-004` — `shout` now requires trust 3 to match ROM
|
|
472
|
+
(`src/interp.c:200`). Previously had no `min_trust` (defaulted to 0).
|
|
473
|
+
Test: `tests/integration/test_interp_dispatcher.py::test_interp_004_shout_requires_trust_3`.
|
|
474
|
+
- `interp.c:INTERP-005` — `murder` now requires trust 5 to match ROM
|
|
475
|
+
(`src/interp.c:247`). Test:
|
|
476
|
+
`test_interp_005_murder_requires_trust_5`.
|
|
477
|
+
- `interp.c:INTERP-006` — `music` `min_position` lowered from
|
|
478
|
+
`RESTING` to `SLEEPING` to match ROM (`src/interp.c:93`). Test:
|
|
479
|
+
`test_interp_006_music_min_position_sleeping`.
|
|
480
|
+
|
|
481
|
+
## [2.6.10] - 2026-04-27
|
|
482
|
+
|
|
483
|
+
Closes five more `interp.c` gaps: command-mapping cleanup
|
|
484
|
+
(`INTERP-009/010/011/012/014` — `hit`/`take`/`junk`/`tap`/`go`/`:`
|
|
485
|
+
now route to canonical handlers), `do_commands` column-padding fix
|
|
486
|
+
(`INTERP-024`), and the prefix-order sweep (`INTERP-017`) — Python's
|
|
487
|
+
prefix scan now mirrors ROM `cmd_table[]` declaration order via a
|
|
488
|
+
250-entry table, so 1- and 2-letter abbreviations resolve identically
|
|
489
|
+
to ROM. `INTERP-013` (collapse `do_wield`/`do_hold` into `do_wear`)
|
|
490
|
+
deferred — Python `do_wear` is missing strength/skill/two-hand checks
|
|
491
|
+
and HOLD auto-unequip that the separate functions currently provide;
|
|
492
|
+
collapsing now would regress behavior. `interp.c` is now 17/24 gaps
|
|
493
|
+
closed (71%).
|
|
494
|
+
|
|
495
|
+
### Fixed
|
|
496
|
+
|
|
497
|
+
- `interp.c:INTERP-009` — `"hit"` now dispatches to `do_kill` as a
|
|
498
|
+
ROM-style alias on the kill `Command`; deleted redundant `do_hit`
|
|
499
|
+
stub from `player_info.py` (`src/interp.c:88`). Test:
|
|
500
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_009_hit_routes_to_do_kill`.
|
|
501
|
+
- `interp.c:INTERP-010` — `"take"` now dispatches to `do_get` as an
|
|
502
|
+
alias on the get `Command`; deleted `do_take` stub
|
|
503
|
+
(`src/interp.c:226`). Test:
|
|
504
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_010_take_routes_to_do_get`.
|
|
505
|
+
- `interp.c:INTERP-011` — `"junk"` and `"tap"` now dispatch to
|
|
506
|
+
`do_sacrifice` as aliases; deleted both stubs from `remaining_rom.py`
|
|
507
|
+
(`src/interp.c:228-229`). Test:
|
|
508
|
+
`test_interp_011_junk_tap_route_to_do_sacrifice`.
|
|
509
|
+
- `interp.c:INTERP-012` — `"go"` now dispatches to `do_enter` as an
|
|
510
|
+
alias; deleted `do_go` stub (`src/interp.c:263`). Test:
|
|
511
|
+
`test_interp_012_go_routes_to_do_enter`.
|
|
512
|
+
- `interp.c:INTERP-014` — `":"` now dispatches to `do_immtalk` as an
|
|
513
|
+
alias; deleted `do_colon` stub from `typo_guards.py` whose
|
|
514
|
+
`"Say what on the immortal channel?"` placeholder was masking ROM's
|
|
515
|
+
NOWIZ toggle behavior (`src/interp.c:356`). Test:
|
|
516
|
+
`test_interp_014_colon_routes_to_do_immtalk`.
|
|
517
|
+
- `interp.c:INTERP-024` — `do_commands`/`do_wizhelp` no longer strip
|
|
518
|
+
trailing whitespace from rows; ROM emits each name as `%-12s` with
|
|
519
|
+
full column padding preserved (`src/interp.c:815-823`). Test:
|
|
520
|
+
`test_interp_024_do_commands_preserves_12char_column_padding`.
|
|
521
|
+
- `interp.c:INTERP-017` — `resolve_command` now walks a 250-entry
|
|
522
|
+
ROM-faithful `_PREFIX_TABLE` in `src/interp.c` declaration order
|
|
523
|
+
instead of Python's feature-grouped `COMMANDS` list; removed the
|
|
524
|
+
exact-match shortcut so prefix resolution mirrors ROM
|
|
525
|
+
`interpret()` exactly (e.g. `"go"` now resolves to `goto` not
|
|
526
|
+
`enter`, matching ROM's hand-ordered prefix block). Sweep test:
|
|
527
|
+
`tests/integration/test_interp_prefix_order.py::test_interp_017_prefix_winner_matches_rom`
|
|
528
|
+
parses `src/interp.c` at collection time and asserts every
|
|
529
|
+
single-letter prefix plus 20 curated 2-letter prefixes resolve
|
|
530
|
+
identically to ROM (45 cases).
|
|
531
|
+
|
|
532
|
+
## [2.6.9] - 2026-04-27
|
|
533
|
+
|
|
534
|
+
Closes four `interp.c` dispatcher-level gaps in one session: empty-input
|
|
535
|
+
behavior (`INTERP-007`), ROM punctuation aliases (`INTERP-008`), snoop
|
|
536
|
+
forwarding (`INTERP-002`), and verified the wiznet `WIZ_SECURE` mirror
|
|
537
|
+
that was already in place (`INTERP-003`). `interp.c` is now 11/24 gaps
|
|
538
|
+
closed (46%).
|
|
539
|
+
|
|
540
|
+
### Fixed
|
|
541
|
+
|
|
542
|
+
- `interp.c:INTERP-007` — empty input now returns silently to match
|
|
543
|
+
ROM `interpret()` (`src/interp.c:401-404`). Previously emitted the
|
|
544
|
+
literal `"What?"`. Test:
|
|
545
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_007_empty_input_returns_silently`.
|
|
546
|
+
- `interp.c:INTERP-008` — added ROM punctuation aliases `.` → `gossip`,
|
|
547
|
+
`,` → `emote`, `/` → `recall` to `COMMAND_INDEX`
|
|
548
|
+
(`src/interp.c:184,186,272`). Test:
|
|
549
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_008_punctuation_aliases_route_to_rom_handlers`.
|
|
550
|
+
- `interp.c:INTERP-002` — `process_command` now forwards the input
|
|
551
|
+
logline to `desc.snoop_by.character.messages` prefixed with `"% "`
|
|
552
|
+
(`src/interp.c:491-496`). Test:
|
|
553
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_002_snoop_forwards_logline_to_snooper`.
|
|
554
|
+
- `interp.c:INTERP-003` — verified `log_admin_command` already mirrors
|
|
555
|
+
logged commands to wiznet `WIZ_SECURE` with ROM-style `$`/`{`
|
|
556
|
+
doubling (`mud/admin_logging/admin.py:107-114`,
|
|
557
|
+
`src/interp.c:468-489`). Audit row description was stale. Test:
|
|
558
|
+
`tests/integration/test_interp_dispatcher.py::test_interp_003_logged_command_mirrors_to_wiznet_secure`.
|
|
559
|
+
|
|
560
|
+
## [2.6.8] - 2026-04-27
|
|
561
|
+
|
|
562
|
+
Closes the immortal command trust drift (`INTERP-001`). All 43 commands
|
|
563
|
+
that were gated too low now match ROM `cmd_table[]` tier-for-tier. This
|
|
564
|
+
is a security-relevant fix — previously a `LEVEL_IMMORTAL` (52) character
|
|
565
|
+
could invoke commands ROM gates at L1..ML (53..60).
|
|
566
|
+
|
|
567
|
+
### Fixed
|
|
568
|
+
|
|
569
|
+
- `interp.c:INTERP-001` — raised `min_trust` on 43 immortal commands
|
|
570
|
+
in `mud/commands/dispatcher.py` to match ROM `cmd_table[]` trust
|
|
571
|
+
tiers (`src/interp.c:63-381`, `src/interp.h:34-44`). Affected
|
|
572
|
+
tiers: ML, L1, L2, L3, L4, L5, L6, L7. Security-relevant — closes
|
|
573
|
+
privilege drift where `LEVEL_IMMORTAL` (52) characters could
|
|
574
|
+
invoke commands ROM gates at L1..ML (53..60). Test:
|
|
575
|
+
`tests/integration/test_interp_trust.py::test_interp_001_command_trust_matches_rom` (50 parameters).
|
|
576
|
+
|
|
577
|
+
## [2.6.7] - 2026-04-27
|
|
578
|
+
|
|
579
|
+
`interp.c` social-cluster audit complete (6/6 social gaps closed). Both
|
|
580
|
+
remaining gaps (prefix lookup + literal "not found" message) shipped
|
|
581
|
+
with integration coverage; socials suite now 31/31. `interp.c` overall
|
|
582
|
+
audit progress: 6/24 gaps closed (25%) — non-social gaps (trust drift,
|
|
583
|
+
dispatcher hooks, command-mapping cleanup) remain open.
|
|
584
|
+
|
|
585
|
+
### Fixed
|
|
586
|
+
|
|
587
|
+
- `interp.c:INTERP-021` — social command lookup now mirrors ROM
|
|
588
|
+
`str_prefix` semantics so partial names (e.g. `gigg` → `giggle`)
|
|
589
|
+
resolve in load order. Added `mud.models.social.find_social()` and
|
|
590
|
+
routed both the dispatcher fallback (`mud/commands/dispatcher.py`)
|
|
591
|
+
and `perform_social` (`mud/commands/socials.py`) through it. Mirrors
|
|
592
|
+
ROM `src/interp.c:584-592`.
|
|
593
|
+
- `interp.c:INTERP-022` — `perform_social` now emits the literal
|
|
594
|
+
`"They aren't here."` when the targeted victim is absent, matching
|
|
595
|
+
ROM `src/interp.c:637-640`. The fabricated `social.not_found` field
|
|
596
|
+
(which has no counterpart in ROM's social table) is no longer used.
|
|
597
|
+
|
|
598
|
+
## [2.6.6] - 2026-04-27
|
|
599
|
+
|
|
600
|
+
`interp.c` ROM parity audit started — full audit doc with 24 stable gap
|
|
601
|
+
IDs (`INTERP-001`..`INTERP-024`) created. Closed the entire CRITICAL+
|
|
602
|
+
IMPORTANT social-cluster subset of `check_social` (`src/interp.c:597-685`):
|
|
603
|
+
position gates, NOEMOTE, sleeping snore exception, and the NPC slap/echo
|
|
604
|
+
auto-react via `mud.utils.rng_mm.number_bits(4)`. Socials integration
|
|
605
|
+
suite grew from 13 to 27 tests, all green.
|
|
606
|
+
|
|
607
|
+
### Fixed
|
|
608
|
+
|
|
609
|
+
- `interp.c:INTERP-018` — `perform_social` now refuses socials from
|
|
610
|
+
characters in `Position.DEAD`, `MORTAL`, `INCAP`, or `STUNNED` and
|
|
611
|
+
emits ROM's exact response messages
|
|
612
|
+
(`"Lie still; you are DEAD."`, `"You are hurt far too bad for that."`,
|
|
613
|
+
`"You are too stunned to do that."`). Mirrors
|
|
614
|
+
`src/interp.c:603-616` (`check_social` position gate).
|
|
615
|
+
- `interp.c:INTERP-019` — sleeping characters now receive
|
|
616
|
+
`"In your dreams, or what?"` for every social except `snore`
|
|
617
|
+
(the canonical Furey exception). Mirrors `src/interp.c:618-626`.
|
|
618
|
+
- `interp.c:INTERP-020` — players punished with the `COMM_NOEMOTE`
|
|
619
|
+
flag now receive `"You are anti-social!"` when attempting any
|
|
620
|
+
social. NPCs are unaffected per ROM's `IS_NPC` short-circuit.
|
|
621
|
+
Mirrors `src/interp.c:597-601`.
|
|
622
|
+
|
|
623
|
+
### Added
|
|
624
|
+
|
|
625
|
+
- `interp.c:INTERP-023` — NPC auto-reaction to player socials. When
|
|
626
|
+
a non-NPC socials at an awake, non-charmed, non-switched NPC,
|
|
627
|
+
`mud.utils.rng_mm.number_bits(4)` (0..15) decides the response:
|
|
628
|
+
values 0..8 echo the social back at the player with the actor and
|
|
629
|
+
victim swapped; values 9..12 produce a slap
|
|
630
|
+
(`"$n slaps $N." / "You slap $N." / "$n slaps you."`); values 13..15
|
|
631
|
+
fall through silently. Mirrors `src/interp.c:652-685`.
|
|
632
|
+
|
|
633
|
+
## [2.6.5] - 2026-04-27
|
|
634
|
+
|
|
635
|
+
`mob_prog.c` ROM parity audit complete — all 7 gaps closed (2 CRITICAL,
|
|
636
|
+
4 IMPORTANT, 1 MINOR). MOBprog predicate evaluation, greet/grall trigger
|
|
637
|
+
exclusivity, $-code expansion, and program-flow state-machine now match
|
|
638
|
+
ROM 2.4b6 behaviour.
|
|
639
|
+
|
|
640
|
+
### Fixed
|
|
641
|
+
|
|
642
|
+
- MOBPROG-007: `_program_flow` now logs a warning and aborts the program when
|
|
643
|
+
an `if`/`or`/`and` keyword is not in ROM's `fn_keyword[]` table, mirroring
|
|
644
|
+
the `bug()` + `return` paths at `src/mob_prog.c:1049-1056`, `1076-1083`,
|
|
645
|
+
`1103-1109`. Typo'd predicates fail loudly instead of silently evaluating
|
|
646
|
+
to False. Integration coverage at
|
|
647
|
+
`tests/integration/test_mobprog_program_flow.py`. Also corrected the
|
|
648
|
+
`test_simple_quest_accept_workflow` fixture program to use the real ROM
|
|
649
|
+
keyword `carries` (not the previously-silent invalid `has_item`).
|
|
650
|
+
- MOBPROG-006: `_expand_arg` `$R` substitution now replicates the ROM
|
|
651
|
+
long-standing bug at `src/mob_prog.c:798-799` — the visibility gate uses
|
|
652
|
+
`rch` (random victim) but the substituted string is `ch->short_descr`
|
|
653
|
+
(NPC actor) or `ch->name` (PC actor). Per AGENTS.md ROM Parity Rules,
|
|
654
|
+
QuickMUD reproduces the bug. Integration coverage at
|
|
655
|
+
`tests/integration/test_mobprog_predicates.py`.
|
|
656
|
+
- MOBPROG-005: `_program_flow` `else` branch now resets
|
|
657
|
+
`state[level] = IN_BLOCK` mirroring ROM `src/mob_prog.c:1138`. Structural
|
|
658
|
+
state-machine parity only — no observable divergence on valid programs;
|
|
659
|
+
regression coverage added at
|
|
660
|
+
`tests/integration/test_mobprog_program_flow.py`.
|
|
661
|
+
- MOBPROG-004: `_cmd_eval` `clan` / `race` / `class` checks now resolve their
|
|
662
|
+
name keyword via a ROM-style prefix lookup over `CLAN_TABLE`, `RACE_TABLE`,
|
|
663
|
+
and `CLASS_TABLE` (mirroring ROM `clan_lookup` / `race_lookup` /
|
|
664
|
+
`class_lookup`, `src/mob_prog.c:601-609`) instead of comparing the int
|
|
665
|
+
attribute to the literal name string. `if class $n mage`,
|
|
666
|
+
`if race $n dragon`, `if clan $n thieves` now match ROM. Integration
|
|
667
|
+
coverage at `tests/integration/test_mobprog_predicates.py`.
|
|
668
|
+
- MOBPROG-003: `_cmd_eval` `vnum` check now compares against `lval=0` when the
|
|
669
|
+
target is a PC instead of returning False. Mirrors ROM `src/mob_prog.c:631-642`
|
|
670
|
+
— `lval` initialises to 0 and is only overwritten for NPCs, so
|
|
671
|
+
`if vnum $n == 0` is True against PCs and `if vnum $n != 0` is False.
|
|
672
|
+
Integration coverage at `tests/integration/test_mobprog_predicates.py`.
|
|
673
|
+
- MOBPROG-002: `mp_greet_trigger` no longer falls through to GRALL after a
|
|
674
|
+
failed GREET percent roll. Mirrors ROM `src/mob_prog.c:1340-1345` where the
|
|
675
|
+
GREET / GRALL branches are exclusive — a mob that is awake, can see the
|
|
676
|
+
entrant, and has a GREET trigger only attempts GREET; GRALL is reserved for
|
|
677
|
+
the busy/blind path. Integration coverage at
|
|
678
|
+
`tests/integration/test_mobprog_greet_trigger.py`.
|
|
679
|
+
- MOBPROG-001: `_cmd_eval` `objexists` now walks `mud.models.obj.object_registry`
|
|
680
|
+
(mirroring ROM `get_obj_world`, `src/mob_prog.c:399`) instead of only the
|
|
681
|
+
current room and same-room carriers. Mob programs that gate on
|
|
682
|
+
`if objexists <vnum|name>` against globally-placed items now match ROM
|
|
683
|
+
semantics. Integration coverage at
|
|
684
|
+
`tests/integration/test_mobprog_predicates.py`.
|
|
685
|
+
|
|
686
|
+
## [2.6.4] - 2026-04-27
|
|
687
|
+
|
|
688
|
+
`mob_cmds.c` ROM parity audit complete — all 18 gaps closed (6 CRITICAL,
|
|
689
|
+
9 IMPORTANT, 3 MINOR). MOBprog script commands (`mob kill`, `assist`,
|
|
690
|
+
`oload`, `flee`, `cast`, `call`, `damage`, `junk`, `purge`, `transfer`)
|
|
691
|
+
now match ROM 2.4b6 behaviour for charm/master defence, position gates,
|
|
692
|
+
target-type dispatch, level bounds, NO_MOB respect, recursion, and
|
|
693
|
+
bug-log emission on script authoring errors.
|
|
694
|
+
|
|
695
|
+
### Fixed
|
|
696
|
+
|
|
697
|
+
- MOBCMD-017: `do_mptransfer` now mirrors ROM's recursive structure — a
|
|
698
|
+
literal `mob transfer all <loc>` recursively dispatches
|
|
699
|
+
`do_mptransfer(ch, "<pcname> <loc>")` once per PC in the room
|
|
700
|
+
(`src/mob_cmds.c:791-806`) so each victim re-runs the full validation
|
|
701
|
+
pipeline (private-room check, location resolution). Previously the
|
|
702
|
+
Python implementation inlined the iteration with a direct
|
|
703
|
+
`_transfer_character` call. NPCs are skipped exactly as in ROM line
|
|
704
|
+
799. Integration coverage at `tests/integration/test_mob_cmds_transfer.py`.
|
|
705
|
+
- MOBCMD-018: verified `do_mpflee` already checks `ch.fighting` as the
|
|
706
|
+
first guard, mirroring ROM `src/mob_cmds.c:1266-1267`. The audit row
|
|
707
|
+
was stale and is now closed without a code change.
|
|
708
|
+
- MOBCMD-007: `do_mppurge` no longer accepts the literal `"all"` token
|
|
709
|
+
as a synonym for the no-arg purge-everything form. ROM
|
|
710
|
+
`src/mob_cmds.c:631-665` treats an empty argument as purge-all and has
|
|
711
|
+
no `"all"` keyword — the token falls through to the name-resolution
|
|
712
|
+
branch like any other word. Also added the missing
|
|
713
|
+
`Mppurge - Bad argument` (ROM line 663) and `Mppurge - Purging a PC`
|
|
714
|
+
(ROM line 671) bug logs via the new `_bug()` helper. The previously
|
|
715
|
+
divergent unit test (`test_mppurge_all_cleans_room`) now uses the
|
|
716
|
+
no-arg form. Integration coverage at
|
|
717
|
+
`tests/integration/test_mob_cmds_purge.py`.
|
|
718
|
+
- MOBCMD-013: `do_mpdamage` now emits a ROM-style `bug()` warning via
|
|
719
|
+
Python's `logging` module when the min or max argument is non-numeric,
|
|
720
|
+
mirroring ROM `src/mob_cmds.c:1105-1107` + `1113-1115`. Previously the
|
|
721
|
+
function silently returned, swallowing what is a script-authoring
|
|
722
|
+
error. A new module-local `_bug()` helper in `mud/mob_cmds.py` mirrors
|
|
723
|
+
ROM's `bug("Mp... - <reason> from vnum %d.", vnum)` pattern; expect
|
|
724
|
+
this helper to be reused as further `mob_cmds` gaps are closed.
|
|
725
|
+
Integration coverage at
|
|
726
|
+
`tests/integration/test_mob_cmds_damage.py::TestMpDamageNonNumericArgsBugLog`.
|
|
727
|
+
- MOBCMD-009: `do_mpflee` now respects `ROOM_NO_MOB` on a candidate
|
|
728
|
+
destination when the fleeing character is an NPC, mirroring ROM
|
|
729
|
+
`src/mob_cmds.c:1277-1280`. Previously script-driven NPC flees would
|
|
730
|
+
pour mobs into rooms flagged NO_MOB. Integration coverage at
|
|
731
|
+
`tests/integration/test_mob_cmds_flee.py::TestMpFleeNoMobRoomFlag`.
|
|
732
|
+
- MOBCMD-006: `do_mpoload` now validates the optional level argument
|
|
733
|
+
against ROM's `level < 0 || level > get_trust(ch)` check
|
|
734
|
+
(`src/mob_cmds.c:575-580`) and refuses to spawn the object when out of
|
|
735
|
+
range. Previously the level was accepted unconditionally so a script
|
|
736
|
+
could load objects above the mob's trust ceiling. Integration coverage
|
|
737
|
+
at `tests/integration/test_mob_cmds_oload.py`.
|
|
738
|
+
- MOBCMD-004: `do_mpjunk` (MOBprog `junk` script command) now matches
|
|
739
|
+
ROM's empty-needle behaviour: `mob junk all.` (trailing dot, no
|
|
740
|
+
suffix) discards nothing because ROM `src/mob_cmds.c:436` defers to
|
|
741
|
+
`is_name(&arg[4], ...)` which returns FALSE for an empty string.
|
|
742
|
+
Python had been short-circuiting on `not suffix` and discarding every
|
|
743
|
+
carried object. Bare `mob junk all` still clears inventory as before.
|
|
744
|
+
Integration coverage at `tests/integration/test_mob_cmds_junk.py`.
|
|
745
|
+
- MOBCMD-002: `do_mpassist` now enforces ROM `src/mob_cmds.c:393`'s full
|
|
746
|
+
guard set — `victim == ch`, `ch->fighting != NULL`, and
|
|
747
|
+
`victim->fighting == NULL`. Previously only the third clause was
|
|
748
|
+
checked, so a script mob already in a fight could be redirected onto a
|
|
749
|
+
new target via `mob assist`, and a script mob could nonsensically
|
|
750
|
+
assist itself. Integration coverage at
|
|
751
|
+
`tests/integration/test_mob_cmds_assist.py`.
|
|
752
|
+
- MOBCMD-001: `do_mpkill` now refuses when the script mob is charmed
|
|
753
|
+
(`AffectFlag.CHARM`) and the chosen victim is its master, mirroring ROM
|
|
754
|
+
`src/mob_cmds.c:364-369`. Previously a charmed mob scripted to
|
|
755
|
+
`mob kill <master>` would attack its own charmer. Integration coverage
|
|
756
|
+
at `tests/integration/test_mob_cmds_kill.py::TestMpKillCharmedMasterGuard`.
|
|
757
|
+
- MOBCMD-015 + MOBCMD-016: `do_mpcall` (MOBprog `call` script command) now
|
|
758
|
+
parses the optional obj1/obj2 tokens from `mob call <vnum> <victim>
|
|
759
|
+
<obj1> <obj2>` and resolves them via `_find_obj_here` (the `get_obj_here`
|
|
760
|
+
analog), forwarding both to `mobprog.call_prog`. ROM
|
|
761
|
+
`src/mob_cmds.c:1217-1252` initialises obj1/obj2 to NULL and only sets
|
|
762
|
+
them when the corresponding token resolves through `get_obj_here`; the
|
|
763
|
+
Python implementation had been dropping both args entirely so called
|
|
764
|
+
sub-programs could never receive object context. Integration coverage at
|
|
765
|
+
`tests/integration/test_mob_cmds_call.py`.
|
|
766
|
+
- MOBCMD-011 + MOBCMD-012: `do_mpcast` (MOBprog `cast` script command) now
|
|
767
|
+
resolves the JSON `target` string into a canonical `_TargetType` IntEnum
|
|
768
|
+
mirroring ROM `TAR_*` (`src/magic.h`) and dispatches on the enum, matching
|
|
769
|
+
ROM's switch in `src/mob_cmds.c:1043-1066`. The previously string-keyed
|
|
770
|
+
branches were drift-prone; in particular the `TAR_OBJ_CHAR_DEF/OFF/INV`
|
|
771
|
+
cases now require an object (no character fallback) and `TAR_CHAR_DEFENSIVE`
|
|
772
|
+
defaults to `ch` when the lookup fails, matching ROM lines 1055 + 1060-1065.
|
|
773
|
+
Integration coverage at `tests/integration/test_mob_cmds_cast.py`.
|
|
774
|
+
- MOBCMD-003: `do_mpkill` now gates on `ch.position == Position.FIGHTING`
|
|
775
|
+
(matching ROM `src/mob_cmds.c:361`) instead of the looser
|
|
776
|
+
`ch.fighting is not None` check, and short-circuits self-attacks via the
|
|
777
|
+
missing `victim is ch` guard from the same ROM line. Integration coverage
|
|
778
|
+
at `tests/integration/test_mob_cmds_kill.py`.
|
|
779
|
+
- MOBCMD-008: `do_mpflee` now performs 6 `rng_mm.number_door()` random-door
|
|
780
|
+
attempts before giving up, mirroring ROM `src/mob_cmds.c:1272-1286`.
|
|
781
|
+
Previously the function iterated the exits list in order, so the first
|
|
782
|
+
valid exit always won — wrong distribution for ROM-faithful flee
|
|
783
|
+
behavior. Integration coverage at
|
|
784
|
+
`tests/integration/test_mob_cmds_flee.py::TestMpFleeRandomDoor`.
|
|
785
|
+
- MOBCMD-010: `do_mpflee` (MOBprog `flee` script command) now routes through
|
|
786
|
+
`mud.world.movement.move_character` instead of the silent `_move_to_room`
|
|
787
|
+
helper, mirroring ROM `src/mob_cmds.c:1283`
|
|
788
|
+
(`move_char(ch, door, FALSE)`). Leave/arrive broadcasts, mp_exit/entry
|
|
789
|
+
triggers, and the rest of the canonical movement pipeline now fire on
|
|
790
|
+
script-driven flees. Integration coverage at
|
|
791
|
+
`tests/integration/test_mob_cmds_flee.py`.
|
|
792
|
+
- MOBCMD-005: `do_mpoload` (MOBprog `oload` script command) now accepts the
|
|
793
|
+
optional `level` argument from `mob oload <vnum> [level] [R|W]`, mirroring
|
|
794
|
+
ROM `src/mob_cmds.c:538-614`. When omitted, level defaults to
|
|
795
|
+
`get_trust(ch)`; the spawned object's `level` is set post-spawn to mirror
|
|
796
|
+
ROM `create_object(pObjIndex, level)`. Previously the level token was parsed
|
|
797
|
+
but discarded, so script-loaded objects always took the prototype's raw
|
|
798
|
+
level. Integration coverage at `tests/integration/test_mob_cmds_oload.py`.
|
|
799
|
+
- MOBCMD-014: `do_mpdamage` (MOBprog `damage` script command) now routes
|
|
800
|
+
through `mud.combat.engine.apply_damage` instead of raw-decrementing
|
|
801
|
+
`victim.hit`. Mirrors ROM `src/mob_cmds.c:1132-1145`
|
|
802
|
+
(`damage(victim, victim, amount, TYPE_UNDEFINED, DAM_NONE, FALSE)`) so
|
|
803
|
+
the death pipeline, position updates, fight triggers, and corpse
|
|
804
|
+
handling fire on script-driven damage. Integration coverage at
|
|
805
|
+
`tests/integration/test_mob_cmds_damage.py`.
|
|
806
|
+
|
|
807
|
+
### Changed
|
|
808
|
+
|
|
809
|
+
- `docs/parity/ACT_OBJ_C_AUDIT.md` and `docs/parity/ROM_C_SUBSYSTEM_AUDIT_TRACKER.md`
|
|
810
|
+
refreshed to reflect that ROM `src/act_obj.c` is at 100% parity. Apr 27, 2026
|
|
811
|
+
formal sweep verified all 12 audited functions
|
|
812
|
+
(`do_get`/`do_put`/`do_drop`/`do_give`/`do_remove`/`do_sacrifice`/`do_quaff`/
|
|
813
|
+
`do_drink`/`do_eat`/`do_fill`/`do_pour`/`do_recite`/`do_brandish`/`do_zap`
|
|
814
|
+
plus `do_wear`/`do_wield`/`do_hold` and `do_steal`) against current Python;
|
|
815
|
+
the recent batch commits (`97c901e` do_drop parity batch, `517542b` close
|
|
816
|
+
get/put/drop/give/wear/sacrifice/recite/brandish/zap/steal gaps) closed all
|
|
817
|
+
outstanding gaps. 193 act_obj-area integration tests green. P1 audited count
|
|
818
|
+
rises from 5/11 (81%) to 6/11 (86%). No code changes — documentation
|
|
819
|
+
reconciliation only.
|
|
820
|
+
|
|
821
|
+
## [2.6.3] - 2026-04-27
|
|
822
|
+
|
|
823
|
+
### Added
|
|
824
|
+
|
|
825
|
+
- Three project-local skills under `.claude/skills/` encoding the ROM 2.4b6 →
|
|
826
|
+
Python parity loop: `rom-parity-audit` (file-level 5-phase audit),
|
|
827
|
+
`rom-gap-closer` (single-gap TDD close flow), `rom-session-handoff`
|
|
828
|
+
(end-of-session SESSION_SUMMARY + SESSION_STATUS + CHANGELOG generation).
|
|
829
|
+
- `CLAUDE.md` "Porting workflow" section: decision-tree mapping of when to
|
|
830
|
+
invoke each skill plus dependencies between them.
|
|
831
|
+
|
|
832
|
+
### Changed
|
|
833
|
+
|
|
834
|
+
- `README.md` Project Status / badges refreshed to current state: version
|
|
835
|
+
`2.6.2`, tests `3508/3521 passing` (99.6%) with 11 skipped and 2 known
|
|
836
|
+
pre-existing failures, integration suite `1000+`, ROM 2.4b parity badge
|
|
837
|
+
scoped to "gameplay 100%" (truer given the long tail of P2/P3 files), and
|
|
838
|
+
active focus called out as `act_obj.c` (~60%).
|
|
839
|
+
- `AGENTS.md` Repo Hygiene §2 now requires that any change to README's
|
|
840
|
+
Project Status / badges / metrics be accompanied in the same commit by a
|
|
841
|
+
refresh of AGENTS.md tracker pointers and `docs/sessions/SESSION_STATUS.md`,
|
|
842
|
+
preventing drift between the three surfaces. Underlying numbers stay
|
|
843
|
+
sourced from `docs/parity/*` trackers.
|
|
844
|
+
|
|
845
|
+
## [2.6.2] - 2026-04-27
|
|
846
|
+
|
|
847
|
+
### Fixed
|
|
848
|
+
|
|
849
|
+
- **act_enter portal regressions** uncovered by the act_enter.c audit
|
|
850
|
+
(PR #123):
|
|
851
|
+
- `_stand_charmed_follower` now forwards `do_stand`'s returned string
|
|
852
|
+
into the follower's message stream, so charmed sleepers receive the
|
|
853
|
+
"You wake and stand up." text exactly as ROM `act_move.c:1044`
|
|
854
|
+
sends inside `do_stand`.
|
|
855
|
+
- `_portal_fade_out` now explicitly removes the portal from
|
|
856
|
+
`room.contents` and clears `portal.location`. `game_loop._extract_obj`
|
|
857
|
+
keys off `obj.in_room` but `Object` uses `obj.location`, so portal
|
|
858
|
+
detachment after charge expiry was a silent no-op. Behavior now
|
|
859
|
+
matches ROM `extract_obj(portal)` at `act_enter.c:212`.
|
|
860
|
+
- `test_enter_closed_portal_denied`: corrected expected message to
|
|
861
|
+
`"You can't seem to find a way in."` per ROM `act_enter.c:94`. The
|
|
862
|
+
prior `"The portal is closed."` was the door-blocked message from
|
|
863
|
+
`act_move.c`, not the portal path.
|
|
864
|
+
- `test_move_through_portal_blocked_while_fighting`: corrected to
|
|
865
|
+
assert silent return per ROM `act_enter.c:70-71`
|
|
866
|
+
(`if (ch->fighting != NULL) return;`); removed the non-ROM
|
|
867
|
+
`"No way! You are still fighting!"` string.
|
|
868
|
+
- **`test_giant_strength_refuses_to_stack`** (was
|
|
869
|
+
`test_stat_modifiers_stack_from_same_spell`): test asserted +4 STR after
|
|
870
|
+
recasting giant strength, but ROM `src/magic.c:3022-3030`
|
|
871
|
+
`spell_giant_strength` early-returns with "You are already as strong as
|
|
872
|
+
you can get!" when the target is already affected. The Python
|
|
873
|
+
implementation correctly mirrors ROM; the test was wrong. Rewrote the
|
|
874
|
+
test to assert ROM anti-stack behavior.
|
|
875
|
+
- **`test_scavenger_prefers_valuable_items`**: flaky because the
|
|
876
|
+
Mitchell-Moore RNG state leaks across tests, and the scavenger only acts
|
|
877
|
+
on a 1/64 roll per `mobile_update` tick. Seed `rng_mm.seed_mm` to a
|
|
878
|
+
known value at start of test and bump the iteration cap from 2000 to
|
|
879
|
+
5000 for deterministic passes.
|
|
880
|
+
|
|
881
|
+
## [2.6.1] - 2026-04-27
|
|
882
|
+
|
|
883
|
+
### Added
|
|
884
|
+
|
|
885
|
+
- **act_enter.c parity (100% ROM parity for portal/enter mechanics):**
|
|
886
|
+
Close all 15 ENTER-001..016 gaps documented in
|
|
887
|
+
`docs/parity/ACT_ENTER_C_AUDIT.md`. 25 new integration tests in
|
|
888
|
+
`tests/integration/test_act_enter_gaps.py`.
|
|
889
|
+
|
|
890
|
+
### Fixed
|
|
891
|
+
|
|
892
|
+
- **ENTER-009 (CRITICAL):** `do_enter` TO_CHAR message ("You enter $p." /
|
|
893
|
+
"...somewhere else...") was being returned as a Python string and
|
|
894
|
+
silently dropped — now delivered to the player.
|
|
895
|
+
- **ENTER-005:** Portal lookup uses `get_obj_list` (visibility,
|
|
896
|
+
numbered syntax `2.portal`, keyword-list semantics) instead of fuzzy
|
|
897
|
+
substring matching.
|
|
898
|
+
- **ENTER-004:** Non-portal objects and closed portals both produce
|
|
899
|
+
`"You can't seem to find a way in."` (was diverging).
|
|
900
|
+
- **ENTER-008/010:** Departure/arrival TO_ROOM messages go through
|
|
901
|
+
`act_format` + `broadcast_room` for correct `$n` invisibility
|
|
902
|
+
resolution.
|
|
903
|
+
- **ENTER-011:** Portal fade-out only broadcasts in the old room when
|
|
904
|
+
caller is in the old room; calls `extract_obj` on charge expiry.
|
|
905
|
+
- **ENTER-013:** `_get_random_room` capped at 100k iterations
|
|
906
|
+
(was potentially returning None; ROM loops indefinitely).
|
|
907
|
+
- **ENTER-006/007/012:** Follower cascade — charmed followers stand
|
|
908
|
+
before following, follower-name interpolation via `act_format`.
|
|
909
|
+
- **ENTER-002/003/014/015/016:** Cosmetic message wording matched to
|
|
910
|
+
ROM and fighting-character silent-skip path.
|
|
911
|
+
|
|
912
|
+
## [2.6.0] - 2026-04-27
|
|
913
|
+
|
|
914
|
+
### Added
|
|
915
|
+
|
|
916
|
+
- **act_obj.c parity batch (100% ROM parity for object-manipulation
|
|
917
|
+
commands):** do_get/do_put/do_drop/do_give/do_wear/do_remove/do_sacrifice/
|
|
918
|
+
do_quaff/do_eat/do_drink/do_fill/do_pour/do_envenom/do_recite/do_brandish/
|
|
919
|
+
do_zap/do_steal and shop commands (do_buy/do_sell/do_list/do_value).
|
|
920
|
+
Adds full ROM TO_ROOM/TO_VICT/TO_NOTVICT broadcasts via act_format +
|
|
921
|
+
broadcast_room. ~80 new integration tests under tests/integration/.
|
|
922
|
+
- **act_move.c parity batch:** do_stand/do_rest/do_sit/do_sleep/do_wake
|
|
923
|
+
rewritten with full ROM furniture support (STAND/SIT/REST/SLEEP_AT/ON/IN
|
|
924
|
+
with capacity checks and ch.on tracking). MOVE-001 arrival broadcast,
|
|
925
|
+
MOVE-002 follower-name interpolation, SNEAK-001/HIDE-001 dispatcher
|
|
926
|
+
delegation to canonical handlers. 40 new integration tests in
|
|
927
|
+
tests/integration/test_position_commands.py.
|
|
928
|
+
- **act_comm.c P2 batch:** do_emote NOEMOTE check, do_pmote (~312 lines),
|
|
929
|
+
do_colour, do_split gold+silver simultaneous-split fix, do_pose pose_table
|
|
930
|
+
by class+level. New mud/utils/poses.py.
|
|
931
|
+
- **act_info.c P2 batch:** do_title/do_description/auto-settings family
|
|
932
|
+
(autolist, autoassist, autoexit, autogold, autoloot, autopeek, autosac,
|
|
933
|
+
autosplit, autotitle).
|
|
934
|
+
- LIQUID_TABLE in mud/models/constants.py extended with proof/full/thirst/
|
|
935
|
+
food/ssize fields sourced from ROM src/const.c:886-931.
|
|
936
|
+
- WebSocket stream support (mud/network/websocket_stream.py) for the
|
|
937
|
+
browser frontend; tests in tests/test_websocket_server.py.
|
|
938
|
+
|
|
939
|
+
### Changed
|
|
940
|
+
|
|
941
|
+
- **AGENTS.md rewritten:** ~700 lines → 275. Removed running session
|
|
942
|
+
narrative, duplicated status reporting, stale "next steps". Added Session
|
|
943
|
+
Notes (docs/sessions/) and Repo Hygiene (CHANGELOG / README / semver in
|
|
944
|
+
pyproject.toml) sections modeled on quickmud-web-client/AGENTS.md.
|
|
945
|
+
- 79 SESSION_SUMMARY_*.md and HANDOFF_*.md files moved from repo root to
|
|
946
|
+
`docs/sessions/`.
|
|
947
|
+
|
|
948
|
+
### Fixed
|
|
949
|
+
|
|
950
|
+
- `_obj_from_char()` now operates on `char.inventory` (was reading the
|
|
951
|
+
wrong field, so transferred objects were not removed from giver).
|
|
952
|
+
- `count_users()` in mud/handler.py now reads `room.people` (room.characters
|
|
953
|
+
does not exist).
|
|
954
|
+
- String-keyed equipment lookups replaced with `WearLocation` IntEnum keys
|
|
955
|
+
across BRANDISH/ZAP/POUR families.
|
|
956
|
+
- Hardcoded hex flag values replaced with enum members
|
|
957
|
+
(`PlayerFlag.AUTOSPLIT`, `WearFlag.NO_SAC`, `ItemType.STAFF/WAND`, etc).
|
|
958
|
+
- `do_steal` MAX_LEVEL set to 60 (was 51); STEAL-001..014 covering
|
|
959
|
+
one_argument semantics, is_safe, is_clan, sleeping-victim wake, PC→PC
|
|
960
|
+
PlayerFlag.THIEF, multi_hit signature, NODROP/INVENTORY checks,
|
|
961
|
+
can_see_object visibility filter.
|
|
962
|
+
- `do_recite/do_brandish/do_zap` success paths were unrunnable due to
|
|
963
|
+
undefined SkillTarget, bad ItemType references, string-keyed HOLD
|
|
964
|
+
lookup; all 17 RECITE/BRANDISH/ZAP gaps closed.
|
|
965
|
+
|
|
966
|
+
## [2.5.2] - 2025-12-30
|
|
967
|
+
|
|
968
|
+
### Added
|
|
969
|
+
|
|
970
|
+
- **Command Integration ROM Parity Tests** (70 new tests):
|
|
971
|
+
- `tests/test_act_comm_rom_parity.py` - 23 tests for communication commands (ROM `act_comm.c`)
|
|
972
|
+
- Channel status display (`do_channels`)
|
|
973
|
+
- Communication flag toggles (`do_deaf`, `do_quiet`, `do_afk`)
|
|
974
|
+
- Channel blocking logic (QUIET, NOCHANNELS flags)
|
|
975
|
+
- Delete command NPC blocking
|
|
976
|
+
- Replay command behaviors
|
|
977
|
+
- `tests/test_act_enter_rom_parity.py` - 22 tests for portal mechanics (ROM `act_enter.c`)
|
|
978
|
+
- Random room selection with flag exclusions (`get_random_room`)
|
|
979
|
+
- Portal entry mechanics (closed, curse, trust checks)
|
|
980
|
+
- Portal charge system and flag handling (RANDOM, BUGGY, GOWITH)
|
|
981
|
+
- Follower cascading through portals
|
|
982
|
+
- `tests/test_act_wiz_rom_parity.py` - 25 tests for wiznet/admin commands (ROM `act_wiz.c`)
|
|
983
|
+
- Wiznet channel toggle and flag management
|
|
984
|
+
- Wiznet broadcast filtering (WIZ_ON, flag filters, min_level)
|
|
985
|
+
- Admin commands (freeze, transfer, goto, trust)
|
|
986
|
+
- Trust level enforcement
|
|
987
|
+
|
|
988
|
+
- **Documentation**:
|
|
989
|
+
- `COMMAND_INTEGRATION_PARITY_REPORT.md` - Comprehensive command integration test completion report
|
|
990
|
+
- Detailed ROM C to Python mapping for all 70 tests
|
|
991
|
+
- Test philosophy and design decisions
|
|
992
|
+
- ROM C source analysis summary
|
|
993
|
+
- Quality metrics and coverage matrix
|
|
994
|
+
|
|
995
|
+
### Changed
|
|
996
|
+
|
|
997
|
+
- **ROM 2.4b6 Parity Certification Updates**:
|
|
998
|
+
- Updated total ROM parity test count: 735 → 805 tests (+70)
|
|
999
|
+
- Updated total test count: 2507 → 2577 tests (+70)
|
|
1000
|
+
- Added Command Integration Tests section to certification document
|
|
1001
|
+
- Updated ROM C source verification to include `act_comm.c`, `act_enter.c`, `act_wiz.c`
|
|
1002
|
+
|
|
1003
|
+
- **Test Coverage**:
|
|
1004
|
+
- Increased command integration test coverage (communication, portal, wiznet modules)
|
|
1005
|
+
- Total ROM parity tests: 805 (127 P0/P1/P2 + 608 combat/spells/skills + 70 command integration)
|
|
1006
|
+
|
|
1007
|
+
## [2.5.1] - 2025-12-30
|
|
1008
|
+
|
|
1009
|
+
### Added
|
|
1010
|
+
|
|
1011
|
+
- **Session Summary Documentation**:
|
|
1012
|
+
- `P0_P1_P2_EXTENDED_TESTING_SESSION_SUMMARY.md` - Verification session summary documenting that all P0/P1/P2 ROM C parity tests were already complete from previous sessions (December 29-30, 2025)
|
|
1013
|
+
|
|
1014
|
+
### Changed
|
|
1015
|
+
|
|
1016
|
+
- Updated README badges and project status to reflect complete ROM C parity test coverage (735 total ROM parity tests including 127 P0/P1/P2 formula verification tests)
|
|
1017
|
+
|
|
1018
|
+
## [2.5.0] - 2025-12-29
|
|
1019
|
+
|
|
1020
|
+
### Added
|
|
1021
|
+
|
|
1022
|
+
- **🎉 ROM 2.4b6 Parity Certification**: Official 100% ROM 2.4b6 behavioral parity certification
|
|
1023
|
+
- Created `ROM_2.4B6_PARITY_CERTIFICATION.md` - Comprehensive official certification document
|
|
1024
|
+
- 10 detailed subsystem parity matrices with ROM C source verification
|
|
1025
|
+
- Complete audit trail with 7 comprehensive audit documents (2000+ lines)
|
|
1026
|
+
- Integration test verification (43/43 passing = 100%)
|
|
1027
|
+
- Unit test coverage breakdown (700+ tests)
|
|
1028
|
+
- Differential testing methodology documented
|
|
1029
|
+
- Production readiness assessment
|
|
1030
|
+
- All 7 certification criteria verified and passing
|
|
1031
|
+
|
|
1032
|
+
- **Combat System Parity Verification** (100% Complete):
|
|
1033
|
+
- `COMBAT_PARITY_AUDIT_2025-12-28.md` - Comprehensive combat system audit
|
|
1034
|
+
- Added combat assist system (`mud/combat/assist.py`) with all ROM mechanics
|
|
1035
|
+
- Added 30+ combat tests (damage types, position multipliers, surrender command)
|
|
1036
|
+
- Verified all 32 ROM C combat functions implemented
|
|
1037
|
+
- Verified all 15 ROM combat commands functional
|
|
1038
|
+
- Position-based damage multipliers (sleeping 2x, resting/sitting 1.5x)
|
|
1039
|
+
- Damage resistance/vulnerability system complete
|
|
1040
|
+
- Special weapon effects (sharpness, vorpal, flaming, frost, vampiric, poison)
|
|
1041
|
+
|
|
1042
|
+
- **World Reset System Parity Verification** (100% Complete):
|
|
1043
|
+
- `WORLD_RESET_PARITY_AUDIT.md` - Comprehensive reset system audit
|
|
1044
|
+
- Verified all 7 ROM reset commands (M, O, P, G, E, D, R)
|
|
1045
|
+
- 49/49 reset tests passing with complete behavioral verification
|
|
1046
|
+
- Door state synchronization (bidirectional + one-way doors)
|
|
1047
|
+
- Exit randomization (Fisher-Yates shuffle)
|
|
1048
|
+
- ROM scheduling formula verified exact
|
|
1049
|
+
- Special cases documented (shop inventory, pet shops, infrared)
|
|
1050
|
+
|
|
1051
|
+
- **OLC Builders System Parity Verification** (100% Complete):
|
|
1052
|
+
- `OLC_PARITY_AUDIT.md` - Comprehensive OLC system audit
|
|
1053
|
+
- Verified all 5 ROM editors (@redit, @aedit, @oedit, @medit, @hedit)
|
|
1054
|
+
- 189/189 OLC tests passing with complete workflow verification
|
|
1055
|
+
- All 5 @asave variants functional
|
|
1056
|
+
- All 5 builder stat commands operational
|
|
1057
|
+
- Builder security system complete (trust levels, vnum ranges)
|
|
1058
|
+
|
|
1059
|
+
- **Security System Parity Verification** (100% Complete):
|
|
1060
|
+
- `SECURITY_PARITY_AUDIT.md` - Comprehensive security system audit
|
|
1061
|
+
- `SECURITY_PARITY_COMPLETION_SUMMARY.md` - Security session summary
|
|
1062
|
+
- Verified all 6 ROM ban flags (BAN_SUFFIX, PREFIX, NEWBIES, ALL, PERMIT, PERMANENT)
|
|
1063
|
+
- All 4 pattern matching modes (exact, prefix*, *suffix, *substring*)
|
|
1064
|
+
- 25/25 ban tests passing
|
|
1065
|
+
- Trust level enforcement verified
|
|
1066
|
+
- ROM file format compatibility verified
|
|
1067
|
+
|
|
1068
|
+
- **Object System Parity Verification** (100% Complete):
|
|
1069
|
+
- `OBJECT_PARITY_COMPLETION_REPORT.md` - Object system completion report
|
|
1070
|
+
- `docs/parity/OBJECT_PARITY_TRACKER.md` - Detailed 11-subsystem breakdown
|
|
1071
|
+
- Verified all 17 ROM object commands functional
|
|
1072
|
+
- 152/152 object tests passing + 277+ total object-related tests
|
|
1073
|
+
- Complete equipment system (11/11 wear mechanics)
|
|
1074
|
+
- Full container system (9/9 mechanics)
|
|
1075
|
+
- Exact encumbrance system (7/7 ROM C functions)
|
|
1076
|
+
- Complete shop economy (11/11 features)
|
|
1077
|
+
|
|
1078
|
+
- **Session Documentation**:
|
|
1079
|
+
- `SESSION_SUMMARY_2025-12-28.md` - Complete session documentation
|
|
1080
|
+
- `SESSION_SUMMARY_2025-12-27.md` - Previous session documentation
|
|
1081
|
+
|
|
1082
|
+
- **Additional Audit Documents**:
|
|
1083
|
+
- `SPELL_AFFECT_PARITY_AUDIT_2025-12-28.md` - Spell affect system verification
|
|
1084
|
+
- `COMBAT_GAP_VERIFICATION_FINAL.md` - Combat gap analysis and closure
|
|
1085
|
+
- `COMBAT_DAMAGE_RESISTANCE_COMPLETION.md` - Damage type system completion
|
|
1086
|
+
- `REMAINING_PARITY_GAPS_2025-12-28.md` - Final gap analysis (none remaining)
|
|
1087
|
+
- `COMMAND_AUDIT_2025-12-27_FINAL.md` - Command parity final verification
|
|
1088
|
+
|
|
1089
|
+
### Changed
|
|
1090
|
+
|
|
1091
|
+
- **README.md Updates**:
|
|
1092
|
+
- Updated version badge to 2.5.0
|
|
1093
|
+
- Updated ROM parity badge to link to official certification
|
|
1094
|
+
- Added "CERTIFIED" designation to ROM parity claim
|
|
1095
|
+
- Updated test counts to reflect integration test results (43/43 passing)
|
|
1096
|
+
- Added integration tests badge
|
|
1097
|
+
- Reorganized documentation section with certification first
|
|
1098
|
+
- Updated project status section with certification details
|
|
1099
|
+
|
|
1100
|
+
- **Documentation Organization**:
|
|
1101
|
+
- Added official certification as primary documentation
|
|
1102
|
+
- Reorganized docs to highlight certification achievement
|
|
1103
|
+
- Updated all parity references to point to certification
|
|
1104
|
+
|
|
1105
|
+
- **Test Organization**:
|
|
1106
|
+
- Added `tests/test_combat_assist.py` - Combat assist mechanics (14 tests)
|
|
1107
|
+
- Added `tests/test_combat_damage_types.py` - Damage resistance/vulnerability (15 tests)
|
|
1108
|
+
- Added `tests/test_combat_position_damage.py` - Position damage multipliers (10 tests)
|
|
1109
|
+
- Added `tests/test_combat_surrender.py` - Surrender command (5 tests)
|
|
1110
|
+
|
|
1111
|
+
### Fixed
|
|
1112
|
+
|
|
1113
|
+
- Combat damage vulnerability check now runs after immunity check (ROM parity fix)
|
|
1114
|
+
- Corrected misleading "decapitation" comment on vorpal flag (ROM 2.4b6 has no decapitation)
|
|
1115
|
+
- Updated outdated parity assessments in ROM_PARITY_FEATURE_TRACKER.md
|
|
1116
|
+
|
|
1117
|
+
### Verified
|
|
1118
|
+
|
|
1119
|
+
- ✅ **100% ROM 2.4b6 command coverage** (255/255 commands implemented)
|
|
1120
|
+
- ✅ **100% integration test pass rate** (43/43 tests passing)
|
|
1121
|
+
- ✅ **96.1% ROM C function coverage** (716/745 functions mapped)
|
|
1122
|
+
- ✅ **All 10 major subsystems** verified with comprehensive audits
|
|
1123
|
+
- ✅ **Production readiness** confirmed for players, builders, admins, developers
|
|
1124
|
+
|
|
1125
|
+
### Documentation
|
|
1126
|
+
|
|
1127
|
+
- 7 comprehensive audit documents totaling 2000+ lines
|
|
1128
|
+
- Official ROM 2.4b6 parity certification document
|
|
1129
|
+
- Complete ROM C source verification methodology
|
|
1130
|
+
- Differential testing documentation
|
|
1131
|
+
- Production deployment guidelines
|
|
1132
|
+
|
|
1133
|
+
## [2.4.0] - 2025-12-27
|
|
1134
|
+
|
|
1135
|
+
### Added
|
|
1136
|
+
|
|
1137
|
+
- **GitHub Release Creator Skill**: Comprehensive Claude Desktop skill for automated release management
|
|
1138
|
+
- Added `.claude/skills/github-release-creator/` with complete release automation tooling
|
|
1139
|
+
- Python script for automated release creation (`create_release.py`)
|
|
1140
|
+
- Shell scripts for release validation and creation
|
|
1141
|
+
- Changelog extraction utilities
|
|
1142
|
+
- Complete documentation with usage examples and workflows
|
|
1143
|
+
- GitHub CLI integration for professional release management
|
|
1144
|
+
- Support for semantic versioning, draft releases, and pre-releases
|
|
1145
|
+
|
|
1146
|
+
## [2.3.1] - 2025-12-27
|
|
1147
|
+
|
|
1148
|
+
### Added
|
|
1149
|
+
|
|
1150
|
+
- **Comprehensive Test Planning Documentation**:
|
|
1151
|
+
- Created `docs/validation/MOB_PARITY_TEST_PLAN.md` - Complete testing strategy for ROM 2.4b mob behaviors
|
|
1152
|
+
- 22 spec_fun behaviors (guards, dragons, casters, thieves)
|
|
1153
|
+
- 30+ ACT flag behaviors (aggressive, wimpy, scavenger, sentinel)
|
|
1154
|
+
- Damage modifiers (immunities, resistances, vulnerabilities)
|
|
1155
|
+
- Mob memory and tracking systems
|
|
1156
|
+
- Group assist mechanics
|
|
1157
|
+
- Wandering/movement AI
|
|
1158
|
+
- Created `docs/validation/PLAYER_PARITY_TEST_PLAN.md` - Complete testing strategy for player-specific behaviors
|
|
1159
|
+
- Information display commands (score, worth, whois)
|
|
1160
|
+
- Auto-settings (autoassist, autoloot, autogold, autosac, autosplit)
|
|
1161
|
+
- Conditions system (hunger, thirst, drunk, full)
|
|
1162
|
+
- Player flags and reputation (KILLER, THIEF)
|
|
1163
|
+
- Prompt customization
|
|
1164
|
+
- Title/description management
|
|
1165
|
+
- Trust/security levels
|
|
1166
|
+
- Player visibility states (AFK, wizinvis, incognito)
|
|
1167
|
+
- **Claude Desktop Skill Support**:
|
|
1168
|
+
- Added `SKILL.md` - Comprehensive skill documentation for AI assistants
|
|
1169
|
+
- Added `.claude/skills/skill-creator/` - Anthropic's skill-creator tool
|
|
1170
|
+
- Skill validation scripts
|
|
1171
|
+
- Skill packaging utilities
|
|
1172
|
+
- Best practices documentation
|
|
1173
|
+
|
|
1174
|
+
### Changed
|
|
1175
|
+
|
|
1176
|
+
- **Test Organization**: Created clear roadmap for implementing 180+ behavioral tests
|
|
1177
|
+
- 6 major mob test areas (P0-P3 priority matrix)
|
|
1178
|
+
- 8 major player test areas (P0-P3 priority matrix)
|
|
1179
|
+
- 4-phase implementation roadmap for each
|
|
1180
|
+
- Complete test templates with ROM C references
|
|
1181
|
+
|
|
1182
|
+
### Documentation
|
|
1183
|
+
|
|
1184
|
+
- Documented 100+ specific test cases with ROM C source references
|
|
1185
|
+
- Added implementation effort estimates and player impact assessments
|
|
1186
|
+
- Created comprehensive testing guides for future development
|
|
1187
|
+
|
|
1188
|
+
## [2.3.0] - 2025-12-26
|
|
1189
|
+
|
|
1190
|
+
### Added
|
|
1191
|
+
|
|
1192
|
+
- **MobProg 100% ROM C Parity Achievement**: All 4 critical trigger hookups complete
|
|
1193
|
+
- `mp_give_trigger` integrated in do_give command
|
|
1194
|
+
- `mp_hprct_trigger` integrated in combat damage system
|
|
1195
|
+
- `mp_death_trigger` integrated in character death handling
|
|
1196
|
+
- `mp_speech_trigger` already integrated (verified)
|
|
1197
|
+
- MobProg movement command validation in area file validator
|
|
1198
|
+
- Comprehensive MobProg testing documentation (5 guides)
|
|
1199
|
+
- Enhanced `validate_mobprogs.py` with movement command validation
|
|
1200
|
+
- Organized validation and parity documentation structure
|
|
1201
|
+
|
|
1202
|
+
### Changed
|
|
1203
|
+
|
|
1204
|
+
- **Documentation Reorganization**: Created proper folder structure
|
|
1205
|
+
- Moved 10 documentation files to `docs/validation/` and `docs/parity/`
|
|
1206
|
+
- Moved 10 scripts to `scripts/validation/` and `scripts/parity/`
|
|
1207
|
+
- Moved 5 report files to appropriate `reports/` subfolders
|
|
1208
|
+
- Created 6 README files documenting folder contents
|
|
1209
|
+
- Updated all cross-references in documentation to use new paths
|
|
1210
|
+
- Enhanced validation scripts with movement command checks
|
|
1211
|
+
|
|
1212
|
+
### Fixed
|
|
1213
|
+
|
|
1214
|
+
- Integration test issues with Object creation and trigger signatures
|
|
1215
|
+
- Syntax error in validate_mobprogs.py output formatting
|
|
1216
|
+
|
|
1217
|
+
## [2.2.1] - Previous Release
|
|
1218
|
+
|
|
1219
|
+
### Added
|
|
1220
|
+
|
|
1221
|
+
- Complete weapon special attacks system with ROM 2.4 parity (WEAPON_VAMPIRIC, WEAPON_POISON, WEAPON_FLAMING, WEAPON_FROST, WEAPON_SHOCKING)
|
|
1222
|
+
|
|
1223
|
+
### Changed
|
|
1224
|
+
|
|
1225
|
+
### Deprecated
|
|
1226
|
+
|
|
1227
|
+
### Removed
|
|
1228
|
+
|
|
1229
|
+
### Fixed
|
|
1230
|
+
|
|
1231
|
+
### Security
|
|
1232
|
+
|
|
1233
|
+
## [1.3.0] - 2025-09-15
|
|
1234
|
+
|
|
1235
|
+
### Added
|
|
1236
|
+
|
|
1237
|
+
- Complete fighting state management with ROM 2.4 parity
|
|
1238
|
+
- Character immortality protection following IS_IMMORTAL macro
|
|
1239
|
+
- Level constants (MAX_LEVEL, LEVEL_IMMORTAL) matching ROM source
|
|
1240
|
+
|
|
1241
|
+
### Changed
|
|
1242
|
+
|
|
1243
|
+
### Deprecated
|
|
1244
|
+
|
|
1245
|
+
### Removed
|
|
1246
|
+
|
|
1247
|
+
### Fixed
|
|
1248
|
+
|
|
1249
|
+
- Character position initialization defaults to STANDING instead of DEAD
|
|
1250
|
+
- Fighting state damage application and position updates
|
|
1251
|
+
- Immortal character survival logic in combat system
|
|
1252
|
+
- Combat defense order to match ROM 2.4 C source (shield_block → parry → dodge)
|
|
1253
|
+
|
|
1254
|
+
### Security
|
|
1255
|
+
|
|
1256
|
+
## [1.2.0] - 2025-09-15
|
|
1257
|
+
|
|
1258
|
+
### Added
|
|
1259
|
+
|
|
1260
|
+
- Complete telnet server with multi-user support
|
|
1261
|
+
- Working shop system with buy/sell/list commands
|
|
1262
|
+
- 132 skill system with handler stubs
|
|
1263
|
+
- JSON-based world loading with 352 resets in Midgaard
|
|
1264
|
+
- Admin commands (teleport, spawn, ban management)
|
|
1265
|
+
- Communication system (say, tell, shout, socials)
|
|
1266
|
+
- OLC building system for room editing
|
|
1267
|
+
- pytest-timeout plugin for proper test timeouts
|
|
1268
|
+
|
|
1269
|
+
### Changed
|
|
1270
|
+
|
|
1271
|
+
- Achieved 100% test success rate (200/200 tests)
|
|
1272
|
+
- Full test suite completes in ~16 seconds
|
|
1273
|
+
- Modern async/await telnet server architecture
|
|
1274
|
+
- SQLAlchemy ORM with migrations
|
|
1275
|
+
- Comprehensive test coverage across all subsystems
|
|
1276
|
+
- Memory efficient JSON area loading
|
|
1277
|
+
- Optimized command processing pipeline
|
|
1278
|
+
- Robust error handling throughout
|
|
1279
|
+
|
|
1280
|
+
### Fixed
|
|
1281
|
+
|
|
1282
|
+
- Character position initialization (STANDING vs DEAD)
|
|
1283
|
+
- Hanging telnet tests resolved
|
|
1284
|
+
- Enhanced error handling and null room safety
|
|
1285
|
+
- Character creation now allows immediate command execution
|
|
1286
|
+
|
|
1287
|
+
## [0.1.1] - 2025-09-14
|
|
1288
|
+
|
|
1289
|
+
### Added
|
|
1290
|
+
|
|
1291
|
+
- Initial ROM 2.4 Python port foundation
|
|
1292
|
+
- Basic world loading and character system
|
|
1293
|
+
- Core command framework
|
|
1294
|
+
- Database integration with SQLAlchemy
|
|
1295
|
+
|
|
1296
|
+
### Changed
|
|
1297
|
+
|
|
1298
|
+
- Migrated from legacy C codebase to pure Python
|
|
1299
|
+
- JSON world data format for easier editing
|
|
1300
|
+
- Modern Python packaging structure
|
|
1301
|
+
|
|
1302
|
+
## [0.1.0] - 2025-09-13
|
|
1303
|
+
|
|
1304
|
+
### Added
|
|
1305
|
+
|
|
1306
|
+
- Initial project structure
|
|
1307
|
+
- Basic MUD framework
|
|
1308
|
+
- ROM compatibility layer
|
|
1309
|
+
- Core game loop implementation
|
|
1310
|
+
|
|
1311
|
+
[Unreleased]: https://github.com/Nostoi/rom24-quickmud-python/compare/v1.3.0...HEAD
|
|
1312
|
+
[1.3.0]: https://github.com/Nostoi/rom24-quickmud-python/compare/v1.2.0...v1.3.0
|
|
1313
|
+
[1.2.0]: https://github.com/Nostoi/rom24-quickmud-python/compare/v0.1.1...v1.2.0
|
|
1314
|
+
[0.1.1]: https://github.com/Nostoi/rom24-quickmud-python/compare/v0.1.0...v0.1.1
|
|
1315
|
+
[0.1.0]: https://github.com/Nostoi/rom24-quickmud-python/releases/tag/v0.1.0
|