Firan
FiranMUX is an heavily-coded game. It was originally built on a heavily-modified TinyMUX 1.4 codebase (with most of 1.5 and bits of 1.6 grafted in), which consumed about 800MB of RAM on average. Under TinyMUX 2.6, with a large cache, Firan functions sufficiently well in disk-based mode, but typically, Firan is compiled with MEMORY_BASED. Currently, without a full complement of players, it's using about 600MB of RAM.
Before some of the configuration changes described below, Firan's @cron ran endlessly and profiling indicated it was processing about 300,000 softcode functions per second with memory speed being the gating factor. Even with this behavior, Firan's database has been very useful to obtain sufficient coverage for profile-guided optimizations as well as a stress test. It is useful to TinyMUX 2.x development to be able to run Firan well.
Firan upgraded to TinyMUX 2.x in late 2006. This required changes to a lot of softcode that "should not have worked" but did anyway. It also required weeks of testing on a sandbox server. The upgrade process uncovered a few bugs and these were addressed immediately. Many additional features were added to make the transition smoother, too. The game has been running on TinyMUX 2.x without trouble.
Players on Firan have little or no direct access to the commands and functions provided by the server. Instead, there is a unified softcode layer for accomplishing anything that needs to be accomplished. Because of this approach, server bugs tend only to directly impact Firan insofar as they impact softcode; this meant that many of the TinyMUX 1.4 issues did not directly affect Firan.
Show-stopping issues
There are currently no show-stopping issues.
- Switch_default_all expects to see a boolean value instead of 'first'. cf_bool() is picker now and won't accept a non-boolean value.
- TinyMUX 2.6 exposes IDIV() as the built-in function, and DIV() is the alias. Whereas in TinyMUX 1.x, DIV() is the built-in function, and IDIV() is the alias.
- In TinyMUX 2.6, cache_depth and cache_trim are deprecated in favor of max_cache_size.
- The helpfiles (including maps) needs to be added to the configuration files via helpfile and raw_helpfile.
- Three attribute numbers (A_COLOR, A_ALEAD, and A_EXITFORMAT) in Firan's database conflict with previously assigned attributes numbers or need to be moved. To convert these, compile with both FIRANMUX and FIRANMUX_CONVERT #define'ed, and load the database once. Re-compile with only FIRANMUX #define'ed.
- All of the *_file_index configuration options are no longer there.
- queue_active_chunk and queue_idle_chunk were set to 200 and 500 respectively. With the queue in TinyMUX 2.6, it is no longer necessary to compensate this much towards throughput at the expensive of responsiveness. A value of 10 or 20 on 2.6 will have better throughput than a value of 200 on 1.4 and still be more responsive.
- Built-in E-mailer needs to be included not just to report crashes but also to E-mail passwords to new players.
- function_invocation_limit needs to be raised from 12000 to perhaps 24000. Perhaps 2.6 is counting functions differently (better or just differently), but the @nobles command takes about 8 seconds on the production game using TinyMUX 1.4, and about 1.5 seconds on the test TinyMUX 2.6.
- The units on timeslice changed from milliseconds to seconds with a decimal point. The configuration files contained this option, and it is interpreted as 1000 seconds. So, after 100 commands from a player, the input stalls for 1000 seconds at which time you would be allowed one additional command.
Issues possibly to be fixed later:
- When looking at the 'track' object, #-1 NOT FOUND appears in every racing lane.
- TinyMUX 1.4 does not count or check function invocations to @functions, and one of the poison posts showed the #-1 FUNCTION INVOCATION LIMIT message. It has always hit this, but now, there is a message.
- Exaurdon's money seems to disappear rapidly. This has usually been tracked back to softcode's uncontrolled, looping use of the queue. Especially after reboot.
- There are conflicts between the hardcode attribute, Created, and Firan's use of Created in softcode. The solution is to rename any attributes during the first conversion, or to rename them with @attribute/rename prior to conversion. Created is added by chargen and reference manually. There is also one case of an object having Reason set, but the softcode doesn't use it.
Issues fixed in Softcode:
- Taking objects that are heavy and require the taking of energy from the player results in a @program loop, asking repeatedly if they want to take the item until they say no. At which point it ends the program with no taking being done. Looping since fixed.
- Separate/group softcode commands needed to ignore the Created and Modified object attributes. In the former case, #-1 PERMISSION DENIED occured which prevented a @pemit, and in the later case, the objects were not deemed 'compatible' enough to group.
- On TinyMUX 1.6, min() and max() return integers, but on TinyMUX 2.6, they return floating-point. Any use of min() and max() on floats will need to be changed to trunc(min()) and trunc(max()).
- on TinyMUX 1.6, ljust() did not truncate the string to field within the width, but TinyMUX 2.6 does. Any use of format(ljust()) should be changed to format(). Any use of strtrunc(ljust()) can be changed to ljust() eventually.
- Because of Floating-point differences, any use of sub() on floating-point values may need to change to round(sub()). In the end, it was easier to add float_precision configuration option to support a fixed six digits of precision.
Issues fixed in Hardcode:
- In working on Firan's linewrap_general(), Brazil inadvertently left a null-terminator off. This affected appearance of anything using format().
- pos() was broken for single-character case. Bug introduced into 2.6 as part of cleaning up compiler warnings, and doesn't appear in 2.4. It affected '@flags me'.
- Players knocked unconscious are unable to talk on channel because they are set GAGGED. By default, TinyMUX 2.6 prevents speech on channels if a player is set GAGGED. Solution is to remove the Gagged() check from the hardcode for the FIRANMUX build.
- There is a conflict between the hardcoded @flag command and the softcoded @flag command. The solution is to @addcommand over @flag. However, @toggle ansi [on|off] doesn't work on either the test site or the production site because @toggle's use of @flag would affect the object containing the @toggle command instead of the player.
- Six get and take softcode commands are layered on top of the hardcode get command. The desired behavior is still fuzzy and unclarified, but both cases can be made to work by adding an alias __take for get in the configuration files, and then @addcommand'ing the six softcode functions which has the result of renaming get to __get.
- Uninitialized sepColumn delimiter in sql() returned garbage.
- sepColumn, if unspecified, should default to sepRow in sql().
- ANSI_String_Finalize() was touching just beyond the end of an LBUF as it laid down a return-to-normal ANSI sequence. Normally, ANSI_String_Copy() leaves room for the return-to-normal sequence. This has as least the effect of corrupting the footer and causing an LBUF to be strategically discarded. Bug was introduced in 2.6 when nFieldEffective in ANSI_String_Copy() was changed from a signed 'int' to an unsigned 'size_t' as part of the changes to make TinyMUX run on 64-bit Windows.
- As part of the ANSI_String_Finalize() scenario described above, once a string contains a value larger than an LBUF, a loop in process_cmdent() containing (ironically enough) extra buffer-overflow checking will cause a crash. This bug was introduced in 2.4.