Automatic username generation from name fields at registration
This is an interesting case in Drupal 8. Previously we could look at the user registration form's validation processes, which in Form API were callback strings in the #validate property array (or attached to each element in the #element_validate property. Note that the Drupal term "element property" means an item in a form array prefixed with a "#".

A basic strategy is similar: alter the form's #validate property and add, not replace, a string referencing a valid PHP callable. Again, probably best to re-order validate callbacks for first-in, first-out.

// Probably best to add this as the first element of #validate
$form['#validate'][] = 'my_register_form_validate';


Then implement the function or callable.

function my_register_form_validate($form, FormStateInterface $formState) {
  // This should do the trick.
  $formState-&gt;setValue('name', $name);
  // But you might need to get the entity from form state storage?
}


But we also need to make sure that the user account form doesn't let you change user name, of it does, then add the same validation/form alter.

In Drupal 8, entities often have their properties validated not in the form but as part of Symfony Constraints as part of their Typed Data data definition. This is so that Drupal is more API-first rather than form-driven (like in Drupal 7).

So I think you're on the right track to look kind of into user_validate_name, but it appears to be unused except in the installer. I think that modifying the entity's base field definition and adding a new constraint would work too.

To do this implement hook_entity_base_field_info_alter. Also see the following question How to easily alter an entitys base field definition per bundle?.

function my_register_form_entity_base_field_info_alter(&amp;$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
  if ($entity_type-&gt;id() === 'user') {
    $fields['name']-&gt;getConstraints()
  }
}


Then implement a Constraint plugin and its corresponding ConstraintValidator class. The ConstraintValidator class might have a validate method like this:

public function validate($items, Constraint $constraint) {
  // The entity should be available on all fields as a parent typed data via FieldItemListInterface::getEntity method
  $entity = $items-&gt;getEntity();
  // Generate user name as say $name.
  $items-&gt;set($name);
}