So is flush_rewrite_rules necessary when creating custom post type?
It’s not necessary, but it’s a good idea. Users can flush the rewrite rules themselves just by going to Settings > Permalinks, but if the user doesn’t do that and you don’t flush the rules yourself then if the user tries to view a custom post they will get a 404 error.
Either way the .htaccess file doesn’t change. All the WordPress .htaccess does is send all requests to index.php, which runs WordPress. WordPress then figures out what content to load by comparing the requested URL against its own rewrite rules, which are stored in the database.
For a custom post type to work a rule needs to be created that tells WordPress what the URL for a custom post type looks like. Since these rules are expensive to generate they are generated once and stored in the database. So at least once you need to generate the rules while the plugin is activated so that the custom post type rule is included. This can be done programatically with flush_rewrite_rules
on activation or by the user visiting Settings > Permalinks. Doing it yourself provides a much better experience for users of your plugin.
You would also flush them on deactivation so that URLs for the post type that no longer exists properly return a 404 rather than make WordPress attempt to load a post from a non-existant post type.